带有贪婪 * 量词的 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:c
、some:cn
、some:cna
、some:cnam
直到最后 some:cname
.
有没有办法改变行为来强制 antlr4 在调用谓词之前首先找到可能的最长匹配?或者,谓词是否有一种有效的方法来确定匹配不是最长的匹配,在这种情况下只需 return 和 false
?
编辑:这种行为的有趣之处在于,只要只将部分匹配传递给谓词,谓词的结果似乎就完全被词法分析器忽略了。这似乎效率低下。
事实证明,这种行为是 Antlr 已知并允许的。 Antlr 可能会也可能不会调用不必要的谓词 (see here for more details)。为了避免这种行为,我现在改用动作,只有在规则完全成功匹配后才会执行。这让我可以在一个动作中切换模式。
以下词法分析器语法片段应该根据 class LexerHelper
:
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:c
、some:cn
、some:cna
、some:cnam
直到最后 some:cname
.
有没有办法改变行为来强制 antlr4 在调用谓词之前首先找到可能的最长匹配?或者,谓词是否有一种有效的方法来确定匹配不是最长的匹配,在这种情况下只需 return 和 false
?
编辑:这种行为的有趣之处在于,只要只将部分匹配传递给谓词,谓词的结果似乎就完全被词法分析器忽略了。这似乎效率低下。
事实证明,这种行为是 Antlr 已知并允许的。 Antlr 可能会也可能不会调用不必要的谓词 (see here for more details)。为了避免这种行为,我现在改用动作,只有在规则完全成功匹配后才会执行。这让我可以在一个动作中切换模式。