考虑我的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
并且“+”具有更高的运算符优先级,所以我无法弄清楚如何告诉它应该首先查找加法运算。我怎么能表达这一点,所以反讽会按照我的意图解析它?
答案 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) + 3
和1 + (2 + 3)
。我不熟悉VB,对"="
的关联性说了些什么,所以我把它变成了非关联的。
同样,我不熟悉您正在使用的框架,因此语法可能不正确;)