def evaluate(token): if token.id == None or token.id == Types.END: raise Exception("Empty program") elif token.id == Types.BOOLEAN: return token.value elif token.id == Types.NUMBER: return token.value elif token.id == "not": return not evaluate(token.first) elif token.id == "and": return evaluate(token.first) and evaluate(token.second) elif token.id == "or": return evaluate(token.first) or evaluate(token.second) elif token.id == "+": return evaluate(token.first) + evaluate(token.second) elif token.id == "-": return evaluate(token.first) - evaluate(token.second) elif token.id == "*": return evaluate(token.first) * evaluate(token.second) elif token.id == "/": return float(evaluate(token.first)) / evaluate(token.second) elif token.id == "->": var = symbol(token.second.id) var.value = evaluate(token.first) return token.second.value elif token.id == "<-": var = symbol(token.first.id) var.value = evaluate(token.second) return token.first.value elif token.token_type == Types.VARIABLE: if token.value == None: raise Exception("Variable %s is not defined" % token.id) return token.value
def infix(id, bp): def led(self, left): self.first = left self.second = expression(bp) return self symbol(id, bp).led = led symbol(id, bp).token_type = Types.OPERATOR
def parentheses(id, closing, bp): def nud(self): expr = expression() # advance(")") global token if token.id != closing: raise SyntaxError("Expected %r" % closing) token = next() return expr symbol(id, bp).nud = nud symbol(id, bp).token_type = Types.OPERATOR
def tokenize(program): spaces, boolean, integer, double_operator, operator, variable = map(re.compile, ('^ +', 'False|True', '^[0-9]+', '^(->|<-|not|and|or)', '^[\+\-\*\/\(\)]', '^[a-zA-Z_]+')) while program != '': if spaces.match(program): mo = spaces.match(program) program = program[mo.end():] elif boolean.match(program): mo = boolean.match(program) p = program[0:mo.end()] t = symbol(Types.BOOLEAN)() if p == "True": t.value = True elif p == "False": t.value = False else: raise Exception("This should never happen") t.string = p yield t program = program[mo.end():] elif integer.match(program): mo = integer.match(program) p = program[0:mo.end()] t = symbol(Types.NUMBER)() t.value = int(p) t.string = p yield t program = program[mo.end():] elif double_operator.match(program): mo = double_operator.match(program) p = program[0:mo.end()] t = symbol(p)() t.string = p yield t program = program[mo.end():] elif operator.match(program): mo = operator.match(program) p = program[0:mo.end()] t = symbol(p)() t.string = p yield t program = program[mo.end():] elif variable.match(program): mo = variable.match(program) p = program[0:mo.end()] symbol(p).token_type = Types.VARIABLE t = symbol(p)() symbol(p).nud = lambda self: self symbol(p).lbp = 10 t.string = p yield t program = program[mo.end():] else: raise Exception("Something went wrong while parsing %s"%program) t = symbol(Types.END)() t.value = t.string = "END" yield t
def literal(type, lbp): symbol(type).token_type = type symbol(type).nud = lambda self: self symbol(type).lbp = lbp
def prefix(id, bp): def nud(self): self.first = expression(bp) return self symbol(id).nud = nud