Antlr4中的条件词法规则

Antlr4中的条件词法规则,antlr4,Antlr4,鉴于这种语法: grammar ColonTest; main : statement* EOF; statement : NUM_LITERAL expression SEMICOLON; expression : primary (MULT_OP primary)*; primary : WORD+; NUM_LITERAL : [0-9]+; SEMICOLON : ';'; MULT_OP : '*' | '/'; // | ':'; WORD

鉴于这种语法:

grammar ColonTest;

main        : statement* EOF;
statement   : NUM_LITERAL expression SEMICOLON;
expression  : primary (MULT_OP primary)*;
primary     : WORD+;

NUM_LITERAL : [0-9]+;
SEMICOLON   : ';';
MULT_OP     : '*' | '/'; // | ':';
WORD        : ('a'..'z' | 'A'..'Z')+;
WS          : [ \t\r\n]+ -> skip;
COLON       : ':' -> skip;
这个输入:

1 : statement;
2 : splitted statement
  : into two lines;
3 : a * b / c;
4 : a * b : c;
在第4行中,由于“冒号”lexer规则,第二个冒号被跳过。但是我需要这个冒号,因为它是语言的一部分(假设它也应该是MULT_OP关键字的一部分)。如何做到这一点

编辑1: 删除
冒号后:':'->跳过并插入:

statement   : NUM_LITERAL ':' expression (':' expression)* SEMICOLON;
这棵树看起来像这样:

所需的树应如下所示:

编辑2: 这个怎么样?定义了一些隐式标记,但目前它可以工作

grammar MultiLine;

main        : statement* EOF;
statement   : NUM_LITERAL ':' expression SEMICOLON;
expression  : primary ((MULT_OP|':') primary)*;
primary     : WORD+;

NUM_LITERAL : [0-9]+;
SEMICOLON   : ';';
MULT_OP     : '*' | '/';
WORD        : ('a'..'z' | 'A'..'Z')+;
WS2         : [\r\n]+ [ \t]+ ':' -> skip; // removes all not needed colons
WS          : [ \t\r\n]+ -> skip;

我可以用任何其他方法改进代码吗?

这样的标记不应该被跳过。然后,将您的
语句
规则更改为:


语句:NUM_字面表达式(':'表达式)*分号;

你需要一个决定:要么保留冒号,要么跳过冒号。不能同时执行两个相反的操作。但问题是为什么你要跳过冒号呢?在解析树中使用它并没有什么坏处,即使在初始数字之后不需要它。当您以后遍历解析树时,您总是可以忽略该标记。

这不完全符合我的需要-我不想在我有一个表达式时将表达式分成两部分。我已经编辑了我的问题(遗憾的是没有直接显示图像-还没有获得足够的信誉点)。我不能设法创建一个正确的“表达式”规则,因为该行可以在任何时刻中断-在表达式的中间,有时在树的深处。因此,我只想删除不必要的冒号,它将表达式分成许多部分。