您好我是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;
但这不起作用。当词法分析器在第二行(“150100”)中读取“100”时,它将其读入一个标记,其中100为值,而不是A类型的三个标记。因此解析器看到“ 100“令牌,它需要一个A令牌。
我很确定这是因为Lexer想要匹配一个令牌的最长短语,所以它将'1','0','0'聚集在一起。我发现没办法解决这个问题。将规则A放在解析器上面包含字符串文字“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;
我还阅读了其他一些帖子:
antlr4 mixed fragments in tokens
Lexer, overlapping rule, but want the shorter match
但我没想到,它解决了我的问题,或者至少我看不出这对我有什么帮助。
答案 0 :(得分:0)
您的某个令牌定义不正确:A : [a-z|A-Z|0-9];
请勿在{{1}}范围内使用垂直线。正确的定义是:[]
。版本> = 4.6的ANTLR将通知范围集内的重复字符A : [a-zA-Z0-9];
。
据我所知,你混合了令牌和规则的概念。使用UPPER首字母定义的标记与使用小写首字母定义的规则不同。你的标题,内容和预告片都是令牌,而不是规则。
所以,我认为正确语法的最终版本是
|
您的输入文本将被解析为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;