给出以下语法:
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。
答案 0 :(得分:0)
问题是你可以在element
列表或令牌中添加树节点,而不是同时添加两者。由于您需要将两者混合在一起,因此列表需要包含树节点,您必须将令牌元素转换为树节点。
如果你想采用通用element +=
方式,最简单的修复方法可能是使用简单的规则将词法分析器包裹在子树中:
comma: COMMA;
这样,如果您在规则中使用comma
进行重写,则重写规则将获得带有令牌的nil
树,而不是直接获取令牌。
将括号内部包装在单独的规则中而不重写树,然后在原始规则中使用它并重写:
values : value (COMMA value)*;
value_list : LEFT_PARENTHESIS vals = values RIGHT_PARENTHESIS -> ^(LIST $vals);
答案 1 :(得分:0)
另一种解决方案是根本不使用令牌列表,只需在需要元素时迭代树节点。这是一个完全无关紧要且最灵活的解决方案。