在同一个ANTLR4语法中使用单词作为语言关键字和标识符?

时间:2018-06-22 10:54:53

标签: antlr4 keyword identifier ambiguity mismatch

关于以下简化语法

proof_command : 'Proof' 'using' collection '.';
collection : 'Collection' IDENT ':=' section_subset_expr
           | 'Collection' KeySOME ':=' IDENT IDENT IDENT
           ;

KeySOME : 'Some';

(其中IDENT只是Java中的常规标识符),我试图解析以下内容:Proof using Collection Some := a b c .这不起作用,并导致以下错误消息:

输入'a'不匹配,期望为'section_subset_expr'

这是因为IDENT当然也可以是“ Some”。

是否可以使用Some作为关键字和标识符,因此上面的表达式可以正确解析?也许通过语义谓词在收集规则中排除IDENT中的“ Some”?但是那会是什么样子?

IDENT : IDENT2;
fragment IDENT2 : FIRST_LETTER (SUBSEQUENT_LETTER)*;
fragment FIRST_LETTER :  [a-z] | [A-Z] | '_' | UNICODE_LETTER;
fragment SUBSEQUENT_LETTER : [a-z] | [A-Z] | DIGIT | '_' | '"' | '\''| UNICODE_LETTER | UNICODE_ID_PART;
fragment UNICODE_LETTER : '\\' 'u' HEX HEX HEX HEX;
fragment UNICODE_ID_PART : '\\' 'u' HEX HEX HEX HEX;
fragment HEX : [0-9a-fA-F];

KeySOME : 'Some'; 

1 个答案:

答案 0 :(得分:1)

词法分析器的工作方式是,当可以在给定输入上匹配多个规则时,它将根据以下条件决定使用哪个规则:

  1. 如果一条规则导致比其他所有规则更长的匹配,则采用该规则(这被称为最大规则)
  2. 如果多个规则导致等长的匹配,则采用在语法中最先出现的匹配。直接出现在解析器规则中的文字(例如语法中的“证明”,“使用”和“集合”)被视为出现在任何命名的词法分析器规则之前。

因此,由于您的KeySOME规则出现在IDENT的后面,因此它将永远不会被采用,因为任何与KeySOME匹配的输入也会与IDENT匹配,并且IDENT首先出现

因此,您可以将KeySOME移动到IDENT之前,也可以完全删除规则,而直接在其位置使用'Some'(即'Collection' 'Some' ':=' IDENT IDENT IDENT)。 / p>