Parses hard_example.toml

This commit is contained in:
moandji.ezana 2013-02-28 09:33:16 +02:00
parent 3dda0b7701
commit c539be53b9
5 changed files with 92 additions and 4 deletions

View file

@ -20,7 +20,7 @@ class TomlParser extends BaseParser<Object> {
}
public Rule Toml() {
return Sequence(push(new TomlParser.Results()), push(((TomlParser.Results) peek()).values), OneOrMore(FirstOf(KeyGroup(), Comment(), Key())));
return Sequence(push(new TomlParser.Results()), push(((TomlParser.Results) peek()).values), OneOrMore(FirstOf(KeyGroup(), '\n', Comment(), Key())));
}
Rule KeyGroup() {
@ -32,11 +32,11 @@ class TomlParser extends BaseParser<Object> {
}
Rule KeyGroupName() {
return Sequence(OneOrMore(FirstOf(Letter(), Digit(), '.', '_')), push(match()));
return Sequence(OneOrMore(TestNot(KeyGroupDelimiter()), FirstOf(Letter(), Digit(), ANY)), push(match()));
}
Rule KeyName() {
return Sequence(OneOrMore(FirstOf(Letter(), Digit(), '_', '.')), push(match()));
return Sequence(OneOrMore(TestNot(EqualsSign()), ANY), push(match()));
}
Rule VariableValues() {
@ -60,7 +60,7 @@ class TomlParser extends BaseParser<Object> {
}
Rule StringValue() {
return Sequence('"', OneOrMore(TestNot('"'), ANY), pushString(match()), '"');
return Sequence(push(new StringBuilder()), '"', OneOrMore(TestNot('"'), FirstOf(SpecialCharacter(), AnyCharacter())), pushString(((StringBuilder) pop()).toString()), '"');
}
Rule Year() {
@ -83,6 +83,14 @@ class TomlParser extends BaseParser<Object> {
return CharRange('a', 'z');
}
Rule SpecialCharacter() {
return Sequence(Sequence('\\', FirstOf('n', '"')), pushCharacter(match()));
}
Rule AnyCharacter() {
return Sequence(ANY, pushCharacter(match()));
}
@SuppressNode
Rule KeyGroupDelimiter() {
return AnyOf("[]");
@ -193,6 +201,18 @@ class TomlParser extends BaseParser<Object> {
return true;
}
boolean pushCharacter(String sc) {
StringBuilder sb = (StringBuilder) peek();
if (sc.equals("\\n")) {
sb.append('\n');
} else if (sc.equals("\\\"")) {
sb.append('\"');
} else {
sb.append(sc);
}
return true;
}
@SuppressWarnings("unchecked")
void putValue(String name, Object value) {
Map<String, Object> values = (Map<String, Object>) peek();

View file

@ -62,6 +62,20 @@ public class RealWorldTest {
assertEquals(asList("alpha", "omega"), clients.get("hosts"));
}
@Test
public void should_parse_hard_example() throws Exception {
Toml toml = new Toml().parse(new File(getClass().getResource("hard_example.toml").getFile()));
assertEquals("You'll hate me after this - #", toml.getString("the.test_string"));
assertEquals(asList("] ", " # "), toml.getList("the.hard.test_array", String.class));
assertEquals(asList("Test #11 ]proved that", "Experiment #9 was a success"), toml.getList("the.hard.test_array2", String.class));
assertEquals(" Same thing, but with a string #", toml.getString("the.hard.another_test_string"));
assertEquals(" And when \"'s are in the string, along with # \"", toml.getString("the.hard.harder_test_string"));
Toml theHardBit = toml.getKeyGroup("the.hard.bit#");
assertEquals("You don't think some user won't do that?", theHardBit.getString("what?"));
assertEquals(asList("]"), theHardBit.getList("multi_line_array", String.class));
}
@SuppressWarnings("unchecked")
private void printMap(Map<String, Object> map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {

View file

@ -141,6 +141,13 @@ public class TomlTest {
assertEquals(1, toml.getLong("a_a").intValue());
}
@Test
public void should_support_question_marks_in_key_names() throws Exception {
Toml toml = new Toml().parse("key?=true");
assertTrue(toml.getBoolean("key?"));
}
@Test
public void should_support_underscores_in_key_group_names() throws Exception {
Toml toml = new Toml().parse("[group_a]\na = 1");
@ -148,6 +155,27 @@ public class TomlTest {
assertEquals(1, toml.getLong("group_a.a").intValue());
}
@Test
public void should_support_sharp_sign_in_key_group_names() throws Exception {
Toml toml = new Toml().parse("[group#]\nkey=1");
assertEquals(1, toml.getLong("group#.key").intValue());
}
@Test
public void should_support_blank_lines() throws Exception {
Toml toml = new Toml().parse(new File(getClass().getResource("should_support_blank_line.toml").getFile()));
assertEquals(1, toml.getLong("group.key").intValue());
}
@Test
public void should_support_double_quote_in_string() {
Toml toml = new Toml().parse("key=\"double \\\" quote\"");
assertEquals("double \" quote", toml.getString("key"));
}
@Test(expected = IllegalStateException.class)
public void should_fail_when_dot_in_key_name() throws Exception {
new Toml().parse("a.a = 1");

View file

@ -0,0 +1,21 @@
# Test file for TOML
# Only this one tries to emulate a TOML file written by a user of the kind of parser writers probably hate
# This part you'll really hate
[the]
test_string = "You'll hate me after this - #" # " Annoying, isn't it?
[the.hard]
test_array = [ "] ", " # "] # ] There you go, parse this!
test_array2 = [ "Test #11 ]proved that", "Experiment #9 was a success" ]
# You didn't think it'd as easy as chucking out the last #, did you?
another_test_string = " Same thing, but with a string #"
harder_test_string = " And when \"'s are in the string, along with # \"" # "and comments are there too"
# Things will get harder
[the.hard.bit#]
what? = "You don't think some user won't do that?"
multi_line_array = [
"]",
# ] Oh yes I did
]

View file

@ -0,0 +1,5 @@
# Comment
[group]
key = 1