Antlr4 Lexer,重叠规则,但需要较短的匹配
我想读取一个输入流,并将输入分为两种类型:模式和单词权重,定义如下 问题产生于这样一个事实,即为单词_WEIGHT定义的所有字符对模式也是有效的。当我们有多个单词权重,且两个单词之间没有空格时,lexer将匹配模式,而不是提供多个单词权重 我需要能够处理以下情况并获得指示结果:Antlr4 Lexer,重叠规则,但需要较短的匹配,antlr4,Antlr4,我想读取一个输入流,并将输入分为两种类型:模式和单词权重,定义如下 问题产生于这样一个事实,即为单词_WEIGHT定义的所有字符对模式也是有效的。当我们有多个单词权重,且两个单词之间没有空格时,lexer将匹配模式,而不是提供多个单词权重 我需要能够处理以下情况并获得指示结果: [20] =>字的重量 cat=>模式 [狗]=>图案 这个案子,这就是问题所在。它符合模式,因为 lexer将选择两种可能性中较长的一种。注: 他们之间没有空隙 [20] [30]=>单词权重单词权重 还需要处
- [20] =>字的重量
- cat=>模式
- [狗]=>图案
- [20] [30]=>单词权重单词权重
- [[[cat]=>模式
grammar Brackets;
fragment
DIGIT
: ('0'..'9')
;
fragment
WORD_WEIGHT_VALUE
: ('-' | '+')? DIGIT+ ('.' DIGIT+)?
| ('-' | '+')? '.' DIGIT+
;
WORD_WEIGHT
: '[' WORD_WEIGHT_VALUE ']'
;
PATTERN
: ~(' ' | '\t' | '\r' | '\n' )+
;
WS
: (' ' | '\t' | '\r' | '\n' )+ -> Skip
;
start : (PATTERN | WORD_WEIGHT)* EOF;
问题是,什么样的Lexer规则会给出期望的结果
我希望有一个功能,一个特殊的指令,可以为影响匹配过程的lexer规则指定。它将在规则匹配时指示lexer停止匹配过程并使用此匹配令牌
跟进-我们选择的解决方案:
将上面的单词_WEIGHT替换为:
fragment
WORD_WEIGHT
: '[' WORD_WEIGHT_VALUE ']'
;
WORD_WEIGHTS
: WORD_WEIGHT (INNER_WS? WORD_WEIGHT)*
;
fragment
INNER_WS
: (' ' | '\t' )+
;
此外,语法规则变为:
start : (PATTERN | WORD_WEIGHTS)* EOF;
现在,任何单词权重序列(空格分隔或不分隔)都将是单词权重标记的值。这也恰好符合我们的用法-我们的语法(不在上面的片段中)总是将单词权重定义为“一个或多个”。现在,多重性被“捕获”如果/当我们需要单独处理每个单词权重时,我们可以在应用程序(解析树侦听器)中拆分值。您可以实现
单词权重
,如下所示:
WORD_WEIGHT
: '[' WORD_WEIGHT_VALUE ']'
PATTERN?
;
然后,在您的lexer中,您可以覆盖emit
方法来更正lexer的位置,以删除添加到单词权重
标记末尾的模式(如果有)。您可以在AntlWorks 2中看到这方面的示例:
- StringTemplate 4中的标记为
- StringTemplate 4中的标记为
修改需要以下步骤
重写lexeransimulator
以添加方法
在lexer类的构造函数中,将\u interp
字段设置为自定义LexeranSimulator
的实例
计算您的令牌所需的结束位置,然后调用resetAcceptPosition
。对于ST4示例中所示的固定宽度令牌,计算只是出现在令牌开头的固定运算符或关键字的长度。对于您的情况,您需要调用getText()
并检查结果以确定单词权重
标记的正确长度。由于单词权重
值
规则无法匹配]
,最简单的分析可能是找到getText()结果中第一个]
字符的索引(WORD\u WEIGHT
的语法确保该字符始终存在)
谢谢!我按照您的建议开始实施,但是出于可维护性的考虑(2年后,当其他人试图理解这一点时)…我们决定支持一个只涉及对lexer规则进行一些更改的解决方案。如果有人感兴趣,我会将更改添加到原始问题中(我想网站会允许我这么做……我是新来的)