带有贪婪 * 量词的 ANTLR4 谓词:避免不必要的谓词调用(词法分析)

ANTLR4 predicates with greedy * quantifier: avoid unnecessary predicate calls (lexing)

以下词法分析器语法片段应该根据 class LexerHelper:

中定义的谓词来标记 'custom names'
fragment NUMERICAL      : [0-9];

fragment XML_NameStartChar
                        : [:a-zA-Z]
                        | '\u2070'..'\u218F'
                        | '\u2C00'..'\u2FEF'
                        | '\u3001'..'\uD7FF'
                        | '\uF900'..'\uFDCF'
                        | '\uFDF0'..'\uFFFD'
                        ;

fragment XML_NameChar   : XML_NameStartChar
                        | '-' | '_' | '.' | NUMERICAL
                        | '\u00B7'
                        | '\u0300'..'\u036F'
                        | '\u203F'..'\u2040'
                        ;

fragment XML_NAME_FRAG  : XML_NameStartChar XML_NameChar*;

CUSTOM_NAME             : XML_NAME_FRAG ':' XML_NAME_FRAG {LexerHelper.myPredicate(getText())}?;

CUSTOM_NAME 的正确匹配始终是可能的最长匹配。现在,如果词法分析器遇到自定义名称,例如 some:cname,那么我希望它对整个字符串 some:cname 进行词法分析,然后使用 'some:cname' 作为参数调用谓词一次。

取而代之的是,词法分析器会调用谓词并调用它一路上找到的每个可能的 'valid' 匹配项,因此 some:csome:cnsome:cnasome:cnam 直到最后 some:cname.

有没有办法改变行为来强制 antlr4 在调用谓词之前首先找到可能的最长匹配?或者,谓词是否有一种有效的方法来确定匹配不是最长的匹配,在这种情况下只需 return 和 false

编辑:这种行为的有趣之处在于,只要只将部分匹配传递给谓词,谓词的结果似乎就完全被词法分析器忽略了。这似乎效率低下。

事实证明,这种行为是 Antlr 已知并允许的。 Antlr 可能会也可能不会调用不必要的谓词 (see here for more details)。为了避免这种行为,我现在改用动作,只有在规则完全成功匹配后才会执行。这让我可以在一个动作中切换模式。