如何在 ANTLR4 中创建带有可选部分的词法规则

How to create lexical rules with optional part in ANTLR4

我正在尝试创建一个语法来使用 ANTLR4 定义布尔文字。它可以采用 "BOOL#TRUE" 或 "TRUE" 的形式。

如果我将它定义为这样的词法规则:

Bool_Literal    : ( 'BOOL' '#' )? ( 'FALSE' | 'TRUE' );    

Antlr 无法匹配输入:

isHigh := FALSE;   

错误是 "mismatched input 'FALSE' expecting Bool_Literal"。

但如果我将其更改为语法规则:

bool_literal    : ( 'BOOL' '#' )? ( 'FALSE' | 'TRUE' );  

它可以正确拾取 "BOOL#FALSE" 或 "FALSE"。

词法规则似乎无法检测到以可选部分开头的标记,有人知道为什么吗?

谢谢!

韦恩

这是我的语法:


grammar TT;

pou
  : assignment +  
  ;

assignment  : Identifier ':=' expression ';' ;  
expression  : primary_expr ;  
primary_expr    : Bool_Literal;   

//bool_literal          : ( 'BOOL' '#' )? ( 'FALSE' | 'TRUE' );

 // lexical   
fragment Letter         : [a-zA-Z]|'_' ;  
fragment Digit          : [0-9];  
fragment Bit            : [0-1];  
fragment Octal_Digit    : [0-7];  
fragment Hex_Digit      : [0-9a-fA-F];  

Identifier          : Letter (Letter|Digit)*;  

Bool_Literal            : ( 'BOOL' '#' )? ( 'FALSE' | 'TRUE' );  

WS      : [ \n\r\t]+ -> channel(HIDDEN) ;  
Comment     :   '//' .*? '\n' -> channel(HIDDEN); // channel COMMENTS)   //     
EOL         : '\n';  

我的测试输入:

isLow := BOOL#TRUE;  
isLow2 := BOOL#FALSE;  
isHigh := FALSE;

Antlr 与大多数词法扫描器生成器一样,优先考虑与标记匹配的第一条规则,以防最长可能的标记可以被两个或更多规则匹配。

在您的语法中,TRUEFALSE 可以作为标识符或布尔文字进行匹配。由于标识符规则在语法中较早出现,因此它将获胜,因此 FALSE 将成为标识符。

所以把 Bool_literal 规则放在 bool_literal 规则出现的地方——或者至少在 identifier 规则之前——然后它就会取而代之。

参见 this Antlr4 FAQ 中的问题 "Why are my keywords being treated as identifiers?"。