ANTLR:如何在同一个AST中存储令牌和树节点?

时间:2016-01-15 08:10:05

标签: antlr antlr3

给出以下语法:

 statement : START value_list;
 value_list : LEFT_PARENTHESIS element += value (COMMA element += value)* RIGHT_PARENTHESIS -> ^(LIST $element+);
 value : NUMBER | STRING | value_list;
 START : 'START';
 LEFT_PARENTHESIS : '(';
 RIGHT_PARENTHESIS : ')';
 COMMA : ',';
 NUMBER : ('0'..'9')+;
 STRING : ('a'..'z' | 'A'..'Z')+;

如何在AST中存储COMMA?换句话说,如果尝试以下内容:

 value_list : LEFT_PARENTHESIS element += value (element += COMMA element += value)* RIGHT_PARENTHESIS -> ^(LIST $element+);

...它会出现以下错误:

 error(125): grammar.g:2:75: label element type mismatch with previous definition: token-list!=rule-list

有关如何解决此问题的任何提示?非常感谢你的帮助!

致以最诚挚的问候,

TJ。

2 个答案:

答案 0 :(得分:0)

问题是你可以在element列表或令牌中添加树节点,而不是同时添加两者。由于您需要将两者混合在一起,因此列表需要包含树节点,您必须将令牌元素转换为树节点。

解决方案1:

如果你想采用通用element +=方式,最简单的修复方法可能是使用简单的规则将词法分析器包裹在子树中:

comma: COMMA;

这样,如果您在规则中使用comma进行重写,则重写规则将获得带有令牌的nil树,而不是直接获取令牌。

解决方案2:

将括号内部包装在单独的规则中而不重写树,然后在原始规则中使用它并重写:

values : value (COMMA value)*;

value_list : LEFT_PARENTHESIS vals = values RIGHT_PARENTHESIS -> ^(LIST $vals);

答案 1 :(得分:0)

另一种解决方案是根本不使用令牌列表,只需在需要元素时迭代树节点。这是一个完全无关紧要且最灵活的解决方案。