嗨,我是Antrl的新手,并且有一个我无法在最后几天解决的问题:
我想写一个识别本文的语法(实际上我想解析一些不同的东西,但是对于这个问题,我简化了它)
100abc
150100
200def
这里的每行以3位数字开始,可以识别该行的类型(标题,内容,预告片),而不是3个字符,即行的有效载荷。
我以为我可以用这种语法重新审议:
grammar Types;
file : header content trailer;
A : [a-z|A-Z|0-9];
NL: 'n';
header : '100' A A A NL;
content: '150' A A A NL;
trailer: '200' A A A NL;
但这不起作用。当Lexer在第二行中读取" 100"(" 150100")时,它将其读取为一个令牌,用100作为该值,而不是A型的三个令牌。100英寸的令牌期望一个令牌。
我很确定这是因为Lexer想要匹配一个令牌的最长短语,因此它将" 1"," 0",'0'一起匹配。我找不到解决这个问题的方法。将规则置于包含字符串字面" 100"字符串的解析器规则之上。并将" 100"分解为碎片,如下所示。
grammar Types;
file : header content trailer;
A : [a-z|A-Z|0-9];
NL: 'n';
HUNDRED: '100';
header : HUNDRED A A A NL;
content: '150' A A A NL;
trailer: '200' A A A NL;
我还阅读了其他一些帖子:
antl4混合片段
lexer,重叠规则,但需要较短的匹配
,但我不认为它可以解决我的问题,或者至少我看不出如何帮助我。
-
您的令牌定义之一是不正确的:
A : [a-z|A-Z|0-9];
不要在范围[]
设置内使用垂直线。正确的定义是:A : [a-zA-Z0-9];
。ANTLR具有版本> = 4.6的ANTLR将通知重复的字符|
内部范围内。 -
我了解您混合代币和规则概念。用上下字母定义的代币与使用下部案例第一个字母定义的规则不同。您的标题,内容和拖车是令牌,而不是规则。
所以,我认为正确的语法的最终版本是
grammar Types;
file : Header Content Trailer;
A : [a-zA-Z0-9];
NL: 'r' 'n'? | 'n' | EOF; // Or leave only one type of newline.
Header : '100' A A A NL;
Content: '150' A A A NL;
Trailer: '200' A A A NL;
您的输入文本将解析为(file 100abcn 150100n 200def)