mirror of
https://github.com/plexusorg/toml4j.git
synced 2024-09-28 04:34:50 +00:00
Handle nested arrays
This commit is contained in:
parent
329b56e7d3
commit
39e828ff10
55
src/main/java/com/moandjiezana/toml/ParboiledParser.java
Normal file
55
src/main/java/com/moandjiezana/toml/ParboiledParser.java
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package com.moandjiezana.toml;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.parboiled.BaseParser;
|
||||||
|
import org.parboiled.Rule;
|
||||||
|
|
||||||
|
public class ParboiledParser extends BaseParser<List<Object>> {
|
||||||
|
|
||||||
|
public Rule Array() {
|
||||||
|
return Sequence('[', startList(), ArrayDo(), ']', endList());
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule ArrayDo() {
|
||||||
|
return OneOrMore(TestNot(']'), FirstOf(String(), Array(), ',', ' ', OtherValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule String() {
|
||||||
|
return Sequence(Sequence('"', ZeroOrMore(TestNot('"'), ANY), '"'), pushToken(match()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Rule OtherValue() {
|
||||||
|
return Sequence(ZeroOrMore(NoneOf("],")), pushToken(match()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// private Rule Comment() {
|
||||||
|
// return Sequence('#' , ZeroOrMore(TestNot(EOI), 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,10 +11,6 @@ public class RegexParser {
|
||||||
private static final Pattern MULTILINE_ARRAY_REGEX = Pattern.compile("\\s*\\[([^\\]]*)");
|
private static final Pattern MULTILINE_ARRAY_REGEX = Pattern.compile("\\s*\\[([^\\]]*)");
|
||||||
private static final Pattern MULTILINE_ARRAY_REGEX_END = Pattern.compile("\\s*\\]");
|
private static final Pattern MULTILINE_ARRAY_REGEX_END = Pattern.compile("\\s*\\]");
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
System.out.println(MULTILINE_ARRAY_REGEX.matcher(" [ ]").matches());
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Results results = new Results();
|
private final Results results = new Results();
|
||||||
|
|
||||||
public Results run(String tomlString) {
|
public Results run(String tomlString) {
|
||||||
|
@ -161,5 +157,4 @@ public class RegexParser {
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,19 @@ import java.util.List;
|
||||||
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.ReportingParseRunner;
|
||||||
|
import org.parboiled.support.ParsingResult;
|
||||||
|
|
||||||
class ValueAnalysis {
|
class ValueAnalysis {
|
||||||
static final Object INVALID = new Object();
|
static final Object INVALID = new Object();
|
||||||
|
private static final List<Object> INVALID_ARRAY = new ArrayList<Object>();
|
||||||
|
|
||||||
private static final Pattern STRING_REGEX = Pattern.compile("\"(.*)\"(.*)");
|
|
||||||
private static final Pattern BOOLEAN_REGEX = Pattern.compile("(true|false)(.*)");
|
private static final Pattern BOOLEAN_REGEX = Pattern.compile("(true|false)(.*)");
|
||||||
private static final Pattern FLOAT_REGEX = Pattern.compile("(-?[0-9\\.]*)(.*)");
|
private static final Pattern FLOAT_REGEX = Pattern.compile("(-?[0-9\\.]*)(.*)");
|
||||||
private static final Pattern INTEGER_REGEX = Pattern.compile("(-?[0-9]*)(.*)");
|
private static final Pattern INTEGER_REGEX = Pattern.compile("(-?[0-9]*)(.*)");
|
||||||
private static final Pattern DATE_REGEX = Pattern.compile("(\\d{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]Z)(.*)");
|
private static final Pattern DATE_REGEX = Pattern.compile("(\\d{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]Z)(.*)");
|
||||||
private static final Pattern LIST_REGEX = Pattern.compile("(\\[(.*)\\])(.*)");
|
|
||||||
private static final Pattern UNICODE_REGEX = Pattern.compile("\\\\u(.*)");
|
private static final Pattern UNICODE_REGEX = Pattern.compile("\\\\u(.*)");
|
||||||
private static final Pattern RESERVED_CHARACTER_REGEX = Pattern.compile("\\\\[^bfntr\"/\\\\]");
|
|
||||||
|
|
||||||
private final String rawValue;
|
private final String rawValue;
|
||||||
private Matcher chosenMatcher;
|
private Matcher chosenMatcher;
|
||||||
|
@ -38,17 +40,14 @@ class ValueAnalysis {
|
||||||
return Double.valueOf(chosenMatcher.group(1));
|
return Double.valueOf(chosenMatcher.group(1));
|
||||||
} else if (isBoolean(value)) {
|
} else if (isBoolean(value)) {
|
||||||
return Boolean.valueOf(chosenMatcher.group(1));
|
return Boolean.valueOf(chosenMatcher.group(1));
|
||||||
} else if (isList(value)) {
|
} else if (isArray(value)) {
|
||||||
ArrayList<Object> values = new ArrayList<Object>();
|
ParboiledParser parser = Parboiled.createParser(ParboiledParser.class);
|
||||||
value = chosenMatcher.group(1);
|
ParsingResult<List<Object>> parsingResult = new ReportingParseRunner<List<Object>>(parser.Array()).run(value);
|
||||||
String[] split = value.substring(1, value.length() - 1).split(",");
|
List<Object> tokens = parsingResult.resultValue;
|
||||||
for (String s : split) {
|
List<Object> values = convertList(tokens);
|
||||||
Object converted = convert(s.trim());
|
|
||||||
if (values.isEmpty() || values.get(0).getClass().isAssignableFrom(converted.getClass()) || converted.getClass().isAssignableFrom(values.get(0).getClass())) {
|
if (values == INVALID_ARRAY) {
|
||||||
values.add(converted);
|
return INVALID;
|
||||||
} else {
|
|
||||||
return INVALID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
|
@ -80,18 +79,6 @@ class ValueAnalysis {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
// char[] chars = value.toCharArray();
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < chars.length; i++) {
|
|
||||||
// char ch = chars[i];
|
|
||||||
// if (Character.isDigit(ch) || ch == '.' || (i == 0 && ch == '-')) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDate(String value) {
|
private boolean isDate(String value) {
|
||||||
|
@ -114,56 +101,14 @@ class ValueAnalysis {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
// char[] chars = s.toCharArray();
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < chars.length; i++) {
|
|
||||||
// if (Character.isDigit(chars[i]) || (i == 0 && chars[i] == '-')) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isList(String s) {
|
private boolean isArray(String s) {
|
||||||
Matcher matcher = LIST_REGEX.matcher(s);
|
return s.startsWith("[");
|
||||||
|
|
||||||
if (matcher.matches()) {
|
|
||||||
chosenMatcher = matcher;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> tokenizeList(String list) {
|
private boolean isHomogenousArray(Object o, List<?> values) {
|
||||||
ArrayList<String> strings = new ArrayList<String>();
|
return values.get(0).getClass().isAssignableFrom(o.getClass()) || o.getClass().isAssignableFrom(values.get(0).getClass());
|
||||||
char[] chars = list.toCharArray();
|
|
||||||
int openIndex = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < chars.length && openIndex < 0; i++) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder token = new StringBuilder();
|
|
||||||
boolean ignore = false;
|
|
||||||
for (int i = 0; i < chars.length; i++) {
|
|
||||||
if (ignore) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (chars[i] == '[')
|
|
||||||
if (chars[i] != ',') {
|
|
||||||
token.append(chars[i]);
|
|
||||||
} else {
|
|
||||||
strings.add(token.toString().trim());
|
|
||||||
token = new StringBuilder();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBoolean(String s) {
|
private boolean isBoolean(String s) {
|
||||||
|
@ -232,6 +177,30 @@ class ValueAnalysis {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Object> convertList(List<Object> tokens) {
|
||||||
|
ArrayList<Object> nestedList = new ArrayList<Object>();
|
||||||
|
|
||||||
|
for (Object token : tokens) {
|
||||||
|
if (token instanceof String) {
|
||||||
|
Object converted = convert(((String) token).trim());
|
||||||
|
if (nestedList.isEmpty() || isHomogenousArray(converted, nestedList)) {
|
||||||
|
nestedList.add(converted);
|
||||||
|
} else {
|
||||||
|
return INVALID_ARRAY;
|
||||||
|
}
|
||||||
|
} else if (token instanceof List) {
|
||||||
|
List<Object> convertedList = convertList((List<Object>) token);
|
||||||
|
if (convertedList != INVALID_ARRAY) {
|
||||||
|
nestedList.add(convertedList);
|
||||||
|
} else {
|
||||||
|
return INVALID_ARRAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nestedList;
|
||||||
|
}
|
||||||
|
|
||||||
private String replaceUnicodeCharacters(String value) {
|
private String replaceUnicodeCharacters(String value) {
|
||||||
Matcher unicodeMatcher = UNICODE_REGEX.matcher(value);
|
Matcher unicodeMatcher = UNICODE_REGEX.matcher(value);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue