/*
* JContextChecker.java
*
* Created on March 12, 2005, 12:16 PM
*/
package compiler;
import java.util.* ;
import java.io.* ;
/**
*
* @author Administrator
*/
public class JContextChecker implements ASTVisitor{
public JTable symtable ;
public String temporary_return_type ;//Just to Store the
return type of Methods
//Becomes null when leaving the scope. Line Number: 142
//To be used to check the return type of the function
//in ReturnCommand
public boolean return_statement_availability ;//Again
to indiacte whether a return statement is available in the current scope
/** Creates a new instance of JContextChecker */
public JContextChecker() {
symtable = new JTable();
temporary_return_type = null ;
return_statement_availability
= false ;
}
public void check(AST ast){
ast.visit(this,null);
}
public void error(String message){
System.out.println("Error: "+message)
;
System.exit(0);
}
public Object visitCompilationUnit(CompilationUnit p,Object
arg){
System.out.println("In Visit Compilation
Unit");
p.cd.visit(this,null);
return null ;
}
public Object visitClassDeclaration(ClassDeclaration p,Object
arg){
System.out.println("In Visit Class
Declaration");
boolean ret = symtable.insert(p.classname.terminal,p.publicdec.terminal,false,"class");
if(ret == false){
error("Cant
enter the Class NAme");
}else{
System.out.println("Successful");
}
symtable.enterScope();
if(p.classbody != null){
p.classbody.visit(this,null);
}
return null ;
}
public Object visitClassBody(ClassBody p,Object arg){
System.out.println("In Visit Class
Body");
if(p.ds != null){
p.ds.visit(this,null);
}
return null ;
}
public Object visitVariableDeclarations(VariableDeclarations
p,Object arg){
System.out.println("In Visit Variable
Declarations");
String scopemodifier = null ;
if(p.modifier != null){
scopemodifier
= p.modifier.str ;
}
boolean st = false ;
if(p.staticvariable != null){
if(p.staticvariable.modifier.equals("static")){
st = true ;
}else{
st = false ;
}
}
String tp = null ;
if(p.type.ptype == true){
tp = p.type.primitivetype.terminal;
}else{
tp = p.type.name.name;
}
if(p.type.ptype == true){
if(tp.equals("void")){
error("Void type Variables are not allowed to be declared");
}
}
boolean ret = symtable.insert(p.variablename.terminal,scopemodifier,st,tp);
if(ret == false ){
error("Variable
Insertion Error");
}
return tp ;
}
public Object visitFunctionDeclarations(FunctionDeclarations
p,Object arg){
System.out.println("In Visit Function
Declarations");
String md = p.md.str ;
boolean st = false ;
if(p.staticfunction != null){
if(p.staticfunction.modifier.equals("static")){
st = true ;
}else{
st = false ;
}
}
String tp = null ;
if(p.type.ptype == true){
tp = p.type.primitivetype.terminal;
}else{
tp = p.type.name.name;
}
LinkedList plist = null ;
if (p.parameterlist != null){
if (p.parameterlist instanceof SequenceDeclarations)
{
plist = (LinkedList) p.parameterlist.visit(this,
null) ;
}
else
{
plist = new LinkedList() ;
String temp = (String) p.parameterlist.visit(this,
null) ;
plist.addFirst(temp) ;
}
}
else
{
plist = new LinkedList() ;
}
temporary_return_type = tp ;
boolean ret = symtable.insert(p.functionname.terminal,
p.md.str, st, tp,plist, p.declaration_type) ;
symtable.enterScope() ;
if (ret == false )
{
error("Method could not be inserted")
;
}
p.block.visit(this,null);
symtable.leaveScope() ;
temporary_return_type = null ;
if(tp.equals("void")==false &&
return_statement_availability==false){
error("No
Return Statement");
}
return_statement_availability
= false ;
return null ;
}
public Object visitBlock(Block p, Object arg) {
System.out.println("In Visit Block");
if(p.dec != null){
p.dec.visit(this,null);
}
if(p.cmd != null){
p.cmd.visit(this,null);
}
return null ;
}
public Object visitSequenceDeclarations(SequenceDeclarations
p,Object arg){
System.out.println("In Visit SequenceDeclarations")
;
LinkedList plist = null ;
if (p.declarationsone instanceof SequenceDeclarations){
System.out.println("Calling
Sequence Declarations's Visit") ;
plist = (LinkedList) p.declarationsone.visit(this
, null) ;
System.out.println("Back in Sequence
Declaration's Visit"+plist) ;
String t2 = (String) p.declarationstwo.visit(this
, null) ;
plist.addLast(t2) ; //
plist should not be null.
}
else
{
String t1 = (String) p.declarationsone.visit(this
, null) ;
String t2 = (String) p.declarationstwo.visit(this
, null) ;
// This is the first expr in the sequence.
plist = new LinkedList() ;
plist.addFirst(t1) ;
plist.addLast(t2) ;
System.out.println("Return List") ;
}
return plist ;
}
public Object visitAssignmentCommand(AssignmentCommand p, Object
arg) {
System.out.println("In Visit Assignment
Command ") ;
String type1 = (String) p.tan.visit(this,null)
;
String type2 = (String) p.exp.visit(this,
null) ;
System.out.println("Type1 = "+type1+"
t2= "+type2) ;
if (type1 == null || type2 == null || !type1.equals(type2)
){
if (type1
== null){
error("Error on the type of Assignment Command(left side)") ;
}else{
error("Error on the type of Assignment
Command(right side)") ;
}
}
return null ;
}
public Object visitMethodCallCommand(MethodCallCommand p,Object
arg){
System.out.println("In Visit Method
Call Command");
String retType = null ;
//First Part Must Check for the
Return Type
System.out.println("Hiii"+p.tan.name.name);
methodSymObject obj = (methodSymObject)symtable.lookup(p.tan.name.name);
System.out.println("CC"+p.tan.name.name+"
"+obj);
if(obj!=null){
if(!obj.type_of_object.equals("function")){
error("No Such Function");
}
retType = (String)obj.type
;
}else{//Object is null. No such
Function in the current class.Search in the API's
StringTokenizer
str = new StringTokenizer(p.tan.name.name,".");
obj =
(methodSymObject)symtable.lookup(str.nextToken());
if(obj==null){//No
such Object exisits
error("Undefined Variable Here");
}else{
String classname = obj.type ;
JParserUtil jps = new JParserUtil();
if(!jps.isClassLoadAvail(classname)){//No such class
error("No Such Class");
}
String functionname = str.nextToken();
Class temp = jps.isMethodFound(classname,functionname);
if(temp!=null){
if(jps.isPublicMethod(classname,functionname)==false){
error("The Function is not a Public");
}
retType = temp.toString();
//Second part is to check for parametertypes
LinkedList type2 = new LinkedList();
if(p.exp != null){
type2 = (LinkedList)p.exp.visit(this,null);
}
LinkedList params = (LinkedList)jps.getParams(classname,functionname);
if(!params.equals(type2)){
error("Type Mismatch in Function Call");
}
}else{
error("No such Function Exists");
}
}
}
return retType ;
}
public Object visitBinaryOpExpression(BinaryOpExpression
p, Object arg) {
System.out.println("In Visit BinaryOp
Expression ") ;
String t1 = (String) p.expressionone.visit(this , null)
;
String t2 = (String) p.expressiontwo.visit(this , null)
;
String op = p.operator.terminal ;
String type = null ;
if ( t1.equals(t2)){
if (op.equals("+")
&& t1.equals("int")
|| op.equals("-") && t1.equals("int")
|| op.equals("*") && t1.equals("int")
|| op.equals("/") && t1.equals("int")
|| op.equals("|") && t1.equals("boolean")
|| op.equals("&") && t1.equals("boolean")){
type = t1 ;
}else
if ((op.equals("==") || op.equals("!=") || op.equals("&&") || op.equals("||"))
&&
(t1.equals("int")
|| t1.equals("boolean"))){
type = "boolean" ;
}else
if ((op.equals("<") || op.equals("<=") || op.equals(">") || op.equals(">="))
&&
t1.equals("int")){
type ="boolean" ;
}else{
error("Type Matching Problem") ;
}
}else{
error("Type Mismatch") ;
}
return type ;
}
public Object visitIfElseCommand(IfElseCommand p, Object
arg) {
System.out.println("In Visit IfElse
Command ") ;
String t1 = (String)p.expression.visit(this,
null) ;
if (!t1.equals("boolean")){
error("Return Value of the IfElse Command
must be boolean") ;
}
if (p.command != null){
p.command.visit(this, null) ;
}
if (p.ecommand != null){
p.ecommand.visit(this, null) ;
}
return null ;
}
public Object visitJustThis(JustThis p, Object arg) {
return (String)symtable.classname
;
}
public Object visitClassInstanceCreationExpression(ClassInstanceCreationExpression
p, Object arg) {
System.out.println("In Visit Class
Instance Creation Expression");
String retType = p.name.name ;
LinkedList type2 = new LinkedList();
if(p.expression != null){
try{
type2 = (LinkedList)p.expression.visit(this,null);
}catch(Exception
e){
String temp = (String)p.expression.visit(this,null);
type2.addLast(temp);
}
}
StringTokenizer str = new StringTokenizer(p.name.name,".");
String temp = null ;
for(int i=0 ; i<str.countTokens()-1;i++)
temp+=str.nextToken();
String classname = str.nextToken();
if(!classname.equals(symtable.classname)){
JParserUtil
jpu = new JParserUtil();
if(!jpu.isClassLoadAvail(retType)){
error("That Particular Class is not available");
}
//System.out.println("Package
: "+p.name.name+" ClassName: "+classname+" Type2: "+type2);
if(!jpu.getConstructorParams(p.name.name,classname,type2)){
error("Type Mismatch in Class Instance Creation Expression");
}
return
retType ;
}else{
methodSymObject
obj = (methodSymObject)symtable.lookup(classname);
LinkedList
params = obj.params ;
if(!type2.equals(params)){
error("Type Mismatch in Constructor");
}
return
retType ;
}
}
public Object visitMethodCallExpression(MethodCallExpression
p, Object arg) {
System.out.println("In Visit Method
Call Expression");
String retType = null ;
//First Part Must Check for the
Return Type
varSymObject obj = (varSymObject)symtable.lookup(p.tan.name.name);
if(obj!=null){
if(!obj.type_of_object.equals("function")){
error("No Such Function");
}
retType
= (String)obj.type ;
}else{//Object is null. No such
Function in the current class.Search in the API's
StringTokenizer
str = new StringTokenizer(p.tan.name.name,".");
obj =
(varSymObject)symtable.lookup(str.nextToken());
if(obj==null){//No
such Object exisits
error("Undefined Variable Here");
}else{
String classname = obj.type ;
JParserUtil jps = new JParserUtil();
if(!jps.isClassLoadAvail(classname)){//No such class
error("No Such Class");
}
String functionname = str.nextToken();
Class temp = jps.isMethodFound(classname,functionname);
if(temp!=null){
if(jps.isPublicMethod(classname,functionname)==false){
error("The Function is not a Public");
}
retType = temp.toString();
//Second part is to check for parametertypes
LinkedList type2 = new LinkedList();
if(p.exp != null){
try{
type2 = (LinkedList)p.exp.visit(this,null);
}catch(Exception e){
String tmp = (String)p.exp.visit(this,null);
type2.addLast(tmp);
}
}
LinkedList params = (LinkedList)jps.getParams(classname,functionname);
if(!params.equals(type2)){
error("Type Mismatch in Function Call");
}
}else{
error("No such Function Exists");
}
}
}
return retType ;
}
public Object visitReturnCommand(ReturnCommand p, Object
arg) {
System.out.println("In Visit Return
Command ") ;
return_statement_availability
= true ;
if(p.expression != null){
String
returntype =(String) p.expression.visit(this,null);
if(!returntype.equals(temporary_return_type)){
error("Return Type of the function does not match with return expression");
}
}else{
if(!temporary_return_type.equals("void")){
error("Return Type of the function does not match with return expression");
}
}
return null ;
}
public Object visitSequenceCommand(SequenceCommand p,
Object arg) {
System.out.println("In Visit Sequence
Command ") ;
p.commandone.visit(this, null) ;
if(p.commandtwo != null)
p.commandtwo.visit(this,
null) ;
return null ;
}
public Object visitSequenceExpression(SequenceExpression
p, Object arg) {
System.out.println("In Sequence
Expression") ;
LinkedList plist = null ;
if (p.expressionone instanceof SequenceExpression){
plist = (LinkedList) p.expressionone.visit(this
, null) ;
if(p.expressiontwo
!= null){
String t2 = (String) p.expressiontwo.visit(this , null) ;
plist.addLast(t2) ; // plist should not be null.
}
}
else{
String
t1 = (String) p.expressionone.visit(this , null) ;
// This
is the first expr in the sequence.
plist
= new LinkedList() ;
plist.addFirst(t1) ;
if(p.expressiontwo
!= null){
String t2 = (String) p.expressiontwo.visit(this , null) ;
plist.addLast(t2) ;
}
}
return plist ;
}
public Object visitThisAndNameExpression(ThisAndNameExpression
p, Object arg) {
System.out.println("In Visit This
And Name Expression");
return p.tan.visit(this,null);
}
public Object visitSimplePWLExpression(SimplePWLExpression
p, Object arg) {
System.out.println("In Visit Simple
PWL Expression");
return (String)p.exp.visit(this,null)
;
}
public Object visitThisAndName(ThisAndName p, Object arg)
{
System.out.println("In
Visit This And Name");
String
retType = null ;
varSymObject
obj = (varSymObject)symtable.lookup(p.name.name);
if(obj!=null){
if(!obj.type_of_object.equals("variable")){
error("Function Cannot be Assigned any Value");
}
//System.out.println("I Found it"+ (String)obj.type);
retType = (String)obj.type ;
}else{//Object
is null. No such variable in the current class.Search in the API's
StringTokenizer str = new StringTokenizer(p.name.name,".");
obj = (varSymObject)symtable.lookup(str.nextToken());
if(obj==null){//No such Object exisits
error("Undefined Variable Here");
}else{
String classname = obj.type ;
JParserUtil jps = new JParserUtil();
if(!jps.isClassLoadAvail(classname)){//No such class
error("No Such Class");
}
String fieldname = str.nextToken();
Class temp = jps.isFieldFound(classname,fieldname);
if(temp!=null){
if(jps.isPublicFinalField(classname,fieldname)==false){
error("The Variable is not a Public Variable or a Final Variable");
}
retType = temp.toString();
}else{
error("No such Field Exists");
}
}
}
return
retType ;
}
public Object visitUnaryOpExpression(UnaryOpExpression
p, Object arg) {
System.out.println("In Visit UnaryOp
Expression") ;
String type = (String) p.exp.visit(this, null) ;
if (p.op.terminal.equals("+") || p.op.terminal.equals("-")){
if (!type.equals("int")){
error("Unary op +/- expr type not int")
;
}
}else{
error("Unary
Op not +/-");
}
return type ;
}
public Object visitWhileCommand(WhileCommand p, Object
arg) {
System.out.println("In Visit While
Command ") ;
String t1 = (String)p.expression.visit(this, null) ;
if (!t1.equals("boolean")){
error("Return Command of While Command
must be boolean") ;
}
if (p.command != null){
p.command.visit(this, null) ;
}
return null ;
}
public Object visitIntegerLiteralExpression(IntegerLiteralExpression
p, Object arg) {
System.out.println("In Visit Integer
Literal Expression");
p.value = "int" ;
return "int" ;
}
public Object visitBooleanLiteralExpression(BooleanLiteralExpression
p, Object arg) {
System.out.println("In Visit Boolean
Literal Expression");
p.value = "boolean" ;
return "boolean" ;
}
public Object visitNullLiteralExpression(NullLiteralExpression
p, Object arg) {
System.out.println("In Visit Null
Literal Expression");
p.value = "null" ;
return "null" ;
}
public Object visitTerminal(Terminal p,Object arg){
System.out.println("In Visit Terminal");
return null ;
}
public Object visitModifier(Modifier p, Object arg) {
System.out.println("In Visit Modifier");
return null ;
}
public Object visitStatic(Static p, Object arg) {
System.out.println("In Visit Static");
return null ;
}
public Object visitPrimitiveType(PrimitiveType p,Object
arg){
System.out.println("In Visit Primitive
Type");
return((String)p.primitivetype.terminal);
}
public Object visitReferenceType(ReferenceType p,Object
arg){
System.out.println("In Visit Reference
Type");
return((String)p.name.name);
}
public Object visitName(Name p,Object arg){
System.out.println("In Visit Name");
return null ;
}
public static void main(String args[]) throws Exception{
//open file name given in command line
JParser p = new JParser(args[0]);
AST tree = p.parse() ;
JContextChecker cc = new JContextChecker() ;
cc.check(tree) ;
System.out.println(""+cc.symtable) ;
}
}