kristofer hat die Gist bearbeitet . Zu Änderung gehen
1 file changed, 79 insertions
symboltable2.md(Datei erstellt)
@@ -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 | + |
Neuer
Älter