-
Notifications
You must be signed in to change notification settings - Fork 1
Intermediate code generator
The ICG (Intermediate Code Generator) turns an AST (Abstract Syntax Tree) into TAC (Three Address Code).
Since the semantic analyser should have found and reported all errors the received AST is assumed to be error free, which is the reason the interface doesn't facilitate the report log. If someting is still not correct an ICG Exception can be thrown allowing the controller to end execution in an orderly fashion and display some information as to what the fuc happened.
public interface IntermediateCodeGenerator {
public List<Quadruple> generateIntermediateCode(AST ast) throws IntermediateCodeGeneratorException;
}
The ICG is closely structured after the AST. It traverses the AST in a depth-first-left-to-right manner beginning at the root node of the AST. At it's core sits the function callProcessing
which gets called for each ASTNode
. This function contains a switch which checks the type of the current node and then calls the processing function for that type of node. Childnodes get processed by recursively calling callProcessing
.
The processing functions are put into separate ...Processor
classes which make the design more modular and group similar functionality together. All processors inherit from NodeProcessor
which has two members GeneratorState
and GeneratorExecutor
. The executor is a helper which allows to recursively call processing. The state stores the current results of the processing.
The members of the GeneratorState
are
-
List<Quadruple> intermediateCode
stores the already created TAC, is what gets returned after processing has finished. -
Stack<IntermediateResult> intermediateResults
if a Node has a value - like a constant or an expression - the value gets stored here, can then be popped in the parent and fed into aQuadruple
. -
Stack<SymbolTable> symbolTables
store the current symbol table to handle blocks correctly. -
Stack<String> breakLabels
allows proper handling of nested loops. -
Set<String> usedIdentifierNames
to prevent name clashes in the TAC if two blocks contain a declaration with the same name it keeps track of used names.
To get a smaller footprint some things were put into separate Classes since their functionality is used often. CastingFactory
allows to cast Types of variables e.g. from Long to Double. QuadrupleFactory
has methods to create Quadruples
with only one call since Different Types often require a switch to create the correct Quadruple
.
ArrayHelper
, BranchHelper
, and StructHelper
classes contain additional functionality that can be used from several processors.