Python常量折叠带标签

时间:2015-02-02 04:36:43

标签: python constant-expression constantfolding

我想做一些类似于使用Python进行常量折叠的东西。

Python有一个方便的构建函数eval(),因此通过应用eval()可以很容易地将常量方程式折叠起来。

示例:

s = '4 + (5) * 2'
reduced_s = str(eval(s))  # '14'

但是,我想要实现的常量折叠应该处理非常量标签。

示例:

s = '_tbl + (2) + (2) * 4' 
should be folded to '_tbl + 10'.

如果常量部分被标签分隔,例如(s ='2 + _tbl + 4'),它仍应产生'_tbl + 6'(或'6 + _tbl)。

几年前我用“C”编写了一个常量折叠程序。这不是一个小例程,因为我需要构建一个树并评估运算符的优先级。

由于Python比“C”更强大,在使用Python做同样的事情之前,我想寻求其他人的智慧。

非常感谢您对这一挑战的见解。

2 个答案:

答案 0 :(得分:0)

如果eval表达式中包含“+”,则需要解析表达式,但如果“+”操作在字符串表达式之外,则可以重载运算符“< strong>添加“以模拟评估。

class MyString(str):
    def __init__(self):
        self.mIntList = []
        self.mStringList = []

    def __add__(self, other):
        result = 0
        try:
            result = eval(other)
        except:
            self.mStringList.append(other)
        else:
            self.mIntList.append(result)
        finally:
            return self

    def __str__(self):
        return str(sum(self.mIntList)) + " ".join(self.mStringList)

if __name__ == '__main__':
    s1 = MyString()
    s1 = s1 + "_table" + "(2) + (2) * 4"
    print s1
    s2 = MyString()
    s2 = s2 + "2" + "table" + "2*4"
    print s2

输出

10_table
10table

答案 1 :(得分:0)

正如评论评论中指出的那样,使用ast模块听起来不错。下面我给出一个样本来分离非常量标签并评估表达式的其余部分。希望,这会给出一些积极的方向。

import ast

label = None

class MyTransformer(ast.NodeTransformer):

    def visit_Name(self, node):
        global label

        if(node.id != "evaluated"):
            label = node.id
            return ast.Num(0)
        return node


expression = '_tbl + (2) + (2) * 4' 

node = ast.parse("evaluated=" + expression)
node=MyTransformer().visit(node)
node = ast.fix_missing_locations(node)
eval(compile(node, '<string>', 'exec'))

print(label, str(evaluated))