ANTLR 4中的重叠标记

时间:2013-11-13 19:25:21

标签: parsing antlr lexer antlr4

我有以下ANTLR 4组合语法:

grammar Example;

fieldList:  field* ;

field:      'field' identifier '{' note '}' ;

note:       NOTE ;
identifier: IDENTIFIER ;

NOTE:       [A-Ga-g] ;
IDENTIFIER: [A-Za-z0-9]+ ;
WS:         [ \t\r\n]+ -> skip ;

解析:

field x { A }
field x { B }

这不是:

field a { A }
field b { B }

在解析失败的情况下,我认为词法分析器会混淆并发出一个NOTE令牌,我想让它发出一个IDENTIFIER令牌。

编辑:

在词法分析器中出现的标记中,“NOTE”标记显示在解析器期望“IDENTIFIER”的位置。 'NOTE'具有更高的优先级,因为它首先显示在语法中。所以,我可以想出两种方法来解决这个问题......首先,我可以改变语法来消除'NOTE'和'IDENTIFIER'的歧义(就像在'NOTE'前加一个'$')。或者,我可以使用'IDENTIFIER',我会使用note,然后在我走遍解析树时处理检测问题。这些都不是最佳的。肯定有办法解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

我实际上最终解决了这个问题:

grammar Example;

fieldList:  field* ;

field:      'field' identifier '{' note '}' ;

note:       NOTE ;
identifier: IDENTIFIER | NOTE ;

NOTE:       [A-Ga-g] ;
IDENTIFIER: [A-Za-z0-9]+ ;
WS:         [ \t\r\n]+ -> skip ;

我的解析树仍然看起来像我想要的那样。

我正在开发的实际语法更复杂,基于此方法的解决方法也是如此。但总的来说,这种方法似乎运作良好。

答案 1 :(得分:0)

对您的问题进行快速而又脏的修复可以是: 更改IDENTIFIER以仅匹配NOTE的补码。然后将它们放在identifier

结果语法:

grammar Example;

fieldList:  field* ;

field:      'field' identifier '{' note '}' ;

note:       NOTE ;
identifier: (NOTE|IDENTIFIER_C)+ ;

NOTE:       [A-Ga-g] ;
IDENTIFIER_C: [H-Zh-z0-9] ;
WS:         [ \t\r\n]+ -> skip ;

此解决方案的缺点是,您没有将标识符作为标记,并且您将每个字符标记化。