具有可选运算符+自定义AST节点的ANTLR表达式

时间:2013-01-15 13:25:15

标签: tree antlr optional

最近我不得不为以下表达式编写语法:

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作为参数。

请帮我写一下这个案例的规则,这样我就有了二叉树和自定义节点!我被卡住了。

1 个答案:

答案 0 :(得分:0)

您应该可以使用^({new AndNode(AND)} ...代替^(AND<AndNode> ...