1

对于我尝试解析的标记语言,我决定尝试使用 ANTLR 生成解析器。我是这个领域的新手,我正在搞砸一些事情。

我的语法是

grammar Test;
DIGIT   :   ('0'..'9');
LETTER  :   ('A'..'Z');
SLASH   :   '/'; 
restriction
    :   ('E' ap)
    |   ('L' ap)
    |   'N';
ap  :   LETTER LETTER LETTER;
car :   LETTER LETTER;
fnum    :   DIGIT DIGIT DIGIT DIGIT? LETTER?;
flt :   car fnum?;
message :   'A' (SLASH flt)? (SLASH restriction)?;

当我给它一个 input string 时,这正是我想要的A/KK543/EPOS。但是,当我给它A/KL543/EPOS时,它失败了(MismatchedTokenException(9!=5))。这似乎是某种冲突;它想restriction在第一个 L 上生成,所以似乎我在语言定义中做错了什么,但我无法正确找出是什么。

4

1 回答 1

3

对于 input "A/KK543/EPOS",创建以下标记:

'一个' '一个'
斜线'/'
字母“K”
字母“K”
数字'5'
数字'4'
数字'3'
斜线'/'
'E' 'E'
字母“P”
字母“O”
字母“S”

但是对于 input "A/KL543/EPOS",这些是创建的:

'一个' '一个'
斜线'/'
字母“K”
'二'
数字'5'
数字'4'
数字'3'
斜线'/'
'E' 'E'
字母“P”
字母“O”
字母“S”

如您所见,char'L'没有标记为LETTER. 对于文字标记'A','E'和在您的解析器规则中'L''N'ANTLR(自动)创建单独的词法分析器规则,这些规则放置在所有其他词法分析器规则之前。这会导致您的词法分析器在幕后看起来像这样:

A      : 'A';
E      : 'E';
L      : 'L';
N      : 'N';
DIGIT  : '0'..'9';
LETTER : 'A'..'Z';
SLASH  : '/'; 

因此,任何一个'A', 'E','L''N'都不会成为一个LETTER令牌。这就是 ANTLR 的工作原理。如果要将它们作为字母进行匹配,则需要创建一个解析器规则letter并让它匹配这些标记。像这样的东西:

message
 : A (SLASH flt)? (SLASH restriction)?
 ;

flt
 : car fnum?
 ;

fnum
 : DIGIT DIGIT DIGIT DIGIT? letter?
 ;

restriction
 : E ap
 | L ap
 | N
 ;

ap
 : letter letter letter
 ;

car
 : letter letter
 ;

letter
 : A
 | E
 | L
 | N
 | LETTER
 ;

A      : 'A';
E      : 'E';
L      : 'L';
N      : 'N';
DIGIT  : '0'..'9';
LETTER : 'A'..'Z';
SLASH  : '/'; 

它将"A/KL543/EPOS"像这样解析输入:

在此处输入图像描述

于 2012-11-29T19:43:09.773 回答