parser.lit (3127B)
1 @code_type c .c 2 @comment_type /* %s */ 3 @compiler lit -t parser.lit && gcc -Wall -Wextra -Wstrict-aliasing=3 -Wwrite-strings -Wvla -Wcast-align=strict -Wstrict-prototypes -Wstringop-overflow=4 -Wshadow -fanalyzer -c parser.c -D TEST_PARSER -g -O0 -o parser.o 4 5 @title Parser 6 @add_css ./style.css 7 @s Note 8 THIS IS A LITERATE PROGRAM! Go to [this link](https://reagancfischer.dev/projects/cminus/code/parser.lit) to see the file that generated this HTML. 9 10 @s The Parser 11 The parser takes tokens from the lexer and builds an abstract syntax tree (AST) which we'll use to generate code. I'll be using a recursive descent parser for this project. 12 13 This will be a "dumb" parser, meaning it won't do any semantic analysis or type checking. You can see this distinction in the code for parsing declarations, which just stores the tokens for the declaration in the type itself instead of building a type. 14 15 A consequence of this is that the parser will freely accept nonsense like `double int x` or `int x = "hello";`, because both are valid according to the (simplified) grammar rules "vardecl -> type ID" and "vardecl -> type ID = expr". 16 17 The parser also won't build a symbol table. That'll be done in the semantic analysis phase. 18 19 @s Design 20 21 I'll break the parser into several modules: 22 - 'ast.c' will contain functions for building the AST, with similar isolation to the lexer. 23 - 'parsing.c' will contain functions for supporting the parser. If I define any functions that don't directly implement a grammar rule, they'll go here. 24 - 'expression.c' will contain functions for parsing expressions. 25 - 'declaration.c' will contain functions for parsing declarations. 26 - 'statement.c' will contain functions for parsing statements. 27 28 @s The AST Interface 29 The AST will be a tree of nodes, each representing a different part of the program. I'll define the AST in 'ast.h' and implement it in 'ast.c'. Like we did for tokens in the lexer, the AST will be an opaque type. The parser will only interact with the AST through functions I provide. 30 31 We'll need functions for creating and destroying nodes and functions for getting the types and values of nodes. I'm going to make the AST immutable, meaning that once a node is created, it can't be changed. 32 33 The AST will be implemented in 'ast.c'. All AST nodes share a common type, but extra data is stored using a zero-length array which resolves to a variable structure. 34 35 All the code for this is about 1500 lines of mind-numbing code. See the full implementation [here](https://reagancfischer.dev/projects/cminus/ast.html). 36 37 @s The Parser Interface 38 39 # Source code, biblography 40 A lot of the logic for this project is from either the Dragon Book, Engineering a Compiler, or LCC: A Retargetable Compiler for ANSI C. Grammars are from The C Reference Manual. 41 42 43 Literate programming rendered using [literate](https://github.com/zyedidia/Literate). 44 45 <footer style=" text-align: center; padding: 20px;"> 46 <p>© 2024 Reagan Fischer. If for some reason you want to use my AMAZING code (lol), it's available under the MIT 47 license <a href="/projects/cminus/code/LICENSE.md">here</a>.</p> 48 </footer>