from base_unit import Token, TokenType from collections import deque class Op: def __init__(self, left, op, right): self.left = left self.op = op self.right = right def __str__(self): return "%s (%s) and (%s)" %(TokenType.get_operator_verb(self.op), self.left, self.right) class Num: def __init__(self, token): self.value = token.value def __str__(self): return self.value class Variable: def __init__(self, token): self.symbol = token.value self.value = None def __str__(self): if self.value == None: return self.symbol else: return str(self.value) class Parser: def __init__(self, tokens): if len(tokens) == 0: raise ValueError("Token list can't be empty") self.bak = deque() self.variables = {} self.tokens = tokens self.current_token = None self.advance_current_token() self.ast = self.generate_ast() def get_tokens(self): new_list = [] for t in self.bak: if t.type == TokenType.variable: if t.value in self.variables: new_list.append(Token(self.variables[t.value], TokenType.constant)) else: new_list.append(Token(t.value, t.type)) return new_list def advance_current_token(self): if len(self.tokens) > 0: if self.current_token != None: self.bak.append(self.current_token) self.current_token = self.tokens.popleft() def factor(self): if self.current_token.type == TokenType.constant: node = Num(self.current_token) self.advance_current_token() return node elif self.current_token.type == TokenType.variable: node = Variable(self.current_token) self.variables[self.current_token.value] = node self.advance_current_token() return node elif self.current_token.type == TokenType.exp_start: self.advance_current_token() # ( node = self.topLevel() self.advance_current_token() # ) return node def lowLevel(self): node = self.factor() while self.current_token.type == TokenType.power: tmp = self.current_token self.advance_current_token() node = Op(left=node, op=tmp.type, right=self.factor()) return node def midLevel(self): node = self.lowLevel() while self.current_token.type in (TokenType.multiply, TokenType.divide): tmp = self.current_token self.advance_current_token() node = Op(left=node, op=tmp.type, right=self.lowLevel()) return node def topLevel(self): node = self.midLevel() while self.current_token.type in (TokenType.add, TokenType.subtract): tmp = self.current_token self.advance_current_token() node = Op(left=node, op=tmp.type, right=self.midLevel()) return node def generate_ast(self): return self.topLevel() def update_variable(self, symbol, value): if symbol in self.variables: self.variables[symbol].value = float(value) else: raise ValueError("Variable value must be a number.", value) def update_variables(self, variables): if len(variables) == 0: return for symbol in variables: if symbol in self.variables: self.variables[symbol].value = float(variables[symbol]) else: raise ValueError("Variable value must be a number.") def get_variable_value_pairs(self): keys = {} for symbol in self.variables: keys[symbol] = self.variables[symbol].value return keys