You will implement a third component of the compiler that checks the static semantics of the program being compiled. You will use the visitor design pattern to walk the AST to check anything that can be verified (statically) at compile-time.
Note that this is the third component for the VC compiler since the recogniser, once extended into a parser, will no longer be used.
Revision Log
1. Specification
You are to implement a semantic or contextual analyser that checks that the program conforms to the source language's context-sensitive constraints (i.e., static semantics) according to the VC Language Definition. This part of the compilation process is referred to as the semantic or contextual analysis.
There are two types of context-sensitive constraints:
• Scope rules: These are the rules governing declarations (defined occurrences of identifiers) and applied occurrences of identifiers.
• Type rules: These are the rules that allow us to infer the types of language constructs and to decide whether each construct has a valid type.
Therefore, the semantic analysis consists of two subphases:
• Identification: applying the scope rules to relate each applied occurrence of an identifier to its declaration, if any.
• Type checking: applying the type rules to infer the type of each construct and comparing that type with the expected type in the context.
This assignment involves developing a visitor class (named Checker) that implements the set of visitor methods in the interface VC.ASTs.Visitor.java. Your semantic analyser will be a visitor object that performs both identification and type checking in one pass by visiting the AST for the program being compiled in the depth-first traversal.
In the case of ill-typed constructs, appropriate error messages as specified below must be reported.
As before, if no lexical, syntactic or semantic error is found, your compiler should announce success by printing:
Compilation was successful.
Otherwise, the following message should be printed:
Compilation was unsuccessful.
2. Identification
This subphase of the semantic analyser has been implemented for you. Identification relates each applied occurrence of an identifier to its declaration, if any, by applying the VC's scope rules. The standard method of implementing this subphase is to employ a symbol table that associates identifiers with their attributes. In the VC compiler, the attribute for an identifier is represented by a pointer (an inherited attribute) to the subtree that represents the declaration (GlobalVarDecl, LocalVarDecl or FuncDecl) of the identifier. This attribute is represented by the instance variable decl in VC.ASTs.Ident.java:
package VC.ASTs;
importVC.Scanner.SourcePosition;
public class Ident extends Terminal {
public AST decl;
publicIdent(String value , SourcePosition position) {
super (value, position);
decl = null;
}
public Object visit(Visitor v, Object o) {
returnv.visitIdent(this, o);
}
}
There is only one symbol table organised as a stack for storing the identifiers in all scopes. Two classes are used:
• VC.Checker.IdEntry.java: defining what a symbol table entry looks like.
• VC.Checker.SymbolTable.java: defining all methods required for symbol table management.
The symbol table methods are called at the following visitor methods of the classChecker:
• visitGlobalVarDecl, visitLocalVarDecland andvisitFuncDecl:whenever the semantic analyser visits the declaration at a subtree, it will callinsertto enter the identifier, its scope level and a pointer to the subtree into the symbol table.
To detect duplicate declarations using the same identifier, you call the method retrieveOneLevel. This method returns a pointer to the identifier entry if the identifier was declared before in the current scope and null otherwise.
• visitIdent:whenever the semantic analyser visits an applied occurrence of an identifierI, it will callretrieve with the identifierIand thus retrieves the pointer to the subtree representing its declaration. It will then decorate the identifier node for Iby establishing a link to this declaration. This link is null if no declaration is found. This fact will be used by you to detect undeclared variables.
• visitCompoundStmt:whenever the semantic analyser visits a block, it calls openScopeat the start of the block to open a new scope andcloseScopeat the end of the block to close the current scope.
Attachment:- ASSIGNMENT.rar