import ptoken as token import tokenizer import uuid import calc_engine 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)" %(token.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 Parser: def __init__(self, tokens): self.tokens = tokens self.current_token = self.tokens.pop() def eat(self, token_type): if self.current_token.type != token_type: print("grammar") if len(self.tokens) > 0: self.current_token = self.tokens.pop() def factor(self): node = self.current_token #print(node) if self.current_token.type == token.TokenType.constant: self.eat(token.TokenType.constant) return Num(node) elif self.current_token.type == token.TokenType.exp_start: self.eat(token.TokenType.exp_start) node = self.topLevel() self.eat(token.TokenType.exp_end) return node def lowLevel(self): node = self.factor() while self.current_token.type == token.TokenType.power: t = self.current_token if t.type == token.TokenType.power: self.eat(token.TokenType.power) node = Op(left=node, op=t.type, right=self.factor()) return node def midLevel(self): node = self.lowLevel() while self.current_token.type in (token.TokenType.multiply, token.TokenType.divide): t = self.current_token if t.type == token.TokenType.multiply: self.eat(token.TokenType.multiply) elif t.type == token.TokenType.divide: self.eat(token.TokenType.divide) node = Op(left=node, op=t.type, right=self.lowLevel()) return node def topLevel(self): node = self.midLevel() while self.current_token.type in (token.TokenType.add, token.TokenType.subtract): t = self.current_token if t.type == token.TokenType.add: self.eat(token.TokenType.add) elif t.type == token.TokenType.subtract: self.eat(token.TokenType.subtract) node = Op(left=node, op=t.type, right=self.midLevel()) return node def parse(self): #print("C: %s" %(self.current_token)) return self.topLevel() def print_tree(root): depth = Parser.get_tree_diameter(root) for i in range(depth): print("%s" %("".rjust(depth - i, ' ')), end = "" ) Parser.print_height(root, i) print() def print_height(node, level): if node == None: return if level == 0: print("%s " %(str(node)), end = "") else: Parser.print_height(node.left, level - 1) Parser.print_height(node.right, level - 1) def get_tree_diameter(node): if type(node) is Num: return 0 if node == None: return 0 return 1 + max(Parser.get_tree_diameter(node.left), Parser.get_tree_diameter(node.right)) def p(node): if type(node) is Num: #print("%s " %(node), end ="") return else: #Parser.p(node.left) print(node) #Parser.p(node.right) Parser.p(node.left) Parser.p(node.right) def calc(node): if type(node) is Num: return float(node.value) left = calc(node.left) right = calc(node.right) return operate(left, right, node.op) debug = True def operate(n1, n2, tokenType): # Utility function to handle dealing with the various mathmatical operations that the engine can process. # Returns the result of any one of five mathmatical operations, else throws an error for unrecognized operations. n1 = float(n1) n2 = float(n2) if tokenType == token.TokenType.add: if debug: print("Adding %f and %f to get %f." %(n1, n2, n1 + n2)) return n1 + n2 elif tokenType == token.TokenType.subtract: if debug: print("Subtracting %f and %f to get %f." %(n1, n2, n1 - n2)) return n1 - n2 elif tokenType == token.TokenType.multiply: if debug: print("Multiplying %f and %f to get %f" %(n1, n2, n1 * n2)) return n1 * n2 elif tokenType == token.TokenType.divide: if debug: print("Dividing %f and %f to get %f" %(n1, n2, n1 / n2)) return n1 / n2 elif tokenType == token.TokenType.power: if debug: print("Raising %f to the power of %f to get %f" %(n1, n2, n1**n2)) return n1 ** n2 else: raise TypeError("Invalid operator value " + str(tokenType) + ".", tokenType) # k(((1+i)^n - 1)/i) #t = Add() #t.add_child(Constant(4)) #t.add_child(Sub()) #t.left.add_child(Sub()) tokens = tokenizer.get_tokens_from_expression_string("5*2^(2+1)-(1+5)-2^5+5*(2/2*3+5)^2") #tokens.reverse() #print(calc_engine.calculate_results(tokens)) #tokens = tokenizer.get_tokens_from_expression_string("200((1-(1.08)^(-12))/0.08)") #print(calc_engine.calculate_results(tokens)) #tokens = tokenizer.get_tokens_from_expression_string("1+6 / 2") #n = Parser(tokens) #s = n.parse() #Parser.p(s) #print(calc(s))