temporary commit
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
wson.version = 2023.009.30
|
||||
wson.version = 2023.10.01
|
||||
|
||||
lys.version = 2023.09.26
|
||||
lys.version = 2023.10.01
|
||||
|
||||
|
@@ -31,7 +31,7 @@ dependencyResolutionManagement {
|
||||
|
||||
rootProject.name = 'wson'
|
||||
|
||||
def includeDirs = ['antlr', 'benchmark', 'test-utils', 'wson-cli', 'wson-w3c-json']
|
||||
def includeDirs = ['antlr', 'benchmark', 'test-utils', 'wson-cli', 'wson-w3c-json', 'wcfg']
|
||||
|
||||
includeDirs.each {
|
||||
include(it)
|
||||
|
16
wcfg/build.gradle
Normal file
16
wcfg/build.gradle
Normal file
@@ -0,0 +1,16 @@
|
||||
plugins {
|
||||
id 'antlr'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation catalog.jwo
|
||||
implementation rootProject
|
||||
|
||||
antlr catalog.antlr
|
||||
antlr catalog.antlr.runtime
|
||||
}
|
||||
|
||||
generateGrammarSource {
|
||||
maxHeapSize = "64m"
|
||||
arguments += ['-package', 'net.woggioni.wson.wcfg']
|
||||
}
|
101
wcfg/src/main/antlr/net/woggioni/wson/wcfg/WCFG.g4
Normal file
101
wcfg/src/main/antlr/net/woggioni/wson/wcfg/WCFG.g4
Normal file
@@ -0,0 +1,101 @@
|
||||
grammar WCFG;
|
||||
|
||||
wcfg
|
||||
: assignment*
|
||||
;
|
||||
|
||||
assignment
|
||||
: IDENTIFIER ':=' (expression | value) ';'
|
||||
;
|
||||
|
||||
expression
|
||||
: value ('<<' value)+
|
||||
;
|
||||
|
||||
obj
|
||||
: '{' pair (',' pair)* '}'
|
||||
| '{' '}'
|
||||
;
|
||||
|
||||
pair
|
||||
: STRING ':' (expression | value)
|
||||
;
|
||||
|
||||
array
|
||||
: '[' value (',' value)* ']'
|
||||
| '[' ']'
|
||||
;
|
||||
|
||||
value
|
||||
: NULL
|
||||
| BOOLEAN
|
||||
| NUMBER
|
||||
| STRING
|
||||
| IDENTIFIER
|
||||
| obj
|
||||
| array
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
: 'true'
|
||||
| 'false'
|
||||
;
|
||||
|
||||
NULL
|
||||
: 'null'
|
||||
;
|
||||
|
||||
NUMBER
|
||||
: '-'? INT ('.' [0-9] +)? EXP?
|
||||
;
|
||||
|
||||
IDENTIFIER: Letter LetterOrDigit*;
|
||||
|
||||
STRING
|
||||
: '"' (ESC | SAFECODEPOINT)* '"'
|
||||
;
|
||||
|
||||
fragment ESC
|
||||
: '\\' (["\\/bfnrt] | UNICODE)
|
||||
;
|
||||
|
||||
|
||||
fragment UNICODE
|
||||
: 'u' HEX HEX HEX HEX
|
||||
;
|
||||
|
||||
|
||||
fragment HEX
|
||||
: [0-9a-fA-F]
|
||||
;
|
||||
|
||||
|
||||
fragment SAFECODEPOINT
|
||||
: ~ ["\\\u0000-\u001F]
|
||||
;
|
||||
|
||||
|
||||
fragment INT
|
||||
: '0' | [1-9] [0-9]*
|
||||
;
|
||||
|
||||
// no leading zeros
|
||||
|
||||
fragment EXP
|
||||
: [Ee] [+\-]? INT
|
||||
;
|
||||
|
||||
fragment LetterOrDigit
|
||||
: Letter
|
||||
| [0-9]
|
||||
;
|
||||
|
||||
fragment Letter
|
||||
: [a-zA-Z$_] // these are the "java letters" below 0x7F
|
||||
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
|
||||
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
|
||||
;
|
||||
|
||||
WS
|
||||
: [ \t\n\r] + -> skip
|
||||
;
|
@@ -0,0 +1,95 @@
|
||||
package net.woggioni.wson.wcfg;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.woggioni.wson.traversal.ValueIdentity;
|
||||
import net.woggioni.wson.value.ObjectValue;
|
||||
import net.woggioni.wson.xface.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static net.woggioni.jwo.JWO.dynamicCast;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CompositeObjectValue implements ObjectValue {
|
||||
|
||||
private final List<ObjectValue> elements;
|
||||
|
||||
private ObjectValue wrapped;
|
||||
|
||||
public CompositeObjectValue(List<ObjectValue> elements, Value.Configuration cfg) {
|
||||
this.elements = elements;
|
||||
wrapped = ObjectValue.newInstance(cfg);
|
||||
List<ValueIdentity> identities = new ArrayList<>();
|
||||
for (ObjectValue element : elements) {
|
||||
CompositeObjectValue compositeObjectValue;
|
||||
if ((compositeObjectValue = dynamicCast(element, CompositeObjectValue.class)) != null) {
|
||||
boolean differenceFound = false;
|
||||
for (int i = 0; i < compositeObjectValue.elements.size(); i++) {
|
||||
ObjectValue objectValue = compositeObjectValue.elements.get(i);
|
||||
if (!differenceFound && (i >= identities.size() || !Objects.equals(
|
||||
identities.get(i),
|
||||
new ValueIdentity(compositeObjectValue.elements.get(i))))) {
|
||||
differenceFound = true;
|
||||
}
|
||||
if (differenceFound) {
|
||||
merge(wrapped, objectValue);
|
||||
identities.add(new ValueIdentity(objectValue));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
merge(wrapped, element);
|
||||
identities.add(new ValueIdentity(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void merge(ObjectValue v1, ObjectValue v2) {
|
||||
for (Map.Entry<String, Value> entry : v2) {
|
||||
Value putResult = v1.getOrPut(entry.getKey(), entry.getValue());
|
||||
if (putResult != entry.getValue()) {
|
||||
if (putResult.type() == Value.Type.OBJECT && entry.getValue().type() == Value.Type.OBJECT) {
|
||||
ObjectValue ov = ObjectValue.newInstance();
|
||||
merge(ov, (ObjectValue) putResult);
|
||||
merge(ov, (ObjectValue) entry.getValue());
|
||||
v1.put(entry.getKey(), ov);
|
||||
} else {
|
||||
v1.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Map.Entry<String, Value>> iterator() {
|
||||
return wrapped.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(String key) {
|
||||
return wrapped.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getOrDefault(String key, Value defaultValue) {
|
||||
return wrapped.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String key) {
|
||||
return wrapped.has(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return wrapped.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Map.Entry<String, Value>> asObject() {
|
||||
return this::iterator;
|
||||
}
|
||||
}
|
226
wcfg/src/main/java/net/woggioni/wson/wcfg/ListenerImpl.java
Normal file
226
wcfg/src/main/java/net/woggioni/wson/wcfg/ListenerImpl.java
Normal file
@@ -0,0 +1,226 @@
|
||||
package net.woggioni.wson.wcfg;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.woggioni.wson.value.ArrayValue;
|
||||
import net.woggioni.wson.value.BooleanValue;
|
||||
import net.woggioni.wson.value.FloatValue;
|
||||
import net.woggioni.wson.value.IntegerValue;
|
||||
import net.woggioni.wson.value.NullValue;
|
||||
import net.woggioni.wson.value.ObjectValue;
|
||||
import net.woggioni.wson.value.StringValue;
|
||||
import net.woggioni.wson.xface.Value;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.woggioni.jwo.JWO.dynamicCast;
|
||||
|
||||
class ListenerImpl implements WCFGListener {
|
||||
|
||||
private final Value.Configuration cfg;
|
||||
|
||||
@Getter
|
||||
private final Value result;
|
||||
|
||||
private interface StackLevel {
|
||||
Value getValue();
|
||||
}
|
||||
|
||||
private static class ArrayStackLevel implements StackLevel {
|
||||
private final ArrayValue value = new ArrayValue();
|
||||
|
||||
@Override
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ObjectStackLevel implements StackLevel {
|
||||
public String currentKey;
|
||||
private final ObjectValue value;
|
||||
|
||||
public ObjectStackLevel(Value.Configuration cfg) {
|
||||
value = ObjectValue.newInstance(cfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ExpressionStackLevel implements StackLevel {
|
||||
private final Value.Configuration cfg;
|
||||
private ObjectValue value = null;
|
||||
public List<ObjectValue> elements = new ArrayList<>();
|
||||
|
||||
public ExpressionStackLevel(Value.Configuration cfg) {
|
||||
this.cfg = cfg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getValue() {
|
||||
if(value == null) {
|
||||
value = new CompositeObjectValue(elements, cfg);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<StackLevel> stack = new ArrayList<>();
|
||||
|
||||
private void add2Last(Value value) {
|
||||
StackLevel last = stack.get(stack.size() - 1);
|
||||
ArrayStackLevel asl;
|
||||
ObjectStackLevel osl;
|
||||
ExpressionStackLevel esl;
|
||||
if ((asl = dynamicCast(last, ArrayStackLevel.class)) != null) {
|
||||
asl.value.add(value);
|
||||
} else if ((osl = dynamicCast(last, ObjectStackLevel.class)) != null) {
|
||||
osl.value.put(osl.currentKey, value);
|
||||
osl.currentKey = null;
|
||||
} else if((esl = dynamicCast(last, ExpressionStackLevel.class)) != null) {
|
||||
esl.elements.add((ObjectValue) value);
|
||||
}
|
||||
}
|
||||
private static String unquote(String quoted) {
|
||||
return quoted.substring(1, quoted.length() - 1);
|
||||
}
|
||||
|
||||
public ListenerImpl(Value.Configuration cfg) {
|
||||
this.cfg = cfg;
|
||||
StackLevel sl = new ObjectStackLevel(cfg);
|
||||
result = sl.getValue();
|
||||
stack.add(sl);
|
||||
}
|
||||
|
||||
private StackLevel pop() {
|
||||
int size = stack.size() - 1;
|
||||
StackLevel sl = stack.get(size);
|
||||
stack.remove(size);
|
||||
return sl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterWcfg(WCFGParser.WcfgContext ctx) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void exitWcfg(WCFGParser.WcfgContext ctx) {
|
||||
stack.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterAssignment(WCFGParser.AssignmentContext ctx) {
|
||||
ObjectStackLevel osl = (ObjectStackLevel) stack.get(0);
|
||||
osl.currentKey = ctx.IDENTIFIER().getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitAssignment(WCFGParser.AssignmentContext ctx) {
|
||||
ObjectStackLevel osl = (ObjectStackLevel) stack.get(0);
|
||||
osl.currentKey = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterExpression(WCFGParser.ExpressionContext ctx) {
|
||||
ExpressionStackLevel esl = new ExpressionStackLevel(cfg);
|
||||
stack.add(esl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitExpression(WCFGParser.ExpressionContext ctx) {
|
||||
add2Last(pop().getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterObj(WCFGParser.ObjContext ctx) {
|
||||
ObjectStackLevel osl = new ObjectStackLevel(cfg);
|
||||
stack.add(osl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitObj(WCFGParser.ObjContext ctx) {
|
||||
add2Last(pop().getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterPair(WCFGParser.PairContext ctx) {
|
||||
ObjectStackLevel osl = (ObjectStackLevel) stack.get(stack.size() - 1);
|
||||
osl.currentKey = unquote(ctx.STRING().getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitPair(WCFGParser.PairContext ctx) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterArray(WCFGParser.ArrayContext ctx) {
|
||||
ArrayStackLevel asl = new ArrayStackLevel();
|
||||
stack.add(asl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitArray(WCFGParser.ArrayContext ctx) {
|
||||
add2Last(pop().getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterValue(WCFGParser.ValueContext ctx) {
|
||||
if (ctx.obj() != null) {
|
||||
} else if (ctx.array() != null) {
|
||||
} else if (ctx.STRING() != null) {
|
||||
add2Last(new StringValue(unquote(ctx.STRING().getText())));
|
||||
} else if (ctx.BOOLEAN() != null) {
|
||||
add2Last(new BooleanValue(Boolean.parseBoolean(ctx.BOOLEAN().getText())));
|
||||
} else if (ctx.NULL() != null) {
|
||||
add2Last(new NullValue());
|
||||
} else if (ctx.NUMBER() != null) {
|
||||
String text = ctx.NUMBER().getText();
|
||||
if (text.indexOf('.') < 0) {
|
||||
add2Last(new IntegerValue(Long.parseLong(text)));
|
||||
} else {
|
||||
add2Last(new FloatValue(Double.parseDouble(text)));
|
||||
}
|
||||
} else if(ctx.IDENTIFIER() != null) {
|
||||
String name = ctx.IDENTIFIER().getText();
|
||||
Value referredValue = result.getOrDefault(name, null);
|
||||
if(referredValue == null) {
|
||||
throw new ParseError(
|
||||
"Undeclared identifier '" + name + "'",
|
||||
ctx.start.getLine(),
|
||||
ctx.start.getCharPositionInLine() + 1
|
||||
);
|
||||
}
|
||||
add2Last(referredValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitValue(WCFGParser.ValueContext ctx) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTerminal(TerminalNode node) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitErrorNode(ErrorNode node) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterEveryRule(ParserRuleContext ctx) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEveryRule(ParserRuleContext ctx) {
|
||||
|
||||
}
|
||||
}
|
15
wcfg/src/main/java/net/woggioni/wson/wcfg/ParseError.java
Normal file
15
wcfg/src/main/java/net/woggioni/wson/wcfg/ParseError.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package net.woggioni.wson.wcfg;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ParseError extends RuntimeException {
|
||||
public ParseError(String message, int line, int column) {
|
||||
super(message + String.format(" at %d:%d", line, column));
|
||||
}
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage();
|
||||
}
|
||||
}
|
110
wcfg/src/main/java/net/woggioni/wson/wcfg/ValueHolder.java
Normal file
110
wcfg/src/main/java/net/woggioni/wson/wcfg/ValueHolder.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package net.woggioni.wson.wcfg;
|
||||
|
||||
import lombok.Setter;
|
||||
import net.woggioni.wson.xface.Value;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ValueHolder implements Value {
|
||||
@Setter
|
||||
private Value delegate = Value.Null;
|
||||
@Override
|
||||
public Type type() {
|
||||
return delegate.type();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNull() {
|
||||
return delegate.isNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asBoolean() {
|
||||
return delegate.asBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long asInteger() {
|
||||
return delegate.asInteger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double asFloat() {
|
||||
return delegate.asFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asString() {
|
||||
return delegate.asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Value> asArray() {
|
||||
return delegate.asArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Map.Entry<String, Value>> asObject() {
|
||||
return delegate.asObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Value value) {
|
||||
delegate.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int index, Value value) {
|
||||
delegate.set(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value pop() {
|
||||
return delegate.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value head() {
|
||||
return delegate.head();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value tail() {
|
||||
return delegate.tail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(int index) {
|
||||
return delegate.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String key, Value value) {
|
||||
delegate.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get(String key) {
|
||||
return delegate.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getOrDefault(String key, Value defaultValue) {
|
||||
return delegate.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value getOrPut(String key, Value value2Put) {
|
||||
return delegate.getOrPut(key, value2Put);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(String key) {
|
||||
return delegate.has(key);
|
||||
}
|
||||
}
|
47
wcfg/src/main/java/net/woggioni/wson/wcfg/WConfig.java
Normal file
47
wcfg/src/main/java/net/woggioni/wson/wcfg/WConfig.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package net.woggioni.wson.wcfg;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.wson.value.ObjectValue;
|
||||
import net.woggioni.wson.xface.Value;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CodePointCharStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WConfig {
|
||||
|
||||
private final Value.Configuration cfg;
|
||||
private final Value value;
|
||||
|
||||
@SneakyThrows
|
||||
public WConfig(Reader reader, Value.Configuration cfg) {
|
||||
this.cfg = cfg;
|
||||
CodePointCharStream inputStream = CharStreams.fromReader(reader);
|
||||
WCFGLexer lexer = new WCFGLexer(inputStream);
|
||||
CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
|
||||
WCFGParser parser = new WCFGParser(commonTokenStream);
|
||||
ListenerImpl listener = new ListenerImpl(cfg);
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(listener, parser.wcfg());
|
||||
value = listener.getResult();
|
||||
}
|
||||
|
||||
public Value get(String key) {
|
||||
return value.get(key);
|
||||
}
|
||||
|
||||
public Value get(String ...overrides) {
|
||||
return new CompositeObjectValue(
|
||||
Arrays.stream(overrides)
|
||||
.map(k -> (ObjectValue) value.get(k))
|
||||
.collect(Collectors.toList()), cfg);
|
||||
}
|
||||
|
||||
public Value whole() {
|
||||
return value;
|
||||
}
|
||||
}
|
56
wcfg/src/test/java/net/woggioni/wson/wcfg/ParseTest.java
Normal file
56
wcfg/src/test/java/net/woggioni/wson/wcfg/ParseTest.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package net.woggioni.wson.wcfg;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.wson.serialization.json.JSONDumper;
|
||||
import net.woggioni.wson.xface.Value;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CodePointCharStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
public class ParseTest {
|
||||
|
||||
@SneakyThrows
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
// "build.wcfg",
|
||||
// "test.wcfg",
|
||||
"recursive.wcfg",
|
||||
})
|
||||
public void test(String resource) {
|
||||
try(Reader reader = new InputStreamReader(getClass().getClassLoader().getResourceAsStream(resource))) {
|
||||
CodePointCharStream inputStream = CharStreams.fromReader(reader);
|
||||
WCFGLexer lexer = new WCFGLexer(inputStream);
|
||||
CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
|
||||
WCFGParser parser = new WCFGParser(commonTokenStream);
|
||||
Value.Configuration cfg = Value.Configuration.builder().serializeReferences(true).build();
|
||||
ListenerImpl listener = new ListenerImpl(cfg);
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(listener, parser.wcfg());
|
||||
Value result = listener.getResult();
|
||||
new JSONDumper(cfg).dump(result, System.out);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void test2() {
|
||||
Value.Configuration cfg = Value.Configuration.builder().serializeReferences(true).build();
|
||||
try (Reader reader = new InputStreamReader(getClass().getResourceAsStream("/build.wcfg"))) {
|
||||
WConfig wConfig = new WConfig(reader, cfg);
|
||||
Value result = wConfig.get("release", "dev");
|
||||
try (OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/build.json"))) {
|
||||
new JSONDumper(cfg).dump(result, os);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
wcfg/src/test/resources/build.wcfg
Normal file
55
wcfg/src/test/resources/build.wcfg
Normal file
@@ -0,0 +1,55 @@
|
||||
default := {
|
||||
"source-directory": ".",
|
||||
"generator": "Unix Makefiles",
|
||||
"options": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
};
|
||||
|
||||
dev := default << {
|
||||
"options": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
};
|
||||
|
||||
jenkins := {
|
||||
"build-directory" : "build"
|
||||
};
|
||||
|
||||
release := default << {
|
||||
"clean": true,
|
||||
"options": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
};
|
||||
|
||||
lin64 := default << {
|
||||
"options" : {
|
||||
"STATIC_LIBSTDCXX" : true,
|
||||
"QT5_STATIC": "ON"
|
||||
}
|
||||
};
|
||||
|
||||
win64 := default << {
|
||||
"options": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "/opt/x-tools/x86_64-w64-mingw32/cmake/toolchain-x86_64-w64-mingw32.cmake",
|
||||
"STATIC_BUILD": "ON",
|
||||
"QT5_STATIC": "ON"
|
||||
}
|
||||
};
|
||||
|
||||
win32 := default << {
|
||||
"options": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "/opt/x-tools/i686-w64-mingw32/cmake/toolchain-i686-w64-mingw32.cmake",
|
||||
"STATIC_BUILD": "ON",
|
||||
"QT5_STATIC": "ON"
|
||||
}
|
||||
};
|
||||
|
||||
musl := default << {
|
||||
"options": {
|
||||
"CMAKE_TOOLCHAIN_FILE": "/opt/x-tools/x86_64-woggioni-linux-musl/cmake/toolchain-x86_64-woggioni-linux-musl.cmake",
|
||||
"QT5_STATIC": "ON",
|
||||
"STATIC_BUILD": "ON"
|
||||
}
|
||||
};
|
4
wcfg/src/test/resources/recursive.wcfg
Normal file
4
wcfg/src/test/resources/recursive.wcfg
Normal file
@@ -0,0 +1,4 @@
|
||||
value1 := {
|
||||
"key" : "value",
|
||||
"myself" : value1
|
||||
};
|
23
wcfg/src/test/resources/test.wcfg
Normal file
23
wcfg/src/test/resources/test.wcfg
Normal file
@@ -0,0 +1,23 @@
|
||||
default := {
|
||||
"foo" : 2,
|
||||
"bar" : true
|
||||
};
|
||||
|
||||
overridden := default << {
|
||||
"foo" : 0,
|
||||
"enabled" : false,
|
||||
"window" : null
|
||||
};
|
||||
|
||||
window := {
|
||||
"width" : 640,
|
||||
"height" : 480
|
||||
};
|
||||
|
||||
foobar := {
|
||||
"child" : overridden << {
|
||||
"window" : window
|
||||
} << {
|
||||
"enabled" : true
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user