Chapter 8: Symbol Tables and Declaration Processing
- Locate and install the lab8 project into your
eclipse workspace as directed by your instructor,
following the usual instructions,
including those for an ant build.
- Browse this lab document to get an idea of the work you will do for this assignment.
The symbol table is the
best example of a structure deserving
global treatment in a compiler based on bottom-up parsing.
In this homework,
you will implement symbol-table processing for our Java-like language.
This requires a traversal of the AST using the
and an optional implementation of a symbol-table manager.
The essential task of this assginment is to associate the declaration of a
name to the relevant uses of that declared name.
The labs from this point on make use of the visitor pattern.
If this term is unfamiliar,
spend some time
investigating the visitor pattern.
Even if you are generally familiar with the pattern, the book and assignments use a
reflective form of the pattern that is very convenient for the work we do.
It is recommended that you read the tutorial and perform the associated exercises
to acquaint yourself with this form of the pattern.
- In this assignment, and in all assignments leading up to the final compiler project,
you have a choice of using your solutions to-date, or the equivalent class components.
For this assignment, you need a working implementation of
Lab 7 , in the form of a parser that creates an
abstract syntax tree (AST). The AST will need a handful of specialized
nodes so that the symbol table visitor can intercept and handle symbol
declarations and uses.
There are two ways for you to do this, and either one is acceptable:
- You can use the supplied parser component found in
the coursesolutions.courseparser package.
- You can use your own implementation:
- Copy your jmm.cup from Lab 7 into the top directory
of this project.
- In the rule for the goal symbol CompilationUnit, be
sure to set RESULT
to the root node of the parse tree in the semantic action.
The parser is chosen by the static method getParser(String) found in
SymtabVisitor. The comments there instruct you how to change from the
course reference parser to your own.
- The ant run target runs your compiler on
each file found in the
- Take note of the following classes and their usage in this lab:
|| Found in the submit package, this is the only file you will submit. It contains the visitor as a public class
and an implementation of a symbol table as a non-public class.
Instructions on its use are found in the code.
|| This is the reference implementation of the visitor, found in
classsolutions.jar. Your installed code will use it until
you make the appropriate change in SymtabVisitor,
as directed by the comments.
Be sure to make that change, so that your symbol table vistor
|| This is the reference implementation of the symbol table itself, found in
For this lab, you can continue using this one unless you want to use your
own, or the one you developed in Studio,
in which case you should
make the appropriate change in SymtabVisitor.
- As installed, you are the reference solution. Take a look at the AST dump to see the structure
of the AST (or use your own from Lab 7). The indentation of the symbol-table pass shows the
- For hints on how to do the visitor, the documentation for
the reference symbol-table visitor .
shows the visit methods present in that solution:
- ClassDeclaring: Check that the name isn't already in the symbol table. Be sure
to pass the visitor along to this node's children, as with BlockIsh.
- MethodDeclaring: Check that the name isn't already in the symbol table.
You should then pass the visitor on to the parameters and to the method's body.
What you do with nest levels in and around those calls will affect how
scoping works in your compiler.
Document your approach using comments in the code you submit.
- FieldDeclaring: Check for duplicate declaration, but treat the name
as though "this." were prepended to it.
- LocalDeclaring: If the symbol is already
declared at the current nest level, complain as directed below. Otherwise, get this symbols
type information, and enter the symbol and its type information into the
Look up the symbol in the symbol table, and use the
setSymInfo method to set the symbol information
for this declaration in the AST (so it looks nice when it prints).
- LocalReferencing: Make sure there is a valid entry for the symbol
in the symbol table at this point. Call
on this node to establish the map
between the reference and its type declaration.
- BlockIsh: manipulate scopes properly and pass the visitor on.
- The information set and retrieved from the symbol table must
be an implementation of the
So you must develop a local class within SymtabVisitor (because
that's the only file you turn in) that implements the SymInfo interface, and you will
have to instantiate it appropriately for a symbol before you
insert the symbol into the symbol table.
Just implement the
getRegister/setRegister methods as stubs—no meaningful implementation of them
is needed at this point.
- If you detect an undeclared reference, your output must contain
Error: Undefined Reference and indicate the offending node.
The easiest way to do this is to use the
- Likewise, if is a symbol is already declared at the current nest level, then you must emit a message
Error: Duplicate declaration