I'm writing a compiler for one of my classes this semester, and although I have a working implementation of a symbol table, I am a bit uncomfortable with its implementation.
Since I'm doing the project in Python, I decided to go with an OO approach and my AST nodes all have an accept
method to implement the visitor pattern. I have preVisit
and postVisit
methods for all types of nodes, and I use them to enter/exit new scopes and add new bindings to the table. It works, but I feel uneasy about the fact that my symbol table is "ephemeral" and bound to this visitor class. I implemented type checking by subclassing the symbol table visitor class, and I needed to be extremely careful with my calls to the super class, to place them exactly at the correct place. The fragility of this implementation and the fact that any phase of the compiler will need to be tightly coupled to the visitor class is causing me some unease.
I was wondering in what other ways people typically implement symbol tables? Since that information is purely static, could it be added directly into the AST nodes? Is there a way to create a table that could be created once and symbols could be looked up in the correct context? Also, how do the purely functional programmers attack this problem?