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



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

  1. 一个字母(例如,...[字母的'])如果前面有'^',则可以表示为大写
    • 例如:^...表示大写"S"
  2. 特殊字符可以嵌入括号中
    • 例如:(@)
  3. 每个编码的实体将用空格分隔

所以我可以编码以下句子:

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          : [ trn]+ -> 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之间的歧义似乎有问题?

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

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

为了确保. ...实际上不同,您可以使用以下方法:

SYMBOL : [.-]+;

然后您可以定义您的^操作员:

CARET : '^';

有了这三个标记(并保持WS不变),您可以显著简化解析器规则:

file
  : entity* EOF
  ;
entity
  : morse_char
  | SPECIAL
  ;
morse_char
  : CARET? SYMBOL
  ;

相关内容

  • 没有找到相关文章

最新更新