通过递归下降在布尔表达式中解析+和*

时间:2016-04-13 17:55:33

标签: parsing recursion recursive-descent left-recursion

我正在为布尔表达式编写一个递归下降解析器,例如:

(1 * 0) 
(0 + ~1)
(0 * (1 + c)

其中1是'True',0是'False',+是'或',*是'和',〜是'not'而'c'只是一些变量名(它可以是任何单个字母)。我打算使用括号而不是实现某种操作顺序。

我当前的解析器可以识别以下表达式

Expression ::= 1
             | 0 
             | Character
             | ~ Expression

但我不确定如何在此基础上实现+和*。我很清楚我已经阅读了

的明显实现
Expression ::= 1
             | 0
             | Character
             | ( Expression + Expression )
             | ( Expression * Expression )

会导致无限循环,因为它是'left-recursive'。我不确定如何改变它以消除这种无限递归。

2 个答案:

答案 0 :(得分:1)

括号到位后,你所拥有的东西不会留下递归。左递归是指生产可以直接或间接地达到自身而两者之间没有消耗的代币。这样的语法确实会在递归下降解析器中引起无限递归,但这种情况不会发生在您的身上。

你确实遇到的问题是语法不明确:在括号之后,不知道+*形式是否被解析,直到整个左边-hand表达式已被解析。

解决该问题的一种方法是在共享前缀/后缀制作中提取公共部分:

Expression ::= 1
             | 0
             | Character
             | ParExpr

ParExpr ::= ( Expression ParOp  Expression )

ParOp ::= +
        | *

答案 1 :(得分:0)

让我为你搜索一下...... https://en.wikipedia.org/wiki/Recursive_descent_parser

领先的LPAREN使其不会被左递归。 如果要概括表达式并具有一些运算符优先级,请遵循Wikipedia文章中BNF的表达式部分。

但是,您选择的语法中存在语法歧义。如果您具有相同优先级的运算符,请将它们组合为非终结符,例如

LogOp :: = + | *

标记类似的操作数以允许扩展:

UnaryOp :: =〜

现在你可以......没关系,@ 500刚刚发布了一个很好的答案,涵盖了我的最后一点。