ANTLR 解析器/词法分析器中的可选前缀

Joa*_*man 5 antlr antlr4

我正在尝试使用 ANTLR4 来解析由以下语法描述的输入字符串:

\n\n
grammar MyGrammar;\n\nparse : PREFIX? SEARCH;\n\nPREFIX\n  : [0-9]+ \':\'\n  ;\n\nSEARCH\n  : .+ \n  ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

例如,有效的输入字符串包括:

\n\n
0: maracuj\xc3\xa1\napple\n3:\xe2\x82\xac53.60\n1: 10kg\n2:chilli pepper\n
Run Code Online (Sandbox Code Playgroud)\n\n

但该SEARCH规则始终匹配整个字符串 - 无论它是否有前缀。

\n\n

我理解这是因为 ANTLR4 词法分析器优先考虑匹配最长字符串的规则。因此,该SEARCH规则匹配所有输入,而不给该PREFIX规则机会。

\n\n

非贪婪版本(即SEARCH : .+? ;)也有同样的问题,因为(据我了解)它只是规则内的非贪婪 - 并且规则SEARCH没有任何其他部分来约束它。

\n\n

如果有帮助,我可以限制SEARCH要排除的文本\':\',但我真的希望它能识别其他任何内容 - unicode 字符、符号、数字、空格等。

\n\n

我已经读过Lexer 来处理带有行号前缀的行,但在这种情况下,字符串的主体(在前缀之后)明显受到更多限制。

\n\n

注意: SEARCH文本可能有一个结构 - 如\xe2\x82\xac53.0010kg以上(我也希望 ANTLR4 解析),或者它可能只是自由文本 - 如applemaracuj\xc3\xa1以上chilli pepper。但我尝试简化,这样我就可以解决提取第一个的问题PREFIX

\n

Cor*_*onA 2

ANTLR 在解析之前进行词法分析。词法分析器更喜欢长匹配,并且 SEARCH 标记会匹配每个 PREFIX 标记,甚至是附加到它的任何字符,因此您的完整行会被 SEARCH 匹配。

为了防止这种情况:保持词法分析器规则分离,或者至少标记不应相互包含。

parse : prefix? search;

search: (WORD | NUMBER)+;

prefix: NUMBER ':';

NUMBER : [0-9]+;
WORD : (~[0-9:])+;
Run Code Online (Sandbox Code Playgroud)