mirror of
https://github.com/plexusorg/toml4j.git
synced 2025-02-11 11:40:27 +00:00
Renamed parsers
This commit is contained in:
parent
bdfe33382a
commit
5253a80748
5 changed files with 149 additions and 484 deletions
|
@ -1,190 +0,0 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import static com.moandjiezana.toml.ValueAnalysis.INVALID;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.parboiled.Parboiled;
|
||||
import org.parboiled.parserunners.BasicParseRunner;
|
||||
import org.parboiled.support.ParsingResult;
|
||||
|
||||
public class RegexParser {
|
||||
private static final Pattern MULTILINE_ARRAY_REGEX = Pattern.compile("\\s*\\[([^\\]]*)");
|
||||
private static final Pattern MULTILINE_ARRAY_REGEX_END = Pattern.compile("\\s*\\]");
|
||||
|
||||
private final Results results = new Results();
|
||||
|
||||
public Results run(String tomlString) {
|
||||
if (tomlString.isEmpty()) {
|
||||
return results;
|
||||
}
|
||||
|
||||
String[] lines = tomlString.split("[\\n\\r]");
|
||||
StringBuilder multilineBuilder = new StringBuilder();
|
||||
boolean multiline = false;
|
||||
|
||||
String key = null;
|
||||
String value = null;
|
||||
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
|
||||
if (line != null) {
|
||||
line = line.trim();
|
||||
}
|
||||
|
||||
if (isComment(line) || line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isTableArray(line)) {
|
||||
String tableName = getTableArrayName(line);
|
||||
if (tableName != null) {
|
||||
results.startTableArray(tableName);
|
||||
String afterTableName = line.substring(tableName.length() + 4);
|
||||
if (!isComment(afterTableName)) {
|
||||
results.errors.append("Invalid table array definition: " + line + "\n\n");
|
||||
}
|
||||
} else {
|
||||
results.errors.append("Invalid table array definition: " + line + "\n\n");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!multiline && isTable(line)) {
|
||||
String tableName = getTableName(line);
|
||||
if (tableName != null) {
|
||||
// Matcher matcher = TABLE_REGEX.matcher(line);
|
||||
// matcher.matches();
|
||||
// String tableName = matcher.group(1);
|
||||
results.startTables(tableName);
|
||||
String afterTableName = line.substring(tableName.length() + 2);
|
||||
if (!isComment(afterTableName)) {
|
||||
results.errors.append("Invalid table definition: " + line + "\n\n");
|
||||
}
|
||||
} else {
|
||||
results.errors.append("Invalid table definition: " + line + "\n\n");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] pair = line.split("=");
|
||||
|
||||
if (!multiline && MULTILINE_ARRAY_REGEX.matcher(pair[1].trim()).matches()) {
|
||||
multiline = true;
|
||||
key = pair[0].trim();
|
||||
multilineBuilder.append(removeComment(pair[1]));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (multiline) {
|
||||
String lineWithoutComment = removeComment(line);
|
||||
multilineBuilder.append(lineWithoutComment);
|
||||
if (MULTILINE_ARRAY_REGEX_END.matcher(lineWithoutComment).matches()) {
|
||||
multiline = false;
|
||||
value = multilineBuilder.toString();
|
||||
multilineBuilder.delete(0, multilineBuilder.length() - 1);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
key = pair[0].trim();
|
||||
value = pair[1].trim();
|
||||
}
|
||||
|
||||
if (!isKeyValid(key)) {
|
||||
results.errors.append("Invalid key name: " + key);
|
||||
continue;
|
||||
}
|
||||
|
||||
ValueAnalysis lineAnalysis = new ValueAnalysis(value);
|
||||
|
||||
Object convertedValue = lineAnalysis.getValue();
|
||||
|
||||
if (convertedValue != INVALID) {
|
||||
results.addValue(key, convertedValue);
|
||||
} else {
|
||||
results.errors.append("Invalid key/value: " + key + " = " + value);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private boolean isTableArray(String line) {
|
||||
return line.startsWith("[[");
|
||||
}
|
||||
|
||||
private String getTableArrayName(String line) {
|
||||
ParboiledParser parser = Parboiled.createParser(ParboiledParser.class);
|
||||
ParsingResult<List<Object>> parsingResult = new BasicParseRunner<List<Object>>(parser.TableArray()).run(line);
|
||||
|
||||
if (parsingResult.resultValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (String) parsingResult.resultValue.get(0);
|
||||
}
|
||||
|
||||
private boolean isTable(String line) {
|
||||
return line.startsWith("[");
|
||||
}
|
||||
|
||||
private String getTableName(String line) {
|
||||
ParboiledParser parser = Parboiled.createParser(ParboiledParser.class);
|
||||
ParsingResult<List<Object>> parsingResult = new BasicParseRunner<List<Object>>(parser.Table()).run(line);
|
||||
|
||||
if (parsingResult.resultValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (String) parsingResult.resultValue.get(0);
|
||||
}
|
||||
|
||||
private boolean isKeyValid(String key) {
|
||||
if (key.contains(".") || key.contains("#") || key.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isComment(String line) {
|
||||
if (line == null || line.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char[] chars = line.toCharArray();
|
||||
|
||||
for (char c : chars) {
|
||||
if (Character.isWhitespace(c)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return c == '#';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private String removeComment(String line) {
|
||||
line = line.trim();
|
||||
if (line.startsWith("\"")) {
|
||||
int startOfComment = line.indexOf('#', line.lastIndexOf('"'));
|
||||
if (startOfComment > -1) {
|
||||
return line.substring(0, startOfComment - 1).trim();
|
||||
}
|
||||
} else {
|
||||
int startOfComment = line.indexOf('#');
|
||||
if (startOfComment > -1) {
|
||||
return line.substring(0, startOfComment - 1).trim();
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
}
|
|
@ -5,11 +5,9 @@ import java.util.List;
|
|||
|
||||
import org.parboiled.BaseParser;
|
||||
import org.parboiled.Rule;
|
||||
import org.parboiled.annotations.BuildParseTree;
|
||||
import org.parboiled.annotations.SuppressNode;
|
||||
|
||||
@BuildParseTree
|
||||
public class ParboiledParser extends BaseParser<List<Object>> {
|
||||
public class StatementParser extends BaseParser<List<Object>> {
|
||||
|
||||
public Rule Array() {
|
||||
return FirstOf(EmptyArray(), Sequence('[', startList(), OneOrMore(FirstOf(NonEmptyArray(), ' ', ',')), ']', endList()));
|
|
@ -126,7 +126,7 @@ public class Toml {
|
|||
* @throws IllegalStateException If tomlString is not valid TOML
|
||||
*/
|
||||
public Toml parse(String tomlString) throws IllegalStateException {
|
||||
Results results = new RegexParser().run(tomlString);
|
||||
Results results = new TomlParser().run(tomlString);
|
||||
if (results.errors.length() > 0) {
|
||||
throw new IllegalStateException(results.errors.toString());
|
||||
}
|
||||
|
|
|
@ -1,333 +1,190 @@
|
|||
package com.moandjiezana.toml;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import static com.moandjiezana.toml.ValueAnalysis.INVALID;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.parboiled.BaseParser;
|
||||
import org.parboiled.Rule;
|
||||
import org.parboiled.annotations.BuildParseTree;
|
||||
import org.parboiled.annotations.SuppressNode;
|
||||
import org.parboiled.Parboiled;
|
||||
import org.parboiled.parserunners.BasicParseRunner;
|
||||
import org.parboiled.support.ParsingResult;
|
||||
|
||||
@BuildParseTree
|
||||
class TomlParser extends BaseParser<Object> {
|
||||
public class TomlParser {
|
||||
private static final Pattern MULTILINE_ARRAY_REGEX = Pattern.compile("\\s*\\[([^\\]]*)");
|
||||
private static final Pattern MULTILINE_ARRAY_REGEX_END = Pattern.compile("\\s*\\]");
|
||||
|
||||
static class Results {
|
||||
public Map<String, Object> values = new HashMap<String, Object>();
|
||||
public Set<String> tables = new HashSet<String>();
|
||||
public StringBuilder errors = new StringBuilder();
|
||||
}
|
||||
private final Results results = new Results();
|
||||
|
||||
public Rule Toml() {
|
||||
return Sequence(push(new TomlParser.Results()), push(((TomlParser.Results) peek()).values), OneOrMore(FirstOf(TableArray(), Table(), '\n', Comment(), Key())));
|
||||
}
|
||||
public Results run(String tomlString) {
|
||||
if (tomlString.isEmpty()) {
|
||||
return results;
|
||||
}
|
||||
|
||||
Rule Table() {
|
||||
return Sequence(Sequence(TableDelimiter(), TableName(), addTable((String) pop()), TableDelimiter(), Spacing()), checkTable(match()));
|
||||
}
|
||||
String[] lines = tomlString.split("[\\n\\r]");
|
||||
StringBuilder multilineBuilder = new StringBuilder();
|
||||
boolean multiline = false;
|
||||
|
||||
Rule TableArray() {
|
||||
return Sequence(Sequence(TableDelimiter(), TableDelimiter(), TableName(), addTableArray((String) pop()), TableDelimiter(), TableDelimiter(), Spacing()), checkTable(match()));
|
||||
}
|
||||
String key = null;
|
||||
String value = null;
|
||||
|
||||
boolean checkTable(String definition) {
|
||||
String afterBracket = definition.substring(definition.lastIndexOf(']') + 1);
|
||||
for (char character : afterBracket.toCharArray()) {
|
||||
if (character == '#') {
|
||||
return true;
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
|
||||
if (line != null) {
|
||||
line = line.trim();
|
||||
}
|
||||
|
||||
if (!Character.isWhitespace(character)) {
|
||||
results().errors.append("Invalid table definition: ").append(definition).append(". You may have forgotten a #.\n");
|
||||
if (isComment(line) || line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Rule Key() {
|
||||
return Sequence(Spacing(), KeyName(), EqualsSign(), VariableValues(), Spacing(), swap(), addKey((String) pop(), pop()));
|
||||
}
|
||||
if (isTableArray(line)) {
|
||||
String tableName = getTableArrayName(line);
|
||||
if (tableName != null) {
|
||||
results.startTableArray(tableName);
|
||||
String afterTableName = line.substring(tableName.length() + 4);
|
||||
if (!isComment(afterTableName)) {
|
||||
results.errors.append("Invalid table array definition: " + line + "\n\n");
|
||||
}
|
||||
} else {
|
||||
results.errors.append("Invalid table array definition: " + line + "\n\n");
|
||||
}
|
||||
|
||||
Rule TableName() {
|
||||
return Sequence(OneOrMore(TestNot(TableDelimiter()), FirstOf(Letter(), Digit(), ANY)), push(match()));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Rule KeyName() {
|
||||
return Sequence(OneOrMore(TestNot(EqualsSign()), ANY), push(match()));
|
||||
}
|
||||
if (!multiline && isTable(line)) {
|
||||
String tableName = getTableName(line);
|
||||
if (tableName != null) {
|
||||
// Matcher matcher = TABLE_REGEX.matcher(line);
|
||||
// matcher.matches();
|
||||
// String tableName = matcher.group(1);
|
||||
results.startTables(tableName);
|
||||
String afterTableName = line.substring(tableName.length() + 2);
|
||||
if (!isComment(afterTableName)) {
|
||||
results.errors.append("Invalid table definition: " + line + "\n\n");
|
||||
}
|
||||
} else {
|
||||
results.errors.append("Invalid table definition: " + line + "\n\n");
|
||||
}
|
||||
|
||||
Rule VariableValues() {
|
||||
return FirstOf(ArrayValue(), DateValue(), BooleanValue(), NumberValue(), StringValue());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Rule ArrayValue() {
|
||||
return Sequence(push(ArrayList.class), '[', Spacing(), ZeroOrMore(VariableValues(), Optional(ArrayDelimiter())), Spacing(), ']', pushList());
|
||||
}
|
||||
String[] pair = line.split("=");
|
||||
|
||||
Rule DateValue() {
|
||||
return Sequence(Sequence(Year(), '-', Month(), '-', Day(), 'T', Digit(), Digit(), ':', Digit(), Digit(), ':', Digit(), Digit(), 'Z'), pushDate(match()));
|
||||
}
|
||||
if (!multiline && MULTILINE_ARRAY_REGEX.matcher(pair[1].trim()).matches()) {
|
||||
multiline = true;
|
||||
key = pair[0].trim();
|
||||
multilineBuilder.append(removeComment(pair[1]));
|
||||
continue;
|
||||
}
|
||||
|
||||
Rule BooleanValue() {
|
||||
return Sequence(FirstOf("true", "false"), push(Boolean.valueOf(match())));
|
||||
}
|
||||
|
||||
Rule NumberValue() {
|
||||
return Sequence(Sequence(Optional('-'), OneOrMore(FirstOf(Digit(), '.'))), pushNumber(match()));
|
||||
}
|
||||
|
||||
Rule StringValue() {
|
||||
return Sequence(push(new StringBuilder()), '"', OneOrMore(TestNot('"'), FirstOf(UnicodeCharacter(), SpecialCharacter(), AnyCharacter())), pushString(((StringBuilder) pop()).toString()), '"');
|
||||
}
|
||||
|
||||
Rule Year() {
|
||||
return Sequence(Digit(), Digit(), Digit(), Digit());
|
||||
}
|
||||
|
||||
Rule Month() {
|
||||
return Sequence(CharRange('0', '1'), Digit());
|
||||
}
|
||||
|
||||
Rule Day() {
|
||||
return Sequence(CharRange('0', '3'), Digit());
|
||||
}
|
||||
|
||||
Rule Digit() {
|
||||
return CharRange('0', '9');
|
||||
}
|
||||
|
||||
Rule Letter() {
|
||||
return CharRange('a', 'z');
|
||||
}
|
||||
|
||||
Rule UnicodeCharacter() {
|
||||
return Sequence(Sequence('\\', 'u', OneOrMore(FirstOf(CharRange('0', '9'), CharRange('A', 'F')))), pushCharacter(match()));
|
||||
}
|
||||
|
||||
Rule SpecialCharacter() {
|
||||
return Sequence(Sequence('\\', ANY), pushCharacter(match()));
|
||||
}
|
||||
|
||||
Rule AnyCharacter() {
|
||||
return Sequence(TestNot(NewLine()), ANY, pushCharacter(match()));
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule TableDelimiter() {
|
||||
return AnyOf("[]");
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule EqualsSign() {
|
||||
return Sequence(Spacing(), '=', Spacing());
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule Spacing() {
|
||||
return ZeroOrMore(FirstOf(Comment(), Whitespace(), NewLine(), AnyOf("\f")));
|
||||
}
|
||||
|
||||
Rule IllegalCharacters() {
|
||||
return Sequence(ZeroOrMore(Whitespace()), OneOrMore(TestNot('#', NewLine()), ANY));
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule Whitespace() {
|
||||
return AnyOf(" \t");
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule NewLine() {
|
||||
return AnyOf("\r\n");
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule ArrayDelimiter() {
|
||||
return Sequence(Spacing(), ',', Spacing());
|
||||
}
|
||||
|
||||
@SuppressNode
|
||||
Rule Comment() {
|
||||
return Sequence(ZeroOrMore(Whitespace()), '#', ZeroOrMore(TestNot(NewLine()), ANY), FirstOf(NewLine(), EOI));
|
||||
}
|
||||
|
||||
boolean addTableArray(String name) {
|
||||
return addTable(name, true);
|
||||
}
|
||||
|
||||
boolean addTable(String name) {
|
||||
return addTable(name, false);
|
||||
}
|
||||
|
||||
boolean addKey(String key, Object value) {
|
||||
if (key.contains(".")) {
|
||||
results().errors.append(key).append(" is invalid: key names may not contain a dot!\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
putValue(key, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean pushList() {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
while (peek() != ArrayList.class) {
|
||||
Object listItem = pop();
|
||||
if (list.isEmpty() || list.get(0).getClass().isAssignableFrom(listItem.getClass()) || listItem.getClass().isAssignableFrom(list.get(0).getClass())) {
|
||||
list.add(0, listItem);
|
||||
if (multiline) {
|
||||
String lineWithoutComment = removeComment(line);
|
||||
multilineBuilder.append(lineWithoutComment);
|
||||
if (MULTILINE_ARRAY_REGEX_END.matcher(lineWithoutComment).matches()) {
|
||||
multiline = false;
|
||||
value = multilineBuilder.toString();
|
||||
multilineBuilder.delete(0, multilineBuilder.length() - 1);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
results().errors.append("Attempt to create mixed array!");
|
||||
key = pair[0].trim();
|
||||
value = pair[1].trim();
|
||||
}
|
||||
|
||||
if (!isKeyValid(key)) {
|
||||
results.errors.append("Invalid key name: " + key);
|
||||
continue;
|
||||
}
|
||||
|
||||
ValueAnalysis lineAnalysis = new ValueAnalysis(value);
|
||||
|
||||
Object convertedValue = lineAnalysis.getValue();
|
||||
|
||||
if (convertedValue != INVALID) {
|
||||
results.addValue(key, convertedValue);
|
||||
} else {
|
||||
results.errors.append("Invalid key/value: " + key + " = " + value);
|
||||
}
|
||||
}
|
||||
|
||||
poke(list);
|
||||
return true;
|
||||
return results;
|
||||
}
|
||||
|
||||
boolean pushDate(String dateString) {
|
||||
String s = dateString.replace("Z", "+00:00");
|
||||
try {
|
||||
s = s.substring(0, 22) + s.substring(23);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
|
||||
dateFormat.setLenient(false);
|
||||
Date date = dateFormat.parse(s);
|
||||
push(date);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
results().errors.append("Invalid date: ").append(dateString).append("\n");
|
||||
private boolean isTableArray(String line) {
|
||||
return line.startsWith("[[");
|
||||
}
|
||||
|
||||
private String getTableArrayName(String line) {
|
||||
StatementParser parser = Parboiled.createParser(StatementParser.class);
|
||||
ParsingResult<List<Object>> parsingResult = new BasicParseRunner<List<Object>>(parser.TableArray()).run(line);
|
||||
|
||||
if (parsingResult.resultValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (String) parsingResult.resultValue.get(0);
|
||||
}
|
||||
|
||||
private boolean isTable(String line) {
|
||||
return line.startsWith("[");
|
||||
}
|
||||
|
||||
private String getTableName(String line) {
|
||||
StatementParser parser = Parboiled.createParser(StatementParser.class);
|
||||
ParsingResult<List<Object>> parsingResult = new BasicParseRunner<List<Object>>(parser.Table()).run(line);
|
||||
|
||||
if (parsingResult.resultValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (String) parsingResult.resultValue.get(0);
|
||||
}
|
||||
|
||||
private boolean isKeyValid(String key) {
|
||||
if (key.contains(".") || key.contains("#") || key.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean pushNumber(String number) {
|
||||
if (number.contains(".")) {
|
||||
push(Double.valueOf(number));
|
||||
} else {
|
||||
push(Long.valueOf(number));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean pushString(String line) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
String[] split = line.split("\\\\n");
|
||||
for (String string : split) {
|
||||
builder.append(string).append('\n');
|
||||
}
|
||||
builder.deleteCharAt(builder.length() - 1);
|
||||
push(builder.toString());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean pushCharacter(String sc) {
|
||||
StringBuilder sb = (StringBuilder) peek();
|
||||
if (sc.equals("\\n")) {
|
||||
sb.append('\n');
|
||||
} else if (sc.equals("\\\"")) {
|
||||
sb.append('\"');
|
||||
} else if (sc.equals("\\t")) {
|
||||
sb.append('\t');
|
||||
} else if (sc.equals("\\r")) {
|
||||
sb.append('\r');
|
||||
} else if (sc.equals("\\\\")) {
|
||||
sb.append('\\');
|
||||
} else if (sc.equals("\\/")) {
|
||||
sb.append('/');
|
||||
} else if (sc.equals("\\b")) {
|
||||
sb.append('\b');
|
||||
} else if (sc.equals("\\f")) {
|
||||
sb.append('\f');
|
||||
} else if (sc.startsWith("\\u")) {
|
||||
sb.append(Character.toChars(Integer.parseInt(sc.substring(2), 16)));
|
||||
} else if (sc.startsWith("\\")) {
|
||||
results().errors.append(sc + " is a reserved special character and cannot be used!\n");
|
||||
} else {
|
||||
sb.append(sc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean addTable(String name, boolean array) {
|
||||
String[] split = name.split("\\.");
|
||||
|
||||
while (getContext().getValueStack().size() > 2) {
|
||||
drop();
|
||||
}
|
||||
|
||||
Map<String, Object> newTable = (Map<String, Object>) getContext().getValueStack().peek();
|
||||
|
||||
boolean addedToTables = results().tables.add(name);
|
||||
if (!addedToTables && !array) {
|
||||
results().errors.append("Could not create table ").append(name).append(": table already exists!\n");
|
||||
|
||||
private boolean isComment(String line) {
|
||||
if (line == null || line.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
String splitKey = split[i];
|
||||
char[] chars = line.toCharArray();
|
||||
|
||||
if (!newTable.containsKey(splitKey)) {
|
||||
if (array && isLast(split, i)) {
|
||||
ArrayList<Map<String, Object>> newTableList = new ArrayList<Map<String, Object>>();
|
||||
newTable.put(splitKey, newTableList);
|
||||
} else {
|
||||
newTable.put(splitKey, new HashMap<String, Object>());
|
||||
}
|
||||
}
|
||||
Object currentValue = newTable.get(splitKey);
|
||||
if (!(currentValue instanceof List) && !(currentValue instanceof Map)) {
|
||||
results().errors.append("Could not create table ").append(name).append(": key already has a value!\n");
|
||||
|
||||
return true;
|
||||
for (char c : chars) {
|
||||
if (Character.isWhitespace(c)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentValue instanceof List) {
|
||||
List<Map<String, Object>> currentList = (List<Map<String, Object>>) currentValue;
|
||||
if (array && isLast(split, i)) {
|
||||
Map<String, Object> newTableListItem = new HashMap<String,Object>();
|
||||
currentList.add(newTableListItem);
|
||||
currentValue = newTableListItem;
|
||||
} else {
|
||||
currentValue = currentList.get(currentList.size() - 1);
|
||||
}
|
||||
return c == '#';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private String removeComment(String line) {
|
||||
line = line.trim();
|
||||
if (line.startsWith("\"")) {
|
||||
int startOfComment = line.indexOf('#', line.lastIndexOf('"'));
|
||||
if (startOfComment > -1) {
|
||||
return line.substring(0, startOfComment - 1).trim();
|
||||
}
|
||||
} else {
|
||||
int startOfComment = line.indexOf('#');
|
||||
if (startOfComment > -1) {
|
||||
return line.substring(0, startOfComment - 1).trim();
|
||||
}
|
||||
|
||||
newTable = (Map<String, Object>) currentValue;
|
||||
}
|
||||
|
||||
push(newTable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void putValue(String name, Object value) {
|
||||
Map<String, Object> values = (Map<String, Object>) peek();
|
||||
Object top = peek();
|
||||
if (top instanceof List) {
|
||||
values = ((List<Map<String, Object>>) top).get(((List<Map<String, Object>>) top).size() - 1);
|
||||
}
|
||||
if (values.containsKey(name)) {
|
||||
results().errors.append("Key ").append(name).append(" already exists!\n");
|
||||
return;
|
||||
}
|
||||
values.put(name, value);
|
||||
}
|
||||
|
||||
private boolean isLast(String[] array, int index) {
|
||||
return index == array.length - 1;
|
||||
}
|
||||
|
||||
private TomlParser.Results results() {
|
||||
return (Results) peek(getContext().getValueStack().size() - 1);
|
||||
return line;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class ValueAnalysis {
|
|||
} else if (isBoolean(value)) {
|
||||
return Boolean.valueOf(chosenMatcher.group(1));
|
||||
} else if (isArray(value)) {
|
||||
ParboiledParser parser = Parboiled.createParser(ParboiledParser.class);
|
||||
StatementParser parser = Parboiled.createParser(StatementParser.class);
|
||||
ParsingResult<List<Object>> parsingResult = new BasicParseRunner<List<Object>>(parser.Array()).run(value);
|
||||
List<Object> tokens = parsingResult.resultValue;
|
||||
List<Object> values = convertList(tokens);
|
||||
|
|
Loading…
Reference in a new issue