用antlr4处理平面文件

用antlr4处理平面文件,antlr4,grammar,Antlr4,Grammar,我需要处理一个平面文本文件,我试图用antlr4生成一个解析器。文件格式如下: 该文件可以包含多条记录 每行是一条记录 每个记录都有多个字段 字段的数量取决于记录类型 每条记录的总长度不是固定的,取决于单个字段的数量 记录类型由前3个字母数字元素定义 每个字段都有一个特定的起始位置(记录中的列)和许多元素 样本文件 ACF0000000101IAR FAT0000000203IARGL9344KDKK FAT0000000301IARGM 示例语法 grammar Cat; file : r

我需要处理一个平面文本文件,我试图用antlr4生成一个解析器。文件格式如下:

  • 该文件可以包含多条记录
  • 每行是一条记录
  • 每个记录都有多个字段
  • 字段的数量取决于记录类型
  • 每条记录的总长度不是固定的,取决于单个字段的数量
  • 记录类型由前3个字母数字元素定义
  • 每个字段都有一个特定的起始位置(记录中的列)和许多元素
  • 样本文件

    ACF0000000101IAR
    FAT0000000203IARGL9344KDKK
    FAT0000000301IARGM
    
    示例语法

    grammar Cat;
    
    file : record+ ;
    
    record: (file_header | cycle_header);
    
    file_header : 'ACF' FIELD1 FIELD2 FIELD3;
    cycle_header : 'FAT' FIELD1 FIELD2;
    
    FIELD1 : DIGIT DIGIT DIGIT DIGIT DIGIT DIGIT DIGIT DIGIT;
    FIELD2 : DIGIT DIGIT;
    FIELD3 : ALPHANUM ALPHANUM ALPHANUM;
    
    fragment DIGIT: [0-9];
    fragment ALPHANUM: [A-Za-z] | DIGIT | ' ';
    fragment NEWLINE: '\n';
    
    这个语法面临的问题是,当我检查树时,文件头规则中的字段2不匹配,而字段3匹配。请记住,cycle_标题的语法不完整

    我的期望是,由于在文件头规则中字段2位于字段3之前,因此这将匹配任何两位数字,其余字符将与字段3匹配,但如图所示,情况并非如此

    因此,我的问题是:

  • Antlr4是否适合解析这样的文件结构,或者更适合使用正则表达式进行某种解析
  • 为什么字段3比字段2匹配,我有什么误解吗
  • Antlr4是否适合解析这样的文件结构,或者更适合使用正则表达式进行某种解析
  • 不,我同意rici的观点。他的评论真的应该是一个答案:


    Antlr4可能不是解决此问题的最佳选择。Antlr词法器并不是真正的上下文,这导致了您看到的问题;lexer匹配给定输入中匹配时间最长的词汇模式。您可以使用无扫描方法,无需词汇规则,但老实说,您最好只使用substring()划分输入行


  • 为什么字段3比字段2匹配,我有什么误解吗
  • 扩展rici的评论:ANTLR的lexer不是“由解析器驱动的”(lexer不会根据解析器试图匹配的内容生成令牌)。lexer始终基于两个简单规则创建令牌:

  • 尽可能多地匹配字符
  • 如果两个或多个lexer规则匹配相同的字符,则让首先定义的规则“win”
  • 由于规则1,对于像
    123
    这样的输入,在
    字段2
    之前创建一个
    字段3

  • Antlr4是否适合解析这样的文件结构,或者更适合使用正则表达式进行某种解析
  • 不,我同意rici的观点。他的评论真的应该是一个答案:


    Antlr4可能不是解决此问题的最佳选择。Antlr词法器并不是真正的上下文,这导致了您看到的问题;lexer匹配给定输入中匹配时间最长的词汇模式。您可以使用无扫描方法,无需词汇规则,但老实说,您最好只使用substring()划分输入行


  • 为什么字段3比字段2匹配,我有什么误解吗
  • 扩展rici的评论:ANTLR的lexer不是“由解析器驱动的”(lexer不会根据解析器试图匹配的内容生成令牌)。lexer始终基于两个简单规则创建令牌:

  • 尽可能多地匹配字符
  • 如果两个或多个lexer规则匹配相同的字符,则让首先定义的规则“win”

  • 由于规则1,对于像
    123
    这样的输入,在
    字段2
    之前创建
    字段3
    ,Antlr4可能不是该问题的最佳选择。Antlr词法器并不是真正的上下文,这导致了您看到的问题;lexer匹配给定输入中匹配时间最长的词汇模式。您可以使用无扫描的方法,不使用词汇规则,但老实说,您最好只使用
    substring()
    将输入行划分。对于这个问题,Antlr4可能不是最佳选择。Antlr词法器并不是真正的上下文,这导致了您看到的问题;lexer匹配给定输入中匹配时间最长的词汇模式。您可以使用无扫描方法,无需词汇规则,但老实说,您最好使用
    substring()
    将输入行划分。看到生成的令牌列表后,我希望会出现这种情况。谢谢你,我将寻找一个替代方案。在看到生成的令牌列表后,我希望情况会是这样。谢谢,我会找一个替代的