import ptoken import tokenizer import queue import deque import copy debug = True def calculate_results(tokens): q = convert_to_queue(tokens) tokenizer.print_token_list(tokens) return process_tokens(q, True) def process_tokens(tokens, top_level = False): pending_operations = []#queue.Queue() power = 0 running_total = 0 p_ops_ran = False while True: if tokens.empty(): break token = tokens.get() if not top_level and token.type == ptoken.TokenType.exp_end: #if look_ahead.popleft().type == ptoken.TokenType.power: # power = float(look_ahead.value) break if token.type == ptoken.TokenType.exp_start: tmp = process_tokens(tokens) pending_operations.append(ptoken.Token(tmp, ptoken.TokenType.constant)) elif token.type == ptoken.TokenType.power: look_ahead = tokens.get() pending_operations.append(ptoken.Token(operate(pending_operations.pop().value, look_ahead.value, token.type), ptoken.TokenType.constant)) elif token.type == ptoken.TokenType.add or token.type == ptoken.TokenType.subtract: if len(pending_operations) > 0 and p_ops_ran: tmp = convert_to_queue(pending_operations) previous_token = None while True: if tmp.empty(): break tmp_token = tmp.get() if tmp_token.type == ptoken.TokenType.constant: previous_token = tmp_token elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract: look_ahead = tmp.get() running_total = operate(previous_token.value, look_ahead.value, tmp_token.type) previous_token = ptoken.Token(running_total, ptoken.TokenType.constant) pending_operations = [] pending_operations.append(previous_token) pending_operations.append(token) tokenizer.print_token_list(pending_operations) p_ops_ran = False elif token.type == ptoken.TokenType.constant: pending_operations.append(token) p_ops_ran = False elif token.type == ptoken.TokenType.multiply or token.type == ptoken.TokenType.divide: look_ahead = tokens.get() if look_ahead.type == ptoken.TokenType.exp_start: look_ahead = ptoken.Token(process_tokens(tokens), ptoken.TokenType.constant) look_behind = pending_operations.pop() running_total = operate(look_behind.value, look_ahead.value, token.type) pending_operations.append(ptoken.Token(running_total, ptoken.TokenType.constant)) p_ops_ran = True tokenizer.print_token_list(pending_operations) if power > 0: running_total = handle_pending(convert_to_queue(pending_operations)) running_total = operate(running_total, power, ptoken.TokenType.power) elif len(pending_operations) > 0: running_total = handle_pending(convert_to_queue(pending_operations)) return running_total def handle_pending(tokens): running_total = 0 previous_token = None while True: if tokens.empty(): break tmp_token = tokens.get() if tmp_token.type == ptoken.TokenType.constant: previous_token = tmp_token elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract: look_ahead = tokens.get() running_total = operate(previous_token.value, look_ahead.value, tmp_token.type) previous_token = ptoken.Token(running_total, ptoken.TokenType.constant) return running_total def convert_to_queue(tokens): q = queue.Queue() for tk in tokens: q.put(ptoken.Token(tk.value, tk.type)) return q def operate(n1, n2, tokenType): n1 = float(n1) n2 = float(n2) if tokenType == ptoken.TokenType.add: if debug: print("Adding %f and %f to get %f." %(n1, n2, n1 + n2)) return n1 + n2 elif tokenType == ptoken.TokenType.subtract: if debug: print("Subtracting %f and %f to get %f." %(n1, n2, n1 - n2)) return n1 - n2 elif tokenType == ptoken.TokenType.multiply: if debug: print("Multiplying %f and %f to get %f" %(n1, n2, n1 * n2)) return n1 * n2 elif tokenType == ptoken.TokenType.divide: if debug: print("Dividing %f and %f to get %f" %(n1, n2, n1 / n2)) return n1 / n2 elif tokenType == ptoken.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) def print_t(tokens): tmp = queue.Queue() while True: if tokens.empty(): break token = tokens.get() print("%s" %(token.value), end = "") tmp.put(token) print() return tmp