我想创建一个语法来解析类似于S表达式语法的公式语言玩具。
我阅读了“PyParsing入门”一书,其中包含一个非常好的部分,其中包含类似的语法。
要解析的两个数据示例是:
sum(5,10,avg(15,20))+10
stdev(5,10)*2
现在,我已经提出了一种语法,可以解析公式,但却无视 扩展功能和运营商优先权。
继续使用它的最佳做法是:我应该添加parseActions吗? 对于与函数名称匹配的单词(sum,avg ...)。如果我构建一个嵌套的 列表,我可以深入分析解析结果并评估函数吗?
答案 0 :(得分:3)
如果没有看到更多代码,建议会有点困难。尽管如此,从你描述的内容来看,听起来你大部分是标记化,识别标点符号的各个部分,并将变量名称与代数运算符的数值常量区分开来。 nestedExpr将赋予一些结构,但只有基本的括号嵌套 - 这仍然会为您的解析后工作留下运算符优先级处理。
如果您正在学习解析中缀表示法,那么有一系列的pyparsing示例可供查看和研究(在pyparsing wiki Examples page)。从fourFn.py开始,它实际上是一个五函数中缀表示法解析器。查看其BNF()方法,并了解递归定义的工作原理(不要担心pushFirst解析操作)。通过这种方式构造解析器,运算符优先级可以直接构建到解析后的结果中。如果你解析4 + 2 * 3
,只需一个标记器就可以给你['4','+','2','*','3']
,然后你必须弄清楚如何在添加4来获得10之前做2 * 3,而不仅仅是暴力加4和2,然后乘以3(这给出了18的错误答案)。 fourFn.py中的解析器将为您提供['4','+',['2','*','3']]
,这足以让您知道在将其添加到4之前评估2 * 3部分。
解析使用操作优先级的中缀表示法的整个概念是如此常见,我编写了一个辅助函数来完成大部分艰苦的工作,称为operatorPrecedence
。您可以在simpleArith.py示例中看到它是如何工作的,然后转到eval_arith.py以查看扩展需要创建解析结构的求值程序。 simpleBool.py是另一个很好的例子,它显示逻辑术语AND'ed和OR'ed的优先级。
最后,既然您正在做类似Excel的事情,请查看excelExpr.py。它试图处理一些在尝试评估Excel单元格引用时遇到的疯狂角落案例,包括对其他工作表和其他工作簿的引用。
祝你好运!