Improved handling of invalid strings and array entries

This commit is contained in:
moandji.ezana 2014-08-12 15:59:53 +02:00
parent 155781b5e2
commit adbfeae05e
9 changed files with 40 additions and 41 deletions

View file

@ -4,27 +4,13 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.parboiled.BaseParser; import org.parboiled.BaseParser;
import org.parboiled.Parboiled;
import org.parboiled.Rule; import org.parboiled.Rule;
import org.parboiled.annotations.BuildParseTree; import org.parboiled.annotations.BuildParseTree;
import org.parboiled.annotations.SuppressNode; import org.parboiled.annotations.SuppressNode;
import org.parboiled.parserunners.RecoveringParseRunner;
import org.parboiled.support.ParseTreeUtils;
import org.parboiled.support.ParsingResult;
@BuildParseTree @BuildParseTree
public class ParboiledParser extends BaseParser<List<Object>> { public class ParboiledParser extends BaseParser<List<Object>> {
public static void main(String[] args) {
ParboiledParser parser = Parboiled.createParser(ParboiledParser.class);
ParsingResult<List<Object>> parsingResult = new RecoveringParseRunner<List<Object>>(parser.Array()).run("[ [], []]");
System.out.println(ParseTreeUtils.printNodeTree(parsingResult));
System.out.println(parsingResult.resultValue);
}
public Rule Array() { public Rule Array() {
return FirstOf(EmptyArray(), Sequence('[', startList(), OneOrMore(FirstOf(NonEmptyArray(), ' ', ',')), ']', endList())); return FirstOf(EmptyArray(), Sequence('[', startList(), OneOrMore(FirstOf(NonEmptyArray(), ' ', ',')), ']', endList()));
} }

View file

@ -21,10 +21,6 @@ import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.parboiled.Parboiled;
import org.parboiled.parserunners.RecoveringParseRunner;
import org.parboiled.support.ParsingResult;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -130,12 +126,6 @@ public class Toml {
* @throws IllegalStateException If tomlString is not valid TOML * @throws IllegalStateException If tomlString is not valid TOML
*/ */
public Toml parse(String tomlString) throws IllegalStateException { public Toml parse(String tomlString) throws IllegalStateException {
TomlParser parser = Parboiled.createParser(TomlParser.class);
ParsingResult<Object> result = new RecoveringParseRunner<Object>(parser.Toml()).run(tomlString);
// ParsingResult<Object> parsingResult = new ReportingParseRunner<Object>(parser.Toml()).run(tomlString);
// System.out.println(ParseTreeUtils.printNodeTree(parsingResult));
// TomlParser.Results results = (TomlParser.Results) result.valueStack.peek(result.valueStack.size() - 1);
Results results = new RegexParser().run(tomlString); Results results = new RegexParser().run(tomlString);
if (results.errors.length() > 0) { if (results.errors.length() > 0) {
throw new IllegalStateException(results.errors.toString()); throw new IllegalStateException(results.errors.toString());

View file

@ -142,7 +142,6 @@ class ValueAnalysis {
private Object convertString(String value) { private Object convertString(String value) {
int stringTerminator = -1; int stringTerminator = -1;
int startOfComment = -1;
char[] chars = value.toCharArray(); char[] chars = value.toCharArray();
for (int i = 1; i < chars.length; i++) { for (int i = 1; i < chars.length; i++) {
@ -153,10 +152,10 @@ class ValueAnalysis {
} }
} }
if (stringTerminator == -1) { if (stringTerminator == -1 || !isComment(value.substring(stringTerminator + 1))) {
return INVALID; return INVALID;
} }
value = value.substring(1, stringTerminator); value = value.substring(1, stringTerminator);
value = replaceUnicodeCharacters(value); value = replaceUnicodeCharacters(value);
@ -183,12 +182,16 @@ class ValueAnalysis {
for (Object token : tokens) { for (Object token : tokens) {
if (token instanceof String) { if (token instanceof String) {
Object converted = convert(((String) token).trim()); Object converted = convert(((String) token).trim());
if (converted == INVALID) {
return INVALID_ARRAY;
}
if (isHomogenousArray(converted, nestedList)) { if (isHomogenousArray(converted, nestedList)) {
nestedList.add(converted); nestedList.add(converted);
} else { } else {
return INVALID_ARRAY; return INVALID_ARRAY;
} }
} else if (token instanceof List) { } else if (token instanceof List) {
@SuppressWarnings("unchecked")
List<Object> convertedList = convertList((List<Object>) token); List<Object> convertedList = convertList((List<Object>) token);
if (convertedList != INVALID_ARRAY && isHomogenousArray(convertedList, nestedList)) { if (convertedList != INVALID_ARRAY && isHomogenousArray(convertedList, nestedList)) {
nestedList.add(convertedList); nestedList.add(convertedList);

View file

@ -160,6 +160,26 @@ public class BurntSushiTest {
runInvalidTest("float-no-trailing-digits"); runInvalidTest("float-no-trailing-digits");
} }
@Test
public void text_after_array_entries() throws Exception {
runInvalidTest("text-after-array-entries");
}
@Test
public void text_after_string() throws Exception {
runInvalidTest("text-after-string");
}
@Test
public void text_before_array_separator() throws Exception {
runInvalidTest("text-before-array-separator");
}
@Test
public void text_in_array() throws Exception {
runInvalidTest("text-in-array");
}
@After @After
public void after() throws IOException { public void after() throws IOException {
inputToml.close(); inputToml.close();

View file

@ -8,7 +8,6 @@ import static org.junit.Assert.assertTrue;
import java.io.File; import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import org.junit.Test; import org.junit.Test;
@ -76,17 +75,4 @@ public class RealWorldTest {
assertTrue(toml.getTable("siteInfo.local.sh").getBoolean("enable")); assertTrue(toml.getTable("siteInfo.local.sh").getBoolean("enable"));
assertFalse(toml.getTable("siteInfo.localMobile.sh").getBoolean("enable")); assertFalse(toml.getTable("siteInfo.localMobile.sh").getBoolean("enable"));
} }
@SuppressWarnings("unchecked")
private void printMap(Map<String, Object> map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() instanceof Map) {
System.out.println("[" + entry.getKey() + "]");
printMap((Map<String, Object>) entry.getValue());
System.out.println("[/" + entry.getKey() + "]");
} else {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
} }

View file

@ -0,0 +1,4 @@
array = [
"Is there life after an array separator?", No
"Entry"
]

View file

@ -0,0 +1 @@
string = "Is there life after strings?" No.

View file

@ -0,0 +1,4 @@
array = [
"Is there life before an array separator?" No,
"Entry"
]

View file

@ -0,0 +1,5 @@
array = [
"Entry 1",
I don't belong,
"Entry 2",
]