【发布时间】:2020-02-27 06:12:41
【问题描述】:
考虑我们有以下输入
formula = "(([foo] + [bar]) - ([baz]/2) )"
function_mapping = {
"foo" : FooFunction,
"bar" : BarFunction,
"baz" : BazFunction,
}
是否有任何 python 库可以让我解析公式并将其转换为 python 函数表示。
例如。
converted_formula = ((FooFunction() + BarFunction() - (BazFunction()/2))
我目前正在研究类似的东西
In [11]: ast = compiler.parse(formula)
In [12]: ast
Out[12]: Module(None, Stmt([Discard(Sub((Add((List([Name('foo')]), List([Name('bar')]))), Div((List([Name('baz')]), Const(2))))))]))
然后进一步处理这个 ast 树。
您知道任何更清洁的替代解决方案吗? 非常感谢任何帮助或见解!
【问题讨论】:
-
使用
compiler.parse()的一个潜在问题是它根据Python语法进行解析,这就是为什么它将公式中的[foo]变成List([Name('foo')])的原因。公式中使用的语法是什么? -
@martineau 确实,公式结构存在问题,因为它与 python List 类型冲突。我定义了公式的语法,因此可以给出类似
In [18]: formula = "((foo + bar) - (baz/2) )" In [19]: ast = compiler.parse(formula) In [20]: ast Out[20]: Module(None, Stmt([Discard(Sub((Add((Name('foo'), Name('bar'))), Div((Name('baz'), Const(2))))))])) -
您可以通过“简单地”进行文本替换来回避
compiler.parse()的语法问题,如下面的answer 所示。也就是说,最好定义公式表达式的语法,这样它就不会与现有的 Python 语法冲突。例如,代替re模块,可以使用string.Template替换$语法来做你想做的事情,这可能更容易理解和实现。
标签: python parsing abstract-syntax-tree dsl