【问题标题】:ANTLR expression with optional operator + custom AST nodes具有可选运算符 + 自定义 AST 节点的 ANTLR 表达式
【发布时间】:2013-01-15 13:25:14
【问题描述】:

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

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 构造有关 - 在原始示例中需要 '&' 构造函数是

AndNode(Token token) { this.token = token; } 

但是对于带有可选“&”的语法,我必须实现一个新的

AndNode(int type) { } 

不再接受 Token 作为参数。

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

【问题讨论】:

    标签: tree antlr optional


    【解决方案1】:

    您应该可以使用^({new AndNode(AND)} ... 而不是^(AND&lt;AndNode&gt; ...

    【讨论】:

    • 是的 280Z28 我可以使用 {new AndNode(AND)} 但它没有帮助。问题是传递给 AndNode 构造函数的 AND 只是一个节点类型常量(整数)而不是 Token 对象。我认为正确构造树需要 Token 对象。如果我有像“rule1 rule2”这样的表达式,那么没有对应于可选 '&' 运算符的令牌。我的问题是 - 我可以做些什么来在规则之间产生空格,就像操作员(一个真正的令牌)一样?:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多