我正在使用Irony.net生成源代码之外的解析树。基本上,我使用ExpressionEvaluatorGrammer就像二进制表达式(算术,关系和逻辑/条件)的语法。我想通过遍历它将生成的分析树转换为Linq表达式。但是,树似乎没有可以直接转换为linq条件表达式的格式。这种表达的假设的例子:遍历具有复杂条件表达式的ast来生成linq表达式
1 == 1 && 4 - 1 == 3
产生(为了简洁伪XML树):
<binary>
<binary>
<binary>
<literal>1</literal>
<op>==</op>
<literal>1</literal>
</binary>
<op>&&</op>
<binary>
<literal>4</literal>
<op>-</op>
<literal>1</literal>
</binary>
</binary>
<op>==</op>
<literal>3</literal>
</binary>
在上面的树中,算术表达式(4 - 1)成为合适的表情到& &随着父节点关闭后的逻辑操作。在理想世界中,它应该是代表“== 3”的节点的左表达式。
你如何遍历这样的树来生成一个合适的和操作?或者,有没有办法以我想要的形式生成树?
编辑:这是语法(部分)的定义。我从Irony.interpreter附带的ExpressionEvaluatorGrammer中提取了它。
RegisterOperators(15, "&", "&&", "|", "||");
RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
RegisterOperators(30, "+", "-");
RegisterOperators(40, "*", "/");
Expr.Rule = Term
Term.Rule = number | ParExpr | stringLit | FunctionCall | identifier | MemberAccess | IndexedAccess;
ParExpr.Rule = "(" + Expr + ")";
BinExpr.Rule = Expr + BinOp + Expr;
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**" | "==" | "<" | "<=" | ">" | ">=" | "!=" | "&&" | "||" | "&" | "|";
我不知道Irony.Net但它生成的xml对应于((1 == 1)&&(4 * 1))== 3。无论是&&和==具有相同的优先级,而*具有更高的优先级或它是一个错误。您可能会尝试在解析之前添加paranthesis,或使用其他工具。如果实际的语法不复杂得多,手动编写解析器(直接生成表达式)应该不会很困难。 – 2012-01-28 16:16:33
你对'RegisterOperators'的看法是什么样子?你如何设置关联性? – user7116 2012-01-28 16:35:25
@sixlettervariables请参阅具有优先级的语法 – 2012-01-28 16:50:32