Antlr4 ANTLR似乎混淆了规则

Antlr4 ANTLR似乎混淆了规则,antlr4,Antlr4,要复制的最小语法: grammar GeneralSearchQuery; id : ID; ID : ('A'[A-Z0-9]+); anystring: ANYSTRING; ANYSTRING: ~[ \t\r\n"\\'():^]+; 问题在于“anystring”规则。如果我删除任何id/id规则,那么奇怪的解析就会消失 其目的是匹配除某些有意义的字符外的任何字符(unicode、非unicode) 据我所知,它是这样分解的: ~ Negate the follow

要复制的最小语法:

grammar GeneralSearchQuery;

id : ID;
ID : ('A'[A-Z0-9]+);

anystring: ANYSTRING;

ANYSTRING: ~[ \t\r\n"\\'():^]+;
问题在于“anystring”规则。如果我删除任何id/id规则,那么奇怪的解析就会消失

其目的是匹配除某些有意义的字符外的任何字符(unicode、非unicode)

据我所知,它是这样分解的:

~       Negate the following pattern
[       Start of a matching group
        Match a literal space 
    \t  Tab character
    \r  Newline character
    \n  Newline character
    "   Double quote character
    \\  backslash character
    '   Single quote character
    (   Left parenthesis
    )   Right parenthesis
    :   Colon character
    ^   Caret character
]       End of a matching group
+       Match the preceeding one or more times
因此,任何以大写字母a开头并以任何其他大写字母继续的字符串都无法解析。它似乎正在将规则更改为
不匹配id


关于我可能遗漏的内容有什么想法吗?

在词法分析阶段,输入将根据语法中的词法规则分成标记。此阶段不受解析器规则中发生的任何事情的影响。也就是说,对于给定的输入,lexer将始终使用相同的令牌序列,而不管解析器做什么或它想要什么类型的令牌

因此,要查看为给定输入生成的标记序列,我们只需要查看语法中定义的词汇规则,其中有两个:

ID : ('A'[A-Z0-9]+);
ANYSTRING: ~[ \t\r\n"\\'():^]+;
现在这两条规则明显重叠:任何可以由
ID
匹配的规则,也可以由
ANYSTRING
匹配。在这种情况下,适用最大咀嚼规则,该规则规定:

  • 如果多个规则可以生成匹配,则使用生成较长匹配的规则
  • 如果多个规则产生相同长度的匹配,则使用语法中第一个规则
  • 因此,根据这些规则,任何以
    a
    开头且不包含任何只能由
    ANYSTRING
    匹配的字符的输入都将生成
    ID
    标记

    如果希望
    anystring
    规则也与有效标识符匹配,则需要将其定义为:

    anystring: ID | ANYSTRING;
    
    anystring: ID | ANYSTRING;