Antlr 标记分析器失败

Antlr 标记分析器失败,antlr,antlr3,parser-generator,Antlr,Antlr3,Parser Generator,对于我试图解析的标记语言,我决定尝试使用ANTLR生成解析器。我是新手,我把事情搞砸了 我的语法是 grammar Test; DIGIT : ('0'..'9'); LETTER : ('A'..'Z'); SLASH : '/'; restriction : ('E' ap) | ('L' ap) | 'N'; ap : LETTER LETTER LETTER; car : LETTER LETTER; fnum

对于我试图解析的标记语言,我决定尝试使用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)?;
当我给它一个输入字符串
A/KK543/EPOS
时,它正是我想要的。但是,当我给它一个
A/KL543/EPOS
时,它失败了(
MismatchedTokenException(9!=5)
)。这似乎是某种冲突;它想在第一个L上生成
限制
,因此似乎我在语言定义中做错了什么,但我无法正确地找出原因。

对于输入
“A/KK543/EPOS”
,创建了以下标记:

'A' 'A' SLASH '/' LETTER 'K' LETTER 'K' DIGIT '5' DIGIT '4' DIGIT '3' SLASH '/' 'E' 'E' LETTER 'P' LETTER 'O' LETTER 'S' 'A' 'A' SLASH '/' LETTER 'K' 'L' 'L' DIGIT '5' DIGIT '4' DIGIT '3' SLASH '/' 'E' 'E' LETTER 'P' LETTER 'O' LETTER 'S' 如您所见,字符
'L'
没有被标记为
字母。对于解析器规则中的文本标记
'A'
'E'
'L'
'N'
,ANTLR(自动)创建独立的词法规则,这些规则位于所有其他词法规则之前。这会使您的lexer在幕后看起来像这样:

A      : 'A';
E      : 'E';
L      : 'L';
N      : 'N';
DIGIT  : '0'..'9';
LETTER : 'A'..'Z';
SLASH  : '/'; 
因此,任何一个
'A'
'E'
'L'
'N'
将永远不会成为
字母
标记。这就是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”
,如下所示:

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  : '/';