describe how you would use python's dict data structure to build a symbol table for a small language compiler
TinyLlama
In a small language compiler like Python, the goal is to convert an input program into a bytecode that can be executed by an interpreter. This bytecode is then translated into machine code (CPU instructions) and executed by a CPU, or run directly in a virtual machine (VM). The intermediate representation for this process is called a symbol table, which is used to store information about the location and value of variables, function definitions, and other data items.
To create a symbol table in Python, you can use a built-in module called "collections" that provides various types of dictionaries and lists. Here's an example code snippet:
from collections import namedtuple
class Var(namedtuple("Var", ["name", "type"])):
def __str__(self):
return self.name + ": " + str(self.type)
class FunDef(namedtuple("FunDef", ["name", "inputs", "body"])):
def __str__(self):
return "%s: %s" % (self.name, self.body)
class SymbolTable:
def __init__(self):
self._dict = {}
def get(self, name):
try:
return self._dict[name]
except KeyError:
raise NameError("%s is undefined" % name)
def put(self, name, value):
self._dict[name] = Var(name, type_=value)
# Example input program and output symbol table
input_file = open("input.py", "r")
output_symbols = SymbolTable()
for line in input_file:
if line.startswith("#"): continue # skip comments and blank lines
parts = line.split()
if len(parts) < 2: continue # missing name or definition
name, type_ = parts[0], parts[1]
value = eval(parts[-1]) # evaluate expression at end of line
output_symbols.put(name, Var(name, type=type_, body=value))
input_file.close()
In this example, we use the namedtuple
class to define a new data
structure with the Var
class as its base class. The get()
and put()
methods then call the __str__()
method to convert the variable's name
and type into string representations, which can be used for printing or
error messages.
The SymbolTable
class then initializes an empty dictionary that will
store variables, function definitions, and other data items in a symbol
table format. In addition, we use a dict
object to define the methods
that allow accessing, inserting, and removing entries from this
dictionary.
We can now use this symbol table to execute Python code by calling the
get()
or put()
methods with the desired variable name and type:
# example input program
x = 10
def add(a, b): return a + b
print(add(3, x)) # error: expected argument 2 (value) to function "add"
The output symbol table would now contain the variable x
with type
int
, which can be used for execution of the program.