最近我不得不为以下表达式制作语法:
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(Operators section)的第一个示例,我还尝试了:
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 构造有关 - 在原始示例中需要 '&' 的构造函数是
AndNode(Token token) { this.token = token; }
但是对于带有可选'&'的语法,我必须实现一个新的
AndNode(int type) { }
它不再接受 Token 作为参数。
请帮我为这种情况编写规则,以便我同时拥有二叉树和自定义节点!我被困住了。