0

最近我不得不为以下表达式制作语法:

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

请帮我为这种情况编写规则,以便我同时拥有二叉树和自定义节点!我被困住了。

4

1 回答 1

0

您应该可以使用^({new AndNode(AND)} ...而不是^(AND<AndNode> ....

于 2013-01-15T14:00:13.067 回答