ROOTS
class BinaryNode(TreeNode):
def init(self, left, right): # inherited methods
self.left, self.right = left, right # left/right branches
def validate(self, dict):
self.left.validate(dict) # recurse down branches
self.right.validate(dict)
def trace(self, level):
print('.' * level + '[' + self.label + ']')
self.left.trace(level+3)
self.right.trace(level+3)
class TimesNode(BinaryNode):
label = ''
def apply(self, dict):
return self.left.apply(dict) self.right.apply(dict)
class DivideNode(BinaryNode):
label = '/'
def apply(self, dict):
return self.left.apply(dict) / self.right.apply(dict)
class PlusNode(BinaryNode):
label = '+'
def apply(self, dict):
return self.left.apply(dict) + self.right.apply(dict)
class MinusNode(BinaryNode):
label = '-'
def apply(self, dict):
return self.left.apply(dict) - self.right.apply(dict)
LEAVES
class NumNode(TreeNode):
def init(self, num):
self.num = num # already numeric
def apply(self, dict): # use default validate
return self.num
def trace(self, level):
print('.' * level + repr(self.num)) # as code, was 'self.num'
class VarNode(TreeNode):
def init(self, text, start):
self.name = text # variable name
self.column = start # column for errors
def validate(self, dict):
if not self.name in dict.keys():
raise UndefinedError(self.name, self.column)
def apply(self, dict):
return dict[self.name] # validate before apply
def assign(self, value, dict):
dict[self.name] = value # local extension
1450 | Chapter 19: Text and Language