0

我正在尝试编写一个计算器,它允许用户输入方程式并接收答案(适用操作顺序)。我不会使用 input() 命令来收集用户输入,而是使用 raw_input() 命令。我从另一个用户那里听说我可以在递归解析的帮助下完成这项任务,我引用:

“第一步是将字符串分成每个参数。

假设用户输入:

1+2.0+3+4

在您甚至可以转换为整数之前,您需要将字符串拆分为其组件:

1
+
2.0
+
3
+
4

这将需要一个递归解析器......” -aong152

此外,我阅读了这篇文章,它解释了如何使用递归解析来产生我正在寻找的结果:

http://blog.erezsh.com/how-to-write-a-calculator-in-70-python-lines-by-writing-a-recursive-descent-parser/

我不明白作者使用的编码,我在这个网站和谷歌上搜索过开始学习递归解析的帮助,但我找不到任何东西。谁能给我推动正确的方向并向我解释递归解析的基础知识?

4

2 回答 2

3

简单算术求和的递归解析可以很容易地类比为添加大量括号。递归解析器可能会像这样解析上述总和1+(2.0+(3+(4))):这样做的原因是你想把整个事情分解成可以计算的单个工作单元。这意味着每个部分必须最多包含两个数字和一个运算符(递归的基本情况是一个数字)。

每对括号都通过额外的递归级别(函数调用自身)添加。因此,最初的调用会看到类似“1 加上一些复杂的东西,下一级递归将为我处理”。

当尚未达到基本情况时,每次调用都会解析第一个数字和操作。然后,它会在操作后在字符串的下一部分调用自身,并返回操作符的结果,以获取其数字和下一次调用(例如,类似return number + parse(string[length:]))。

当达到基本情况时(字符串中只剩下一个数字),它不会根据另一个函数调用返回某些内容,而是只返回数字。然后,递归展开,每个函数都获得复数右手边的值。最终,原始调用将返回结果。

这很容易扩展到允许其他运算符,方法是让函数的每个实例都在一个运算符(而不是运算符和一个数字)上工作,以及它左右两边的表达式,从最高优先级的运算符开始。因此,在解析类似 的字符串时0+1+2*3+4,必须从乘法开始。您的函数返回类似 的function(left-hand-side) operator function(right-hand-side)内容,最初会像这样解析它(0+1+2)*(3+4):这将变成(0+(1+(2)))*(3+(4)). 您可以沿具有相同优先级的运算符进行线性解析,因此该算法可以迭代查找要递归的乘法或除法,递归找到的第一个;如果没有找到,它可以对加法和减法执行相同的操作,最后如果没有找到,则将数字作为基本情况返回(有趣的是,我给出的后一个示例有 2 个基本情况实例,2 和 4;这是一个功能多重递归)。

于 2013-05-09T03:30:19.460 回答
1

可以在此处找到使用pyparsing 且可以处理 +-/* 的完全正常工作的解析器:

http://pyparsing.wikispaces.com/file/view/fourFn.py/30154950/fourFn.py

这使用递归语法来处理括号的正确嵌套。阅读本书中的示例可能是值得的,您将学习编写语法以及它与解析器的不同之处!

于 2013-05-09T03:40:14.627 回答