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

在同一ANTLR4语法中将单词用作语言关键字和标识符?,antlr4,keyword,identifier,ambiguity,mismatch,Antlr4,Keyword,Identifier,Ambiguity,Mismatch,关于以下简化语法 proof_command : 'Proof' 'using' collection '.'; collection : 'Collection' IDENT ':=' section_subset_expr | 'Collection' KeySOME ':=' IDENT IDENT IDENT ; KeySOME : 'Some'; (在Java中,IDENT只是一个常用的标识符)我试图解析以下内容:使用集合Some进行证明

关于以下简化语法

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

KeySOME : 'Some';
(在Java中,IDENT只是一个常用的标识符)我试图解析以下内容:
使用集合Some进行证明:=abc。
这不起作用,并导致以下错误消息:

不匹配的输入“a”预期“部分”\u子集\u expr'

这是因为IDENT当然也可以是“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'; 

lexer的工作方式是,当给定输入上可以匹配多个规则时,它根据以下标准决定使用哪一个规则:

  • 如果一个规则导致比所有其他规则更长的匹配,则采用该规则(这称为最大多规则)
  • 如果多个规则导致长度相等的匹配,则采用语法中最先出现的规则。直接出现在语法分析器规则中的文本(例如语法中的“Proof”、“using”和“Collection”)被计算为出现在任何命名词法规则之前
  • 因此,由于
    KeySOME
    规则出现在
    IDENT
    后面,因此将永远不会采用该规则,因为匹配
    KeySOME
    的任何输入也会匹配
    IDENT
    IDENT


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

    在语法中,相对于定义键组的位置,您在哪里定义了
    IDENT
    ?我在IDENT后面定义了它。我不知道这会有什么不同。是吗?这让我更进一步了。但现在我不能再使用一些作为标识符了。这里不会解析:“Collection Some:=Some.”有什么方法可以解决这个问题吗?为了清楚起见,该语言允许某些标记作为关键字和标识符。@TilmanZuckmantel根据lexer规则,每个标记仅具有一种标记类型。
    Some
    总是一个关键字,或者总是一个
    IDENT
    。如果您想在某些位置允许使用
    Some
    来代替
    IDENT
    ,则必须在这些情况下明确添加它作为备选方案。也许通过一条规则
    idOrSome:IDENT |“Some”