解析数据文件

时间:2012-01-25 15:40:34

标签: antlr

我想解析像这样的数据文件(虚构示例):

Name: bob
Age: 14
-----
Name: alice
-----

我们假设,对于这个例子,文件的格式足够复杂,我不想直接编码。我更喜欢使用ANTLR来获得更好的解析器。

这是一个问题:如何使用ANTLR将这些数据映射到结构,如列表?我不需要完整的语法,只需要解释如何将数据映射到数据结构。

1 个答案:

答案 0 :(得分:3)

我找不到BA-S在你的问题评论中发布的the answer,所以我开始写一个新答案。如果没有太多解释(请阅读其他答案以获取更多信息),下面是一个如何使用ANTLR将该简单输入解析为List<Person>的示例。

描述你输入的语法:

grammar T;

parse
 : person* EOF
 ;

person
 : Name Word (Age Number)? Separator
 ;

Name
 : 'Name:'
 ;

Age
 : 'Age:'
 ;

Word
 : ('a'..'z')+
 ;

Number
 : ('0'..'9')+
 ;

Separator
 : '-----'
 ;

Space
 : (' ' | '\t' | '\r' | '\n') {skip();}
 ;

相同的语法,但随后包括嵌入式代码:

grammar T;

parse returns [List<Person> persons]
@init{$persons = new ArrayList<Person>();}
 : (person {$persons.add($person.p);})* EOF
 ;

person returns [Person p]
 : Name Word (Age Number)? Separator {$p = new Person($Word.text, $Number.text);}
 ;

Name
 : 'Name:'
 ;

Age
 : 'Age:'
 ;

Word
 : ('a'..'z')+
 ;

Number
 : ('0'..'9')+
 ;

Separator
 : '-----'
 ;

Space
 : (' ' | '\t' | '\r' | '\n') {skip();}
 ;

一个小型测试类(使用class Person):

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;

public class Main {
  public static void main(String[] args) throws Exception {
    TLexer lexer = new TLexer(new ANTLRFileStream("test.txt"));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    java.util.List<Person> persons = parser.parse();
    System.out.println(persons);
  }
}

class Person {

  final String name;
  final int age;

  public Person(String nm, String num) {
    name = nm;
    age = num == null ? -1 : Integer.valueOf(num);
  }

  @Override
  public String toString() {
    return String.format("{name=%s, age=%d}", name, age);
  }
}

test.txt包含:

Name: bob
Age: 14
-----
Name: alice
-----

如果您现在运行Main,将打印以下内容:

[{name=bob, age=14}, {name=alice, age=-1}]