【问题标题】:The lexer chooses the wrong Token词法分析器选择了错误的 Token
【发布时间】:2016-12-22 11:49:49
【问题描述】:

您好,我是 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”时,它会将其读入 one 标记,其中 100 作为值而不是三个 A 类型的标记。因此解析器看到“ 100" 令牌,它需要一个 A 令牌。

我很确定这是因为 Lexer 想要匹配一个 Token 的最长短语,因此它将“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

但我不认为它解决了我的问题,或者至少我不知道这对我有什么帮助。

【问题讨论】:

    标签: antlr4


    【解决方案1】:
    1. 您的一个标记定义不正确:A : [a-z|A-Z|0-9]; 不要在[] 集合范围内使用垂直线。正确的定义是:A : [a-zA-Z0-9];。版本 >= 4.6 的 ANTLR 将通知范围集中的重复字符 |

    2. 据我了解,您将令牌和规则概念混合在一起。与使用小写首字母定义的规则不同,使用大写首字母定义的标记。您的标题、内容和预告片是标记,而不是规则。

    所以,我认为正确语法的最终版本是

    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 100abc\n 150100\n 200def)

    【讨论】:

      猜你喜欢
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 2022-12-14
      • 2014-10-01
      • 1970-01-01
      • 2022-10-13
      • 2012-05-17
      • 1970-01-01
      相关资源
      最近更新 更多