Reputation: 475
I want to parse a data file like this one (fictive example):
Name: bob
Age: 14
-----
Name: alice
-----
Let's suppose, for this example, that the format of the file is complex enough that I don't want to code it directly. I prefer using ANTLR to get a better parser.
Here is the question: how, with ANTLR, can I map this data to a structure, like a list ? I don't need the complete grammar but only an explanation of how I can map data like that to a data struture.
Upvotes: 2
Views: 1230
Reputation: 170308
I couldn't find the answer that BA-S posted in a comment under your question, so I started writing a new answer. Without much explanation (read the other answer for more info), here is an example of how you could parse that simple input using ANTLR into a List<Person>
.
The grammar describing your input:
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();}
;
The same grammar but then including embedded code:
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();}
;
And a small test class (with the 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);
}
}
where test.txt
contains:
Name: bob
Age: 14
-----
Name: alice
-----
If you now run Main
, the following will be printed:
[{name=bob, age=14}, {name=alice, age=-1}]
Upvotes: 4