ANTLR - 解析器规则中的字符串文字会覆盖其他规则

时间:2014-02-03 21:25:30

标签: antlr antlr4

我已经定义了一些hex_byte规则,它应该匹配两个十六进制([a-fA-F0-9])字符。我在我的语法的几个规则中使用它。

hungry.g

grammar hungry;

expr: message NEWLINE;

message
    :   hex_byte specificMessage
    ;

hex_byte 
    :   a=HEX_BYTE 
    ;

specificMessage
    :   '05' lunchRequest
    |   '06' dinnerRequest
    |   '07' brunchRequest
    ;

lunchRequest  : hex_byte*;
dinnerRequest : hex_byte*;
brunchRequest : hex_byte*;



HEX_DIGIT 
    :   '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'a'|'b'|'c'|'d'|'e'|'f'|'A'|'B'|'C'|'D'|'E'|'F'
    ;

HEX_BYTE
    :   HEX_DIGIT HEX_DIGIT
    ;

NEWLINE : [\r\n]+;

包含在任何其他解析器规则(例如FF,78,12等)中未用作字符串文字的hex_byte序列的输入正常工作。但是,当我引入包含在hexMessage规则(05,06,07)中用作字符串文字的十六进制字节的输入时,解析失败。为什么会发生这种失败?

以下是解析expr规则输入的几个示例:

780612产生

successful_parse

0506BB抱怨:

  

第1行:0错过了'05'的HEX_BYTE

     

第1行:2个无关输入'06'期待{HEX_BYTE,NEWLINE}

并制作

enter image description here

1 个答案:

答案 0 :(得分:0)

在ANTLR中,单个令牌只有一种令牌类型。通过在解析器规则中使用字符串文字,您已隐式定义了令牌类型(在这种情况下为匿名令牌,因为没有词法分析器规则与特定文字匹配)。

您可以使用语义谓词而不是引入新的令牌类型来纠正这种情况:

specificMessage
  : {"05".equals(_input.LT(1).getText())}? HEX_BYTE lunchRequest
  | {"06".equals(_input.LT(1).getText())}? HEX_BYTE dinnerRequest
  | {"07".equals(_input.LT(1).getText())}? HEX_BYTE brunchRequest
  ;