我想解析像这样的数据文件(虚构示例):
Name: bob
Age: 14
-----
Name: alice
-----
我们假设,对于这个例子,文件的格式足够复杂,我不想直接编码。我更喜欢使用ANTLR来获得更好的解析器。
这是一个问题:如何使用ANTLR将这些数据映射到结构,如列表?我不需要完整的语法,只需要解释如何将数据映射到数据结构。
答案 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}]