Search code examples
compiler-construction

Writing a compiler: will symbol table still be used after semantic analysis (type-checking)


I am reading Modern Compiler Implementation In ML, and trying to do the compiler project (the tiger language).

In chapter 5, semantic analysis, it uses functional data structure for constructing symbol stable. So insert table key value will return a new table, instead of modify the existing table, and the old table is preserved when the function returns. So when type checking is done, the symbol table is still empty.

My question is, does it mean the symbol table is purely used for type checking? Because I've read this SO post, which says symbol table is also going to be used in code generation (I haven't gone that far yet).

If symbol table should be used after semantic analysis, should I use imperative data structure?

Any concrete example would be appreciated. :)


Solution

  • No. You might want it for code generation, error/feedback reporting, and for linking.

    Type checking just verifies the program isn't obviously insane. At the completion of checking, you may now want to generate intermediate code. The Java expression

      a+b
    

    may be type checked, but when going to generate code it matters what the types of a and b are. You get different code depending on whether a and b are respectively numbers or strings or even different.

    For reporting, it may be that during code generation and optimization, the compiler has an opinion about why it cannot make a certain desired result. In that case, it may wish to communicate the opinion to the user in his terms; often in terms of some named entity which contributes to the opinion. To do that, you need to retain ties from the intermediate representation back to the names in the symbol table.

    Finally, you may have system of seperate compilation. If that is the case, the linkages between seperately compiled elements is usually done by use of names exported from the program by the compiler, to the linker. You can hardly link a call to "foo" if foo is defined in another compilation unit, unless the compiler and linker agree to name the linkage, well, "foo".

    So no, you shouldn't throw the symbol table away.