0

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

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

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

ABC a@b.com

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

^.- ^-... ^-.-. ( ) ._ (@) -... (.) -.-. --- --
 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

SPECIAL和之间的歧义似乎有问题DOT_OR_DASH

4

1 回答 1

1

看起来您的(@)语法在其他编程语言中表现得像带引号的字符串。我将首先定义SPECIAL为:

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

为了确保. ...实际上不同,你可以使用这个:

SYMBOL : [.-]+;

然后你可以定义你的^运营商:

CARET : '^';

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

file
  : entity* EOF
  ;

entity
  : morse_char
  | SPECIAL
  ;

morse_char
  : CARET? SYMBOL
  ;
于 2013-08-08T22:28:51.440 回答