From 825e8613668e30bcaa688b717b418939e591dd0d Mon Sep 17 00:00:00 2001 From: lafrite Date: Sat, 8 Nov 2014 16:43:04 +0100 Subject: [PATCH] Start spliting exp --- pymath/expression.py | 136 +++++++++---------------------------------- pymath/str2tokens.py | 94 ++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 109 deletions(-) create mode 100644 pymath/str2tokens.py diff --git a/pymath/expression.py b/pymath/expression.py index 1be503d..c800d6e 100644 --- a/pymath/expression.py +++ b/pymath/expression.py @@ -108,88 +108,39 @@ class Expression(object): self.child = Expression(steps[-1]) + ## --------------------- - ## String parsing + ## "fix" recognition - @classmethod - def str2tokens(self, exp): - """ Parse the expression, ie tranform a string into a list of tokens + #@classmethod + #def get_fix(self, tokens): + # """ Give the "fix" of an expression + # [A, +, B] -> infix, or if there is parenthesis it is infix + # [+, A, B] -> prefix + # [A, B, +] -> postfix + # /!\ does not verify if the expression is correct/computable! - /!\ float are not availiable yet! + # :param exp: the expression (list of token) + # :returns: the "fix" (infix, postfix, prefix) - :param exp: The expression (a string) - :returns: list of token + # """ + # if self.isOperator(tokens[0]): + # return "prefix" + # elif "(" in tokens: + # return "infix" + # elif not self.isOperator(tokens[0]) and not self.isOperator(tokens[1]): + # return "postfix" + # else: + # return "infix" - """ - tokens = [''] + #def feed_fix(self): + # """ Recognize the fix of self.tokens and stock tokens in self.[fix]_tokens """ + # if len(self.tokens) > 1: + # fix = self.get_fix(self.tokens) + # else: + # fix = "postfix" # Completement arbitraire mais on s'en fiche! - for character in exp: - if character.isdigit(): - # for "big" numbers (like 2345) - if type(tokens[-1]) == int: - if tokens[-1] > 0: - tokens[-1] = tokens[-1]*10 + int(character) - else: - tokens[-1] = tokens[-1]*10 - int(character) - - - # Special case for "-" at the begining of an expression or before "(" - elif tokens[-1] == "-" and \ - str(tokens[-2]) in " (+-*/:": - tokens[-1] = - int(character) - else: - tokens.append(int(character)) - - elif character in "+-*/):^": - tokens.append(character) - - elif character in "(": - # If "3(", ")(" - if self.isNumber(tokens[-1]) \ - or tokens[-1] == ")" : - tokens.append("*") - tokens.append(character) - - elif character == ".": - raise ValueError("No float number please") - - elif character != " ": - raise ValueError("{} is an unvalid character".format(character)) - - return tokens[1:] - - # --------------------- - # "fix" recognition - - @classmethod - def get_fix(self, tokens): - """ Give the "fix" of an expression - [A, +, B] -> infix, or if there is parenthesis it is infix - [+, A, B] -> prefix - [A, B, +] -> postfix - /!\ does not verify if the expression is correct/computable! - - :param exp: the expression (list of token) - :returns: the "fix" (infix, postfix, prefix) - - """ - if self.isOperator(tokens[0]): - return "prefix" - elif "(" in tokens: - return "infix" - elif not self.isOperator(tokens[0]) and not self.isOperator(tokens[1]): - return "postfix" - else: - return "infix" - - def feed_fix(self): - """ Recognize the fix of self.tokens and stock tokens in self.[fix]_tokens """ - if len(self.tokens) > 1: - fix = self.get_fix(self.tokens) - else: - fix = "postfix" # Completement arbitraire mais on s'en fiche! - - setattr(self, fix+"_tokens", self.tokens) + # setattr(self, fix+"_tokens", self.tokens) # ---------------------- @@ -239,39 +190,6 @@ class Expression(object): # "fix" tranformations @classmethod - def in2post_fix(cls, infix_tokens): - """ From the infix_tokens list compute the corresponding postfix_tokens list - - @param infix_tokens: the infix list of tokens to transform into postfix form. - @return: the corresponding postfix list of tokens. - - >>> Expression.in2post_fix(['(', 2, '+', 5, '-', 1, ')', '/', '(', 3, '*', 4, ')']) - [2, 5, '+', 1, '-', 3, 4, '*', '/'] - """ - opStack = Stack() - postfixList = [] - - for token in infix_tokens: - if token == "(": - opStack.push(token) - elif token == ")": - topToken = opStack.pop() - while topToken != "(": - postfixList.append(topToken) - topToken = opStack.pop() - elif cls.isOperator(token): - # On doit ajouter la condition == str sinon python ne veut pas tester l'appartenance à la chaine de caractère. - while (not opStack.isEmpty()) and (cls.PRIORITY[opStack.peek()] >= cls.PRIORITY[token]): - postfixList.append(opStack.pop()) - opStack.push(token) - else: - postfixList.append(token) - - while not opStack.isEmpty(): - postfixList.append(opStack.pop()) - - return postfixList - ## --------------------- ## Computing the expression diff --git a/pymath/str2tokens.py b/pymath/str2tokens.py new file mode 100644 index 0000000..8c20f27 --- /dev/null +++ b/pymath/str2tokens.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# encoding: utf-8 + + + +def str2tokens(self, exp): + """ Parse the expression, ie tranform a string into a list of tokens + + /!\ float are not availiable yet! + + :param exp: The expression (a string) + :returns: list of token + + """ + tokens = [''] + + for character in exp: + if character.isdigit(): + # for "big" numbers (like 2345) + if type(tokens[-1]) == int: + if tokens[-1] > 0: + tokens[-1] = tokens[-1]*10 + int(character) + else: + tokens[-1] = tokens[-1]*10 - int(character) + + + # Special case for "-" at the begining of an expression or before "(" + elif tokens[-1] == "-" and \ + str(tokens[-2]) in " (+-*/:": + tokens[-1] = - int(character) + else: + tokens.append(int(character)) + + elif character in "+-*/):^": + tokens.append(character) + + elif character in "(": + # If "3(", ")(" + if self.isNumber(tokens[-1]) \ + or tokens[-1] == ")" : + tokens.append("*") + tokens.append(character) + + elif character == ".": + raise ValueError("No float number please") + + elif character != " ": + raise ValueError("{} is an unvalid character".format(character)) + + return tokens[1:] + + + +def in2post_fix(cls, infix_tokens): + """ From the infix_tokens list compute the corresponding postfix_tokens list + + @param infix_tokens: the infix list of tokens to transform into postfix form. + @return: the corresponding postfix list of tokens. + + >>> .in2post_fix(['(', 2, '+', 5, '-', 1, ')', '/', '(', 3, '*', 4, ')']) + [2, 5, '+', 1, '-', 3, 4, '*', '/'] + """ + opStack = Stack() + postfixList = [] + + for token in infix_tokens: + if token == "(": + opStack.push(token) + elif token == ")": + topToken = opStack.pop() + while topToken != "(": + postfixList.append(topToken) + topToken = opStack.pop() + elif cls.isOperator(token): + # On doit ajouter la condition == str sinon python ne veut pas tester l'appartenance à la chaine de caractère. + while (not opStack.isEmpty()) and (cls.PRIORITY[opStack.peek()] >= cls.PRIORITY[token]): + postfixList.append(opStack.pop()) + opStack.push(token) + else: + postfixList.append(token) + + while not opStack.isEmpty(): + postfixList.append(opStack.pop()) + + return postfixList + + + + + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del