Summary
In this chapter, you learned about the techniques a real-world compiler uses in the frontend. Starting with the project's layout, you created separate libraries for the lexer, the parser, and the semantic analyzer. To output messages to the user, you extended an existing LLVM class, which allowed the messages to be stored centrally. The lexer has now been separated into several interfaces.
You then learned how to construct a recursive descent parser from a grammar description, which pitfalls to avoid, and how to use generators to do the job. The semantic analyzer you constructed performs all the semantic checks that are required by the language while being intertwined with the parser and AST construction.
The result of your coding effort was a fully decorated AST, which will be used in the next chapter to generate IR code and object code.