We will be including more of java into Tea:
compilation_unit -- > class_declaration ";"
class_declaration -- > <modifier> "class" name ["extends" class_name]
"{" <method_declaration | variable_declaration> "}"
method_declaration -- > <modifier> type name "(" ")" "{" statement_block "}"
variable_declaration --> <modifier> type name declarative_statement
....
modifier --> "public" | "static"
variable_type --> "int" | class_name
class_name --> name
In the past students have found it useful to also put out AST nodes for declarations, but that is up to you.
Input: The usual programs with declarations plus one which tests your new constructs:
#1 public class input_a { public void main() { int a, b, c, p, xyz; a = 3; xyz = a + b + c - p / 4; a = xyz * ( p + 9 ); p = a - xyz - p; } } #2 void input_b() { if ( i > j ) i = i + j; elsif ( i < j ) i = 1; } #3 void input_c() { while ( i < j && j < k ) { k = k + 1; while ( i == j ) i = i + 2; } }Output: Each program, followed by its AST, followed by its symbol table. As an extra, print the entries out in alphabetical order. The table might look something like :
public class input_a { public void main() { int a, b, c, p, xyz; a = 3; xyz = a + b + c - p / 4; a = xyz * ( p + 9 ); p = a - xyz - p; } } c class = variable type = int dline = 3 scope = 2 references: 6 3 b class = variable type = int dline = 3 scope = 2 references: 6 3 a class = variable type = int dline = 3 scope = 2 references: 8 7 6 5 3 main class = method dline = 2 other = void modifier = public scope = 1 references: 2 p class = variable type = int dline = 3 scope = 2 references: 8 7 6 3 xyz class = variable type = int dline = 3 scope = 2 references: 8 7 6 3 input_a class = class dline = 1 modifier = public scope = 0 references: 1Do not confuse the java word class with the "class" attribute in a symbol table!
Implement your Symbol Table as an abstract data type. That is, use statements such as enter (SymbolTable,Name), rather than enter (SymbolTable[i],Name). Ask me if this is unclear.
Here is an excerpt :
options { IGNORE_CASE = false; OPTIMIZE_TOKEN_MANAGER = true; MULTI = false; STATIC = false; } PARSER_BEGIN(tea) import java.io.*; import java.util.*; public class tea { public static Hashtable ST = new Hashtable(); int scope = 0; public static void main(String[] args) throws ParseException, FileNotFoundException { String temp; STO temp2; if ( args.length < 1 ) { System.out.println("Please pass in the filename for a parameter."); System.exit(1); } tea parser = new tea( new FileInputStream(args[0]) ); SimpleNode root = parser.program(); // root.dump(""); Enumeration t = ST.keys(); while ( t.hasMoreElements() == true ) { temp = (String)t.nextElement(); temp2 = (STO)ST.get(temp); System.out.println(temp); if ( temp2.Sclass != null ) System.out.println(" class = " + temp2.Sclass); if ( temp2.type != null ) System.out.println(" type = " + temp2.type); if ( temp2.dline != 0 ) System.out.println(" dline = " + temp2.dline); if ( temp2.other != null ) System.out.println(" other = " + temp2.other); if ( temp2.modifier != null ) System.out.println(" modifier = " + temp2.modifier); System.out.println(" scope = " + temp2.scope); System.out.println(" references:"); Stack temp3 = (Stack)temp2.references.clone(); while ( temp3.empty() == false ) System.out.println(" " + temp3.pop()); } // System.out.println("Parse completed."); } public void Add_Reference(String Name, int LineNo) { Integer tint = new Integer(LineNo); STO temp = (STO)ST.get(Name); if ( temp.references.peek().equals(tint) == false ) { temp.references.push(tint); ST.put(Name,temp); } } } public class STO extends Object { int dline; // Declaration Line Number int scope; // scope of the object String other; // "Other" string associated with class String modifier; // Modifier of class String Sclass; // class String type; // type Stack references = new Stack(); public STO(String Class, String Type, int Dline, String Modifier, String Other, int Scope ) { Sclass = Class; type = Type; dline = Dline; other = Other; modifier = Modifier; scope = Scope; references.push(new Integer(dline)); } } PARSER_END(tea) SKIP: /* Whitespace */ { "\t" | "\n" | "\r" | " " } TOKEN: /* Most Things */ { .... } SimpleNode program() : {} { compilation_unit() <EOF > { return jjtThis; } } void compilation_unit() #void : {} { class_declaration() } void class_declaration() : { Token t1, t2, t3=null; }{ t1=<MODIFIER > <CLASS> t2=<NAME> [<EXTENDS> t3=<NAME>] <LBRACE> {scope++;}(method_declaration())* {scope--;}<RBRACE > { jjtThis.value = t1.image; // modifier jjtThis.ovalue = t2.image; // name if ( t3 != null ) jjtThis.ovalue2 = t3.image; // other jjtThis.bline = t1.beginLine; // line ST.put(t2.image,new STO("class",null, t1.beginLine, t1.image, jjtThis.ovalue2, scope)); } } /* void variable_declaration() : { Token t1; }{ t1=<MODIFIER > declarativestatement() { jjtThis.value = t1.image; jjtThis.bline = t1.beginLine; } } */ ... void assignmentstatement() : { Token temp; } { temp=<NAME > [<ASSIGNOP> expression()] { jjtThis.value = temp.image; jjtThis.bline=temp.beginLine; if ( ST.get(temp.image) != null ) Add_Reference(temp.image,temp.beginLine); } } ...
Send questions and comments to: Karen Lemone