Parse :: RecDescent:解析嵌套的算术表达式?

时间:2016-02-14 20:19:19

标签: perl parsing expression parse-recdescent

目前我用它来解析算术表达式:

expr  : '(' expr ')' 
      | number op expr 
      | variable op expr 
      | number
      | variable
      | <error>

它适用于简单表达式,但不能处理嵌套的括号表达式。 任何想法如何扩展/修改它,以便它可以处理嵌套表达式。

例如,这有效:

5 + 12
33 - $var
13 + 2 * $v
( 44 + 98 )

但这不起作用:

( 44 + 98 ) / 2
( 44 + 98 ) / ( 5 + $var2 )
( 11 + 5 ) * ( 3 + ( $v * 2 ) )

2 个答案:

答案 0 :(得分:4)

您的优先级链存在问题。 window.addEventListener('resize', function () { "use strict"; window.location.reload(); }); 可以解析为1 + (2 + 3),右侧的number op exprexpr,但'(' expr ')'无法解析,因为(1 + 2) + 3可以&expr #39; t出现在op的左侧。当然你不能直接在那里添加它,因为禁止左递归。你需要做的就是把它分解成:

expr: term '+' expr
    | term '-' expr
    | term

term: factor '*' term
      | factor '/' term
      | factor

factor: '(' expr ')'
    | number
    | variable
    | <error>

是的,在链的末尾,括号一直在那里,这可能看起来很奇怪,但它说的是带括号的表达式可以出现在一个因子可以的任何地方,并且会在它冒泡之前进行评估。现在很容易看出,因为所有内容都引用factor,所以括号内的表达式可以出现在任何需要的地方。

答案 1 :(得分:3)

使用中缀运算符添加规则以将括号中的表达式与另一个表达式组合:

| '(' expr ')' op expr

顺便说一句,原始语法不会受到嵌套表达式的影响,而是以括号中的术语开头的中缀表达式。

通常,用户hobbs的解决方案是使用不同首选项的中缀运算符处理表达式的标准方法。它的另一个优点是正确的子表达式评估顺序由语法处理,不需要额外的代码处理。

只有在你不需要一个成熟的表达式评估器时才能使用我的解决方案(你肯定会发现你需要一个......)。