ANTLR4 捕获整行任意数据

ANTLR4 catch an entire line of arbitrary data

我有一个语法,命令行以 / 开头,“数据行”是不以斜杠开头的所有内容。

我只是无法正确解析它,以下规则

FM_DATA: ( ('\r' | '\n' | '\r\n') ~'/') -> mode(DATA_MODE);

除了一条数据线

几乎可以满足我的需要

abcde

生成了以下令牌

[@23,170:171='\na',<4>,4:72]
[@24,172:175='bcde',<103>,5:1]

所以第一个字符被规则吞没了。

我也试过了

FM_DATA: ( {getCharPositionInLine() == 0}? ~'/') -> mode(DATA_MODE);

但这会导致更奇怪的事情。

使它按预期工作的正确规则是什么?

TIA - 亚历克斯

... -> more 命令可用于让第一个字符(或词法分析器规则的第一部分)不被消耗(还)。

快速演示:

lexer grammar FmDataLexer;

NewLine
 : [\r\n]+ -> skip
 ;

CommandStart
 : '/' -> pushMode(CommandMode)
 ;

FmDataStart
 : . -> more, pushMode(FmDataMode)
 ;

mode CommandMode;

 CommandLine
  : ~[\r\n]+ -> popMode
  ;

mode FmDataMode;

 FmData
  : ~[\r\n]+ -> popMode
  ;

如果您运行以下代码:

FmDataLexer lexer = new FmDataLexer(CharStreams.fromString("abcde\n/mu"));
CommonTokenStream stream = new CommonTokenStream(lexer);
stream.fill();

for (Token t : stream.getTokens()) {
  System.out.printf("%-20s '%s'\n", FmDataLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
}

你会得到这个输出:

FmData               'abcde'
CommandStart         '/'
CommandLine          'mu'
EOF                  '<EOF>'

参见:https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md#mode-pushmode-popmode-and-more