ANTLR和关键字/标记

ANTLR和关键字/标记,antlr,token,keyword,Antlr,Token,Keyword,我正试图用ANTLR4编写一个简单的语法,并将其用于我的项目,但我不能完全理解这个问题。假设我有语法: parser grammar GrammarParser; ranks : RANKS COLON entry* ; entry : rank who SEMICOLON ; rank : RANK_HIGH | RANK_LOW ; who : ID ; lexer grammar GrammarLexer; RANKS : 'ranks' ; RANK_HIGH : '

我正试图用ANTLR4编写一个简单的语法,并将其用于我的项目,但我不能完全理解这个问题。假设我有语法:

parser grammar GrammarParser;
ranks : RANKS COLON entry* ;
entry : rank who SEMICOLON ;
rank  : RANK_HIGH | RANK_LOW ;
who   : ID ;

lexer grammar GrammarLexer;
RANKS      : 'ranks' ;
RANK_HIGH  : 'high' ;
RANK_LOW   : 'low' ;
ID         : [a-zA-Z]+ ;
COLON      : ':' ;
SEMICOLON  : ';' ;
WS         : [ \t\r\n]+ -> skip ;
问题在于,对于这些语法,这个简单的例子颠覆了整个想法:

ranks: low ranks; high high; ranks ranks;
首先,lexer将为其返回以下令牌流:

RANKS COLON ID RANKS SEMICOLON ID ID SEMICOLON RANKS RANKS SEMICOLON
这说明了问题所在。排名应该是一个关键字,只适用于起始点-相反,它会覆盖我定义(至少在规则中)排名和ID的位置(第一个和第三个条目)。类似地,由于列组是在其他任何东西之前定义的,lexer在列组\高/列组\低/ID之前进行选择(当它和其中任何一个匹配来自流的相同符号序列时)。类似地,ID超过秩高/秩低

因此,总而言之,我可以在任何地方使用“等级”,但它将始终用作等级,我不能使用“高”/“低”,因为它们将始终被识别为ID。此外,由于优先级原因,ID也不能是“等级”

在这里,模式似乎没有多大帮助,因为语法没有指示列组何时真正结束,因此在到达后无法弹出模式(考虑到它可能只是整个文件中要解析的一小部分)

有什么解决办法吗?

移动

ID         : [a-zA-Z]+ ;

在关键字规则之后:)

是。很明显,要修复识别为ID的秩高/秩低,而这两个不应被识别为ID。但这并不能解决当您将。。。例如,案例中ID应为的“等级”。因为“等级”总是被识别为等级,因此
条目的规则不匹配(等级!=ID)。此外,现在您不能在规则中ID所在的位置使用“高”/“低”,因为再次出现RANK_*!=因此,诸如“high-high”之类的条目将被拒绝。如果您的意思是“将ID的规则移到上面语法的末尾”,则该注释有效。谢谢你的评论。我想我并没有大错特错,但如果是这样,我很想听听不需要将ID移到语法的末尾,只需在关键字之后。我没有看到空白规则,因此语法无法生成您指示的结果。请更正,我将再看一眼。通过添加WS规则编辑语法。没什么特别的。问题是词法分析器不知道标记化输入的上下文。例如,“等级”永远是等级。你可以用模式来控制它,但是模式是通过lexer规则打开和关闭的(推送和弹出),因此如果某些模式有一个开始标记,但没有结束标记(比如这里的RANKS是标记解析空间的开始标记,但是没有明确的结束指示器)。仍然RANK_HIGH:'HIGH';排名低:“低”;永远不会匹配。请把它也修好。