201250093 谭子悦
The two major tasks in Lab 3 are to implement type checking and symbol renaming for SysY.
To implement type checking, we first need to maintain a symbol table with multiple scopes.
And then, with the symbol table in hand, we can check the type of symbol when traversing through non-terminal nodes.
My implementation uses three categories of classes and interfaces (Scope
, Symbol
, Type
) to implement the symbol table, and uses the visitor pattern in SemanticVisitor to iterate through the code.
Our program needs to rename the symbol according to the provided line number and column number.
My first idea was to modify the SyntaxVisitor
and let it find the target symbol in the first run, then rename all the occurrences of it in the second run. But then I found that it's hard for SyntaxVisitor
to recognize either two identities refer to the same symbol because it has no knowledge of either the symbol table or the scope layer.
Henceforth, in my later implementation, the SemanticVisitor
will:
Maintain a map of relation:
$$ f:S\rightarrow \{I_k~|~\exists k \in N.\textrm{ identity $I_k$ resolves to symbol $S$}\} $$
Remember the corresponding symbol S' of the target identity.
Then, the SyntaxVisitor
will have the SemanticVisitor
as its member variable. Each time it meets an identity terminal $I_k$, it will check whether $I_k \in f(S')$. If so, then it will change its name to the new name.
I only got a score of 1495 after doing all the stuff above. Then I reviewed my code carefully and found several mistakes, for example: