鉴于这个语法:
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行中,由于“COLON”词法分析器规则,跳过第二个冒号。但我需要这个冒号,因为它是语言的一部分(假设它也应该是MULT_OP关键字的一部分)。怎么做到这一点?
删除COLON : ':' -> skip;
并插入:
statement : NUM_LITERAL ':' expression (':' expression)* SEMICOLON;
树看起来像这样:
所需的树应如下所示:
这个怎么样?一些隐式令牌被定义 - 但现在它可以工作。
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;
我可以用其他方式改进代码吗?
答案 0 :(得分:0)
:
等标记可能不会被跳过。然后,将您的statement
规则更改为:
statement : NUM_LITERAL expression (':' expression)* SEMICOLON;
答案 1 :(得分:0)
您需要做出决定:要么保留冒号,要么跳过它。你不能同时拥有两个相反的行动。但问题是为什么你想首先跳过冒号?即使您在初始数字之后不需要它,也不会在解析树中使用它。当你以后走完你的解析树时,你总是可以忽略那个令牌。