ANTLR v4:相同的字符在不同的上下文中具有不同的含义

时间:2013-08-08 21:39:42

标签: antlr grammar lexer antlr4

这是我在解析器生成器上的第一次破解,因此是ANTLR。我正在使用ANTLR v4尝试使用以下额外规则为摩尔斯电码生成一个简单的练习解析器:

  1. 如果在其前面加上'^',则可以将字母(例如... [字母's'])表示为大写
    • 例如:^...表示首都'S'
  2. 特殊字符可以嵌入括号中
    • 例如:(@)
  3. 每个编码实体将以空格分隔
  4. 所以我可以编码以下句子:

      

    ABC a@b.com

    as(下面显示相应的字母):

    ^.- ^-... ^-.-. ( ) ._ (@) -... (.) -.-. --- --
     A   B     C    ' ' a  '@' b    '.' c    o   m
    

    特别注意以下两个实体:( )(表示空格)和(.)(表示句点。

    我发现主要有一件事我很难理解:同样的标记可以采用不同的含义,取决于它是否在括号中。也就是说,我想告诉ANTLR我想丢弃空格,但不是( )的情况。此外,摩尔斯电码字符可以由点划线(句点和短划线)组成,但是,我不想将(.)中的句号视为“任何字符”。

    这是我到目前为止的语法:

    grammar MorseCode;
    
    file: entity*;
    
    entity:
          special
        | morse_char;
    
    special: '(' SPECIAL ')';
    
    morse_char: '^'? (DOT_OR_DASH)+;
    
    SPECIAL     : .; // match any character
    DOT_OR_DASH : ('.' | '-');
    
    WS          : [ \t\r\n]+ -> skip; // we don't care about whitespace (or do we?)
    

    当我针对以下输入进行尝试时:

    ^... --- ...(@)
    

    我得到以下输出(来自grun ... -tokens):

    [@0,0:0='^',<1>,1:0]
    [@1,1:1='.',<4>,1:1]
    ...
    [@15,15:14='<EOF>',<-1>,1:15]
    line 1:1 mismatched input '.' expecting DOT_OR_DASH
    

    似乎SPECIALDOT_OR_DASH之间存在歧义问题?

1 个答案:

答案 0 :(得分:1)

似乎您的(@)语法在其他编程语言中的行为类似于带引号的字符串。我首先将SPECIAL定义为:

SPECIAL : '(' .*? ')';

为确保. ...实际上不同,您可以使用此功能:

SYMBOL : [.-]+;

然后您可以定义^运算符:

CARET : '^';

使用这三个令牌(并保持WS原样),您可以显着简化解析器规则:

file
  : entity* EOF
  ;

entity
  : morse_char
  | SPECIAL
  ;

morse_char
  : CARET? SYMBOL
  ;