toml4j/src/main/java/com/moandjiezana/toml/ValueParser.java
2015-01-23 16:06:06 +02:00

85 lines
2.1 KiB
Java

package com.moandjiezana.toml;
import java.util.ArrayList;
import java.util.List;
import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.annotations.BuildParseTree;
@BuildParseTree
class ValueParser extends BaseParser<List<Object>> {
public Rule Array() {
return FirstOf(EmptyArray(), Sequence('[', startList(), OneOrMore(FirstOf(NonEmptyArray(), ' ', ',')), ']', endList()));
}
public Rule LiteralString() {
return FirstOf(EmptyLiteralString(), Sequence('\'', OneOrMore(TestNot("'"), ANY), startList(), pushToken(match()) , '\'', endList(), Comment()));
}
public Rule MultilineLiteralString() {
return FirstOf(EmptyMultilineLiteralString(), Sequence("'''", startList(), Sequence(OneOrMore(TestNot("'''"), ANY), pushToken(match())), "'''", endList(), Comment()));
}
Rule NonEmptyArray() {
return FirstOf(Array(), OneOrMore(TestNot(']'), FirstOf(StringToken(), Array(), ',', ' ', OtherValue())));
}
Rule StringToken() {
return Sequence(Sequence('"', ZeroOrMore(Sequence(TestNot('"'), ANY)), '"'), pushToken(match()));
}
Rule EmptyLiteralString() {
return Sequence('\'', '\'', startList(), pushToken(""), endList());
}
Rule EmptyMultilineLiteralString() {
return Sequence("'''", "'''", startList(), pushToken(""), endList(), Comment());
}
Rule EmptyArray() {
return Sequence('[', ']', startList(), endList());
}
Rule SignedNumber() {
return Sequence(Optional(AnyOf("+-")), Number());
}
Rule Number() {
return OneOrMore(CharRange('0', '9'));
}
Rule OtherValue() {
return Sequence(ZeroOrMore(NoneOf("],")), pushToken(match()));
}
Rule Comment() {
return FirstOf(EOI, OneOrMore(' ', Sequence('#', ZeroOrMore(ANY))));
}
boolean startList() {
ArrayList<Object> newTokens = new ArrayList<Object>();
if (!getContext().getValueStack().isEmpty()) {
peek().add(newTokens);
}
push(newTokens);
return true;
}
boolean endList() {
if (getContext().getValueStack().size() > 1) {
pop();
}
return true;
}
boolean pushToken(String s) {
peek().add(s);
return true;
}
}