我想做一些类似于使用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做同样的事情之前,我想寻求其他人的智慧。
非常感谢您对这一挑战的见解。
答案 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))