反语解析器中的表达式优先级

时间:2013-01-01 18:14:43

标签: c# parsing expression irony

考虑我的vbscript语法的这部分

EXPR.Rule = BINARY_EXPR 
        | COMPARE_EXPR
        | AND_EXPR
        | OR_EXPR;

BINARY_EXPR.Rule = EXPR + BINARY_OP + EXPR + ReduceHere();
COMPARE_EXPR.Rule = EXPR + COMPARE_OP + EXPR + ReduceHere();
AND_EXPR.Rule = EXPR + "and" + EXPR;
OR_EXPR.Rule = EXPR + "or" + EXPR;

COMPARE_OP.Rule = ToTerm("=") | "<=" | ">=" | "<" | ">" | "<>";
BINARY_OP.Rule = ToTerm("+") | "&" | "^" | "-" | "*" | "/" | "\\";// | "=" | "<=" | ">=" | "<" | ">" | "<>" | "mod" | "and" | "or";

RegisterOperators(60, "^");
RegisterOperators(50, "*", "/", "\\", "mod");
RegisterOperators(40, "+", "-", "&");
RegisterOperators(30, "=", "<=", ">=", "<", ">", "<>");
RegisterOperators(20, "and", "or");

和这个vbscript程序:

if 2=1+1 then x = 5

它将其解析为if (2=1)+1 then x = 5而不是if 2=(1+1) then x = 5。我在BINARY_EXPR之前指定COMPARE_EXPR并且“+”具有更高的运算符优先级,所以我无法弄清楚如何告诉它应该首先查找加法运算。我怎么能表达这一点,所以反讽会按照​​我的意图解析它?

1 个答案:

答案 0 :(得分:2)

我从未与Irony合作,但如果它没有提供该功能(或者如果你无法弄清楚它是如何工作的),你总是可以尝试对你的EXPR非终结分层。

我们只采用加法,减法,乘法,括号和比较,例如:

EXPR0.Rule = EXPR1
           | EXPR1 + "=" + EXPR1
           ;
EXPR1.Rule = EXPR2
           | EXPR1 + "+" + EXPR1
           | EXPR1 + "-" + EXPR2
           ;
EXPR2.Rule = EXPR3
           | EXPR2 + "*" + EXPR2
           ;
EXPR3.Rule = "(" + EXPR0 + ")"
           | USEVARIABLE
           | LITERAL
           ;

具有相同优先权的所有运营商都居住在他们自己的阶层中。他们不能在左侧或右侧拥有较低优先级的运算符,而不会一直运行到EXPR3,这会提供回EXPR0的循环。

请注意,"-"在其右侧需要EXPR2。这是因为它是right-associative operator,而"+"是关联运算符。虽然1 - 2 - 3必须始终被解释为(1 - 2) - 3,但1 + 2 + 3可以被解释为(1 + 2) + 31 + (2 + 3)。我不熟悉VB,对"="的关联性说了些什么,所以我把它变成了非关联的。

同样,我不熟悉您正在使用的框架,因此语法可能不正确;)