0

我想创建一个语法来解析类似于 S 表达式语法的玩具式公式语言。

我通读了“PyParsing 入门”一书,其中包含一个非常好的部分,涵盖了类似的语法。

要解析的两个数据示例是:

sum(5,10,avg(15,20))+10
stdev(5,10)*2

现在,我想出了一种语法,它可以解析公式,但忽略扩展函数和运算符优先级。

继续使用它的最佳做法是什么:我是否应该为匹配 oneOf 函数名称( sum, avg ... )的单词添加 parseActions 。如果我构建一个嵌套列表,我可以对解析结果进行深度优先遍历并评估函数吗?

4

1 回答 1

3

在没有看到更多代码的情况下提出建议有点困难。尽管如此,根据您的描述,听起来您主要是在进行标记化,以识别各种标点符号并将变量名称与代数运算符中的数字常量区分开来。nestedExpr 将赋予一些结构,但只是基本的括号嵌套 - 这仍然为您的解析后工作留下运算符优先级处理。

如果您正在学习解析中缀表示法,有一系列 pyparsing 示例供您查看和研究(在pyparsing wiki 示例页面)。从fourFn.py 开始,它实际上是一个函数中缀符号解析器。查看它的 BNF() 方法,了解递归定义是如何工作的(暂时不用担心 pushFirst 解析操作)。通过以这种方式构造解析器,运算符优先级直接内置到解析结果中。如果你 parse 4 + 2 * 3,一个单纯的分词器只会给你['4','+','2','*','3'],然后你必须弄清楚如何在添加 4 以获得 10 之前执行 2*3 ,而不仅仅是蛮力添加 4 和 2,然后乘以 3 (这给出18 的错误答案)。fourFn.py 中的解析器会给你['4','+',['2','*','3']],这足以让您知道在将 2*3 部分添加到 4 之前对其进行评估。

使用操作优先级来解析中缀符号的整个概念非常普遍,我编写了一个辅助函数来完成大部分艰苦的工作,称为operatorPrecedence. 您可以在示例 simpleArith.py 中查看其工作原理,然后转到 eval_arith.py 以查看创建解析结构评估器所需的扩展。simpleBool.py 是另一个很好的例子,它显示了逻辑术语 AND'ed 和 OR'ed 在一起的优先级。

最后,既然您正在做类似 Excel 的事情,请查看 excelExpr.py。它尝试处理您在尝试评估 Excel 单元格引用时遇到的一些疯狂的极端情况,包括对其他工作表和其他工作簿的引用。

祝你好运!

于 2011-06-04T16:19:14.733 回答