parsingcompiler-constructionabstract-syntax-treesemantic-analysis

The construction of semantic analyser


In the process of learning about compilers a wrote a simple tokenizer and parser (recursive descent). The parser constructs an abstract syntax tree. Now I am going with semantic analysis. However I have a few questions about a construction of semantic analyser. Should I analyse the code semantically on the generated abstract syntax tree using recursive calls through the tree or maybe should I construct another tree (using a visitor pattern for example) for the purpose of semantic analysis. I found a document online which says that I should analyse the code semantically during the process of parsing, but it does not comply with a rule of single responsibility and makes the whole parser more prone to errors. Or maybe should I make semantic analysis a part of a intermediate representation generator? Maybe I am missing something, I would be grateful if someone could clarify this thing for me.


Solution

  • You are learning. Keep it simple; build a tree and run the semantic analyzer over the tree when parsing is completed.

    If you decide (someday) to build a fast compiler, you might consider implementing some of that semantic analysis as you parse. This makes building both the parser and the semantic analyzer harder because they are now interacting (tangled is a better word, read about why most C++ parsers are implemented with a so-called "lexer hack" if you want to get ill). You'll also find that sometimes the information you need isn't available ("is the target of that goto defined so far?" so you usually can't do a complete job as parse runs, or you may have to delay some semantic processing for later in the parse and that's tricky to arrange. I don't recommend adding this kind of complexity early in your compiler education.

    Start simple and focus on learning what semantic analysis is about.

    You can optimize later when it is clear what you have to optimize and why you should do it.