#!/usr/bin/env python # encoding: utf-8 from generic import Stack from calculus import isNumber, doMath class Expression(object): """An arithmetic expression""" priority = {"*" : 3, "/": 3, "+": 2, "-":2, "(": 1} def __init__(self, exp, fix = "infix"): """Initiate the expression. :param exp: the string representing the expression (infx form by default) :param fix: form of the expression infix (default) - postfix - prefix """ if fix == "infix": self._exp_infix = exp self._token_infix = exp.split(" ") elif fix == "postfix": self._token_postfix = exp else: print("Pas encore fait!") def infixToPostfix(self): """Convert the infix expression into postfix expression. """ #@todo importer les exemples opStack = Stack() postfixList = [] for token in self._token_infix: if token == "(": opStack.push(token) elif token == ")": topToken = opStack.pop() while topToken != "(": postfixList.append(topToken) topToken = opStack.pop() elif token in "+-*/": while (not opStack.isEmpty()) and (self.priority[opStack.peek()] >= self.priority[token]): postfixList.append(opStack.pop()) opStack.push(token) else: postfixList.append(token) while not opStack.isEmpty(): postfixList.append(opStack.pop()) self._token_postfix = postfixList self._exp_postfix = " ".join(postfixList) def computePostfix(self): """Compute a postfix expression like a good student :returns: list of steps to reach the result (postfix form) """ tokenList = self._token_postfix.copy() tmpTokenList = [] # on va chercher les motifs du genre A B + pour les calculer while len(tokenList) > 2: #print(tokenList[2]) if isNumber(tokenList[0]) and isNumber(tokenList[1]) and tokenList[2] in "+-*/": # S'il y a une opération à faire op1 = tokenList[0] op2 = tokenList[1] token = tokenList[2] res = doMath(token, op1, op2) tmpTokenList.append(res) # Comme on vient de faire le calcul, on peut détruire aussi les deux prochains termes del tokenList[0:3] else: tmpTokenList.append(tokenList[0]) del tokenList[0] tmpTokenList += tokenList if len(tmpTokenList) > 1: next_steps = Expression(tmpTokenList, fix = "postfix").computePostfix() else: next_steps = tmpTokenList print(self._exp_postfix) return [self._exp_postfix] + next_steps def test(exp): """Make various test on an expression """ print("-------------") print("Expression ",exp) expression = Expression(exp) expression.infixToPostfix() print(expression.computePostfix()) if __name__ == '__main__': exp = "1 + 3 * 5" test(exp) exp = "2 * 3 * 3 * 5" test(exp) exp = "2 * 3 + 3 * 5" test(exp) # ----------------------------- # Reglages pour 'vim' # vim:set autoindent expandtab tabstop=4 shiftwidth=4: # cursor: 16 del