最近我不得不为以下表达式编写语法:
rule1 & rule2 & rule3 => produces binary tree
(AndNode (AndNode RuleNode(rule1) RuleNode(rule2)) RuleNode(rule3))
rule1 | (rule2 & rule3) => produces binary tree
(OrNode RuleNode(rule1) (AndNode RuleNode(rule2) RuleNode(rule3)))
RuleNode,AndNode和OrNode是我的类,它将在以后用于评估整个表达式时使用。 rule1,rule2等只是我域中的概念,与解析器或词法分析器规则无关。
这是语法:
RULE : ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9')*;
QUOTE : '\'';
PARAM : QUOTE ( ~('\'') )* QUOTE;
LPAREN : '(';
RPAREN : ')';
DELIMITER : ',';
AND : '&';
OR : '|';
WS : (' ' | '\t')+ {$channel = HIDDEN;};
params : LPAREN! PARAM (DELIMITER! PARAM)* RPAREN!;
rule : RULE<RuleNode>^ params?;
expr : andexpr;
andexpr : orexpr (AND<AndNode>^ orexpr)*;
orexpr : atom (OR<OrNode>^ atom)*;
atom : rule | LPAREN! expr RPAREN!;
parse : expr;
一切都运行得很好,直到我要求将AND运算符设为默认运算符,所以我可以编写我的示例:
rule1 rule2 rule3
rule1 | (rule2 rule3)
我尝试以不同的方式指定anexpr规则:
1)
andexpr : orexpr+ -> (^(AND<AndNode> orexpr))+;
结果 - 生成不是二叉树的树,甚至没有根节点的AndNode:
(nil RuleNode(rule1) RuleNode(rule2) RuleNode(rule3))
2)
基于ANTLR Tree Construction(操作员部分)的第一个例子,我也试过了:
andexpr : (a=orexpr->$a) (b=orexpr -> ^(AND<AndNode> $andexpr $b))*;
结果 - 与1)相同的扁平树
如果我从2中删除自定义节点:
andexpr : (a=orexpr->$a) (b=orexpr -> ^(AND $andexpr $b))*;
然后解析器生成二叉树:
(AND (AND RuleNode(rule1) RuleNode(rule2)) RuleNode(rule3))
但不幸的是,AND不是我的自定义AndNode。我怀疑它与AndNode构造有关 - 在原始示例中使用'&amp;'要求应征者是
AndNode(Token token) { this.token = token; }
但是对于带有可选'&amp;'的语法我不得不实施一个新的
AndNode(int type) { }
不再接受Token作为参数。
请帮我写一下这个案例的规则,这样我就有了二叉树和自定义节点!我被卡住了。
答案 0 :(得分:0)
您应该可以使用^({new AndNode(AND)} ...
代替^(AND<AndNode> ...
。