目前我用它来解析算术表达式:
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 ) )
答案 0 :(得分:4)
您的优先级链存在问题。 window.addEventListener('resize', function () {
"use strict";
window.location.reload();
});
可以解析为1 + (2 + 3)
,右侧的number op expr
为expr
,但'(' 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的解决方案是使用不同首选项的中缀运算符处理表达式的标准方法。它的另一个优点是正确的子表达式评估顺序由语法处理,不需要额外的代码处理。
只有在你不需要一个成熟的表达式评估器时才能使用我的解决方案(你肯定会发现你需要一个......)。