Step3 Instructions
User Manual:
Open the PDF directly: View PDF .
Page Count: 3
Download | |
Open PDF In Browser | View PDF |
Project Step 3 — Symbol Table Your goal in this step is to process variable declarations and create Symbol Tables. A symbol table is a data structure that keeps information about non-keyword symbols that appear in source programs. Variables and function names are examples of such symbols. The symbols added to the symbol table will be used in many of the further phases of the compilation. In Step 2 you didn't need token values since only token types are used by parser generator tools to guide parsing. But in this step your parser needs to get token values such as identifier names and string literals from your scanner. You also need to add semantic actions to create symbol table entries and add those to the symbol table. Semantic Actions Semantic actions are steps that your compiler takes as the parser recognizes constructs in your program. Another way to think about this is that semantic actions are code that executes as your compiler matches various parts of the program (constructs like variable declarations or tokens like identifiers). By taking the right kind of action when the right kind of construct is recognized, you can make your compiler do useful work! One way to think about when to take actions in your parser is to think about associating actions with nodes of your parse tree. Each element in the parse tree can take an action to generate a semantic record for that node in the parse tree; these actions can include looking at the semantic records generated for the children in the parse tree. For example, consider the parse tree for the following piece of code: STRING foo := "Hello World"; Which produces the (partial) parse tree below: We can create semantic records for each of the tokens IDENTIFIER and STRINGLITERAL that record their values ("foo" and "Hello World", respectively), and "pass them up" the tree so that those records are the records for id and str. We can then construct a semantic record for string_decl using the semantic records of its children to produce a structure that captures the necessary information for a string declaration entry in your symbol table (and even add the entry to the symbol table). Parser-driven Semantic Actions It may seem like a lot of work to keep track of pieces of data at each node of the parse tree and assemble them into more complicated records. But most parsers help do this automatically. As they build up the parse tree, they will call actions that execute to collect data from the parse tree and create semantic records. In essence, the parsers perform a postorder traversal of the parse tree as they walk the tree, and store information about the necessary semantic records in a way that you can easily retrieve them. In ANTLR, you can extend the auto-generated Listener/ Visitor classes to implement sematic actions. It is worth remembering two things: 1. Tokens become leaves in the parse tree. The semantic record for a token is always the text associated with that token. 2. Every symbol that shows up in a grammar rule will be a node in your parse tree, and that if you recognize a grammar rule, there will be a node in your parse tree associated with the left-hand-side of the rule and that node will have a separate child for each of the symbols that appear on the right-hand side. Symbol Tables Your task in this step of the project is to construct symbol tables for each scope in your program. For each scope, construct a symbol table, then add entries to that symbol table as you see declarations. The declarations you have to handle are integer/float declarations, which should record the name and type of the variable, and string declarations, which should additionally record the value of the string. Note that typically function declarations/definitions would result in entries in the symbol table, too, but you do not have to record them for this step. Nested Symbol Tables There are multiple scopes where variables can be declared: • Variables can be declared before any functions. These are "global" variables and can be accessed from any function. • Variables can be declared as part of a function's parameter list. These are "local" to the function and cannot be accessed by any other function. • Variables can be declared at the beginning of a function body. These are "local" to the function as well. • Variables can be declared at the beginning of a then block, an else block, or a repeat statement. These are "local" to the block itself. Other blocks, even in the same function, cannot access these variables. Note that the scopes in the program are nested (function scopes are inside global scopes, and block scopes are nested inside function scopes, or each other). You will have to keep track of this nesting so that when a piece of code uses a variable named "x" you know which scope that variable is from. What you need to do You should define the necessary semantic actions and data structures to let you build the symbol table(s) for input programs. At the end of the parsing phase, you should print out the symbols you found. For each symbol table in your program, use the following format: Symbol tablename type name type value ; ... The global scope should be named "GLOBAL", function scopes should be given the same name as the function name, and block scopes should be called "BLOCK X" where X is a counter that increments every time you see a new block scope. Function parameters should be included as part of the function scope. The order of declarations matters! We expect the entries in your symbol table to appear in the same order that they appear in the original program. Keep this in mind as you design the data structures to store your symbol tables. See the sample outputs for more complete examples of what we are looking for. CAVEAT You may be tempted to just print declarations as you see them, rather than building an actual tree of symbol tables. While that will suffice for step 3, it will not be sufficient for step 4. We strongly suggest that you build the necessary data structures since you will have to, eventually, anyway. Handling errors Your compiler should output the string DECLARATION declarations with the same name in the same scope. ERROR if there are two
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf Linearized : No Page Count : 3 PDF Version : 1.4 Title : Microsoft Word - step3_instructions.docx Producer : macOS Version 10.14 (Build 18A391) Quartz PDFContext Creator : Word Create Date : 2019:02:16 12:04:42Z Modify Date : 2019:02:16 12:04:42ZEXIF Metadata provided by EXIF.tools