考虑我的 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
。我在 COMPARE_EXPR
之前指定了 BINARY_EXPR
并且“+”具有更高的运算符优先级,所以我不知道如何告诉它应该首先寻找加法运算.我还能如何表达这一点,以便 Irony 以我想要的方式解析它?
最佳答案
我从未使用过 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 不够熟悉,无法谈论 "="
的关联性,所以我将其设为非关联性。
同样,我不熟悉您使用的框架,因此语法可能不正确;)
关于c# - Irony 解析器中的表达式优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14112958/