Parse::RecDescent : 解析嵌套算术表达式?
Parse::RecDescent : Parsing nested arithmetic expression?
目前我用它来解析算术表达式:
expr : '(' expr ')'
| number op expr
| variable op expr
| number
| variable
| <error>
它适用于简单的表达式,但不能处理嵌套的括号表达式。
知道如何 extend/modify 它可以处理嵌套表达式。
例如这个有效:
5 + 12
33 - $var
13 + 2 * $v
( 44 + 98 )
但这不起作用:
( 44 + 98 ) / 2
( 44 + 98 ) / ( 5 + $var2 )
( 11 + 5 ) * ( 3 + ( $v * 2 ) )
您的优先链有问题。 1 + (2 + 3)
可以解析为number op expr
,右边的expr
是'(' expr ')'
,但是(1 + 2) + 3
不行,因为expr
不行出现在 op
的左侧。当然你不能直接添加它,因为左递归是被禁止的。您需要做的是将其分解为:
expr: term '+' expr
| term '-' expr
| term
term: factor '*' term
| factor '/' term
| factor
factor: '(' expr ')'
| number
| variable
| <error>
是的,括号一直在链的末端,这可能看起来很奇怪,但它的意思是括号表达式可以出现在因子可以出现的任何地方,并且会在它冒泡之前被评估.现在很容易看出,因为所有内容都指向 factor
,所以带括号的表达式可以出现在任何需要的地方。
添加规则以使用中缀运算符将括号表达式与另一个表达式组合:
| '(' expr ')' op expr
顺便说一句,原始语法不会出现嵌套表达式,但会出现以括号中的术语开头的中缀表达式。
通常,用户 hobbs 的解决方案是处理具有不同偏好的中缀运算符的表达式的标准方法。它还有一个额外的好处,即正确的子表达式评估顺序由语法本身处理,不需要由额外代码处理。
仅当您不需要成熟的表达式求值器时才使用我的解决方案(您肯定会发现您需要一个...)。
目前我用它来解析算术表达式:
expr : '(' expr ')'
| number op expr
| variable op expr
| number
| variable
| <error>
它适用于简单的表达式,但不能处理嵌套的括号表达式。 知道如何 extend/modify 它可以处理嵌套表达式。
例如这个有效:
5 + 12
33 - $var
13 + 2 * $v
( 44 + 98 )
但这不起作用:
( 44 + 98 ) / 2
( 44 + 98 ) / ( 5 + $var2 )
( 11 + 5 ) * ( 3 + ( $v * 2 ) )
您的优先链有问题。 1 + (2 + 3)
可以解析为number op expr
,右边的expr
是'(' expr ')'
,但是(1 + 2) + 3
不行,因为expr
不行出现在 op
的左侧。当然你不能直接添加它,因为左递归是被禁止的。您需要做的是将其分解为:
expr: term '+' expr
| term '-' expr
| term
term: factor '*' term
| factor '/' term
| factor
factor: '(' expr ')'
| number
| variable
| <error>
是的,括号一直在链的末端,这可能看起来很奇怪,但它的意思是括号表达式可以出现在因子可以出现的任何地方,并且会在它冒泡之前被评估.现在很容易看出,因为所有内容都指向 factor
,所以带括号的表达式可以出现在任何需要的地方。
添加规则以使用中缀运算符将括号表达式与另一个表达式组合:
| '(' expr ')' op expr
顺便说一句,原始语法不会出现嵌套表达式,但会出现以括号中的术语开头的中缀表达式。
通常,用户 hobbs 的解决方案是处理具有不同偏好的中缀运算符的表达式的标准方法。它还有一个额外的好处,即正确的子表达式评估顺序由语法本身处理,不需要由额外代码处理。
仅当您不需要成熟的表达式求值器时才使用我的解决方案(您肯定会发现您需要一个...)。