symboltable2.md(файл создан)
| @@ -0,0 +1,79 @@ | |||
| 1 | + | describe how you would use python's dict data structure to build a symbol table for a small language compiler | |
| 2 | + | ||
| 3 | + | ## TinyLlama | |
| 4 | + | ||
| 5 | + | ||
| 6 | + | In a small language compiler like Python, the goal is to convert an input | |
| 7 | + | program into a bytecode that can be executed by an interpreter. This | |
| 8 | + | bytecode is then translated into machine code (CPU instructions) and | |
| 9 | + | executed by a CPU, or run directly in a virtual machine (VM). The | |
| 10 | + | intermediate representation for this process is called a symbol table, | |
| 11 | + | which is used to store information about the location and value of | |
| 12 | + | variables, function definitions, and other data items. | |
| 13 | + | ||
| 14 | + | To create a symbol table in Python, you can use a built-in module called | |
| 15 | + | "collections" that provides various types of dictionaries and lists. | |
| 16 | + | Here's an example code snippet: | |
| 17 | + | ||
| 18 | + | ```python | |
| 19 | + | from collections import namedtuple | |
| 20 | + | ||
| 21 | + | class Var(namedtuple("Var", ["name", "type"])): | |
| 22 | + | def __str__(self): | |
| 23 | + | return self.name + ": " + str(self.type) | |
| 24 | + | ||
| 25 | + | class FunDef(namedtuple("FunDef", ["name", "inputs", "body"])): | |
| 26 | + | def __str__(self): | |
| 27 | + | return "%s: %s" % (self.name, self.body) | |
| 28 | + | ||
| 29 | + | class SymbolTable: | |
| 30 | + | def __init__(self): | |
| 31 | + | self._dict = {} | |
| 32 | + | ||
| 33 | + | def get(self, name): | |
| 34 | + | try: | |
| 35 | + | return self._dict[name] | |
| 36 | + | except KeyError: | |
| 37 | + | raise NameError("%s is undefined" % name) | |
| 38 | + | ||
| 39 | + | def put(self, name, value): | |
| 40 | + | self._dict[name] = Var(name, type_=value) | |
| 41 | + | ||
| 42 | + | # Example input program and output symbol table | |
| 43 | + | input_file = open("input.py", "r") | |
| 44 | + | output_symbols = SymbolTable() | |
| 45 | + | for line in input_file: | |
| 46 | + | if line.startswith("#"): continue # skip comments and blank lines | |
| 47 | + | parts = line.split() | |
| 48 | + | if len(parts) < 2: continue # missing name or definition | |
| 49 | + | name, type_ = parts[0], parts[1] | |
| 50 | + | value = eval(parts[-1]) # evaluate expression at end of line | |
| 51 | + | output_symbols.put(name, Var(name, type=type_, body=value)) | |
| 52 | + | input_file.close() | |
| 53 | + | ``` | |
| 54 | + | ||
| 55 | + | In this example, we use the `namedtuple` class to define a new data | |
| 56 | + | structure with the `Var` class as its base class. The `get()` and `put()` | |
| 57 | + | methods then call the `__str__()` method to convert the variable's name | |
| 58 | + | and type into string representations, which can be used for printing or | |
| 59 | + | error messages. | |
| 60 | + | ||
| 61 | + | The `SymbolTable` class then initializes an empty dictionary that will | |
| 62 | + | store variables, function definitions, and other data items in a symbol | |
| 63 | + | table format. In addition, we use a `dict` object to define the methods | |
| 64 | + | that allow accessing, inserting, and removing entries from this | |
| 65 | + | dictionary. | |
| 66 | + | ||
| 67 | + | We can now use this symbol table to execute Python code by calling the | |
| 68 | + | `get()` or `put()` methods with the desired variable name and type: | |
| 69 | + | ||
| 70 | + | ```python | |
| 71 | + | # example input program | |
| 72 | + | x = 10 | |
| 73 | + | def add(a, b): return a + b | |
| 74 | + | print(add(3, x)) # error: expected argument 2 (value) to function "add" | |
| 75 | + | ``` | |
| 76 | + | ||
| 77 | + | The output symbol table would now contain the variable `x` with type | |
| 78 | + | `int`, which can be used for execution of the program. | |
| 79 | + | ||
Новее
Позже