Assignment #5

Symbol Tables, Classes and Methods

In this assignment, we will be processing the declarations of Tea, and then creating a symbol table

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 (from Theo's):

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:
  1
Do 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 from Theo's:


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