import minijava.analysis.*; import minijava.node.*; import minijava.symbol.*; public class SymbolTableBuilder extends DepthFirstAdapter { private Table symtable; private minijava.symbol.Class currClass; private minijava.symbol.Method currMethod; private boolean [] ok ; SymbolTableBuilder(Table table, boolean [] ok) { this.symtable = table; this.ok = ok; currClass = null; currMethod = null; } public boolean iscyclic(minijava.symbol.Class supercl, minijava.symbol.Class subcl) { if (subcl == null) { return false; } if (subcl.getId().equals(supercl.getId())) { return true; } if (subcl.parent() == null) { return false; // root reached } return iscyclic(supercl, symtable.getClass(subcl.parent())); } void checkType(PType type) { if (type instanceof AIdentifierType) { String id = ( (AIdentifierType) type).getIdLiteral().getText(); if (symtable.containsClass(id) == false) { System.out.println("Unrecognized type for variable " + id.toString() + " declared inside class " + currClass.getId().trim()); ok[0] = false; // System.exit( -1); } } } public void inAMainClass(AMainClass node) { String ClassName = node.getClname().toString().trim(); currClass = symtable.getClass(ClassName); } public void outAMainClass(AMainClass node) { currClass = null; } public void inASimpleClassDecl(ASimpleClassDecl node) { String ClassName = node.getIdentifier().toString().trim(); currClass = symtable.getClass(ClassName); } public void outASimpleClassDecl(ASimpleClassDecl node) { currClass = null; } public void inAExtendsClassDecl(AExtendsClassDecl node) { String ClassName = node.getNewcl().toString().trim(); String ParentClass = node.getOldcl().toString().trim(); currClass = symtable.getClass(ClassName); int line = ((AIdentifier) node.getNewcl()).getIdLiteral().getLine(); if (iscyclic(currClass, symtable.getClass(ParentClass))) { System.out.println("Line " + line + ": " + "Cyclic inheritance detected for class" + currClass.getId()); ok[0] = false; System.exit( -1); } if (symtable.containsClass(ParentClass) == false) { System.out.println("Line " + line + ": "+ "Symbol " + ParentClass + ", " + " declared as Parent of class " + ClassName + ", does not exist"); ok[0] = false; // System.exit( -1); } } public void outAExtendsClassDecl(AExtendsClassDecl node) { currClass = null; } public void inAVarDecl(AVarDecl node) { PType t = node.getType(); int line = ((AIdentifier) node.getIdentifier()).getIdLiteral().getLine(); checkType(t); String id = node.getIdentifier().toString(); if (currMethod == null) { if (!currClass.addVar(id, t)) { System.out.println("Line " + line + ": " + id + " is already defined in " + currClass.getId()); ok[0] = false; // System.exit( -1); } } else { if (currMethod.containsVar(id)) { System.out.println("Line " + line + ": " + id + " is already defined in " + currClass.getId() + "." + currMethod.getId()); ok[0] = false; // System.exit( -1); } else if (currMethod.containsParam(id)) { System.out.println("Line " + line + ": " + id + " is already defined as " + "a parameter of method " + currClass.getId() + "." + currMethod.getId()); ok[0] = false; // System.exit( -1); } else if (!currMethod.addVar(id, t)) { System.out.println("Line " + line + ": " + "Unexpected error while adding Var to Symbol Table "); ok[0] = false; } } } public void inAMethodDecl(AMethodDecl node) { PType t = node.getType(); String id = node.getIdentifier().toString(); int line = ((AIdentifier) node.getIdentifier()).getIdLiteral().getLine(); checkType(t); if (!currClass.addMethod(id, t)) { System.out.println("Line " + line + ": " + "Function" + id + "is already defined in" + currClass.getId()); ok[0] = false; // System.exit( -1); } currMethod = currClass.getMethod(id); } public void outAMethodDecl(AMethodDecl node) { currMethod = null; } public void inAFormal(AFormal node) { PType t = node.getType(); String id = node.getIdentifier().toString(); int line = ((AIdentifier) node.getIdentifier()).getIdLiteral().getLine(); checkType(t); if (!currMethod.addParam(id, t)) { System.out.println("Line " + line + ": " + "Parameter " + id + " of function " + currMethod.getId() + " in class " + currClass.getId() + " already exists"); ok[0] = false; } } }