From 48756ef6cfa2012e79c0f22b0fdc3cb238f6d00e Mon Sep 17 00:00:00 2001 From: Jeroen van den Bos Date: Thu, 9 Mar 2017 07:53:40 +0100 Subject: [PATCH 01/10] #157: Improved Javadoc and Post implementation consistency. Based on feedback from @rdvdijk. --- core/src/main/java/io/parsingdata/metal/token/Def.java | 3 ++- core/src/main/java/io/parsingdata/metal/token/Post.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/token/Def.java b/core/src/main/java/io/parsingdata/metal/token/Def.java index 505457b3..0def2671 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Def.java +++ b/core/src/main/java/io/parsingdata/metal/token/Def.java @@ -38,7 +38,8 @@ * A Def consists of a size (a {@link ValueExpression}. *

* Parsing will succeed if size evaluates to a single value and if - * that many bytes are available in the input. + * that many bytes are available in the input. This means that a size of zero + * will lead to a successful parse, but will not produce a value. * * @see Nod * @see ValueExpression diff --git a/core/src/main/java/io/parsingdata/metal/token/Post.java b/core/src/main/java/io/parsingdata/metal/token/Post.java index 6a356bdd..72510c1c 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Post.java +++ b/core/src/main/java/io/parsingdata/metal/token/Post.java @@ -54,8 +54,8 @@ public Post(final String name, final Token token, final Expression predicate, fi protected Optional parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { final Optional result = token.parse(scope, environment.addBranch(this), encoding); if (result.isPresent()) { - final Environment newEnvironment = result.get().closeBranch(); - return predicate.eval(newEnvironment.order, encoding) ? success(newEnvironment) : failure(); + final Environment newEnvironment = result.get(); + return predicate.eval(newEnvironment.order, encoding) ? success(newEnvironment.closeBranch()) : failure(); } return failure(); } From 29b09c9d9f39cfedcc0e7aabd2ac5fe468cbb31f Mon Sep 17 00:00:00 2001 From: Christophe Creeten Date: Wed, 22 Mar 2017 18:41:20 +0100 Subject: [PATCH 02/10] Changed order of list returned by ByToken#getAllRoots. --- .../metal/data/selection/ByToken.java | 10 +++--- .../metal/data/selection/ByTokenTest.java | 35 ++++++++++++++++++- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java b/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java index 2677e380..46341a1e 100644 --- a/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java +++ b/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java @@ -92,12 +92,12 @@ public static ImmutableList getAllRoots(final ParseGraph graph, final private static ImmutableList getAllRootsRecursive(final ParseItem item, final ParseGraph parent, final Token definition) { final ImmutableList result = item.getDefinition().equals(definition) && (parent == null || !parent.getDefinition().equals(definition)) - ? ImmutableList.create(item) - : new ImmutableList(); + ? ImmutableList.create(item) + : new ImmutableList<>(); if (item.isGraph() && !item.asGraph().isEmpty()) { - return getAllRootsRecursive(item.asGraph().tail, item.asGraph(), definition) - .add(getAllRootsRecursive(item.asGraph().head, item.asGraph(), definition)) - .add(result); + return result + .add(getAllRootsRecursive(item.asGraph().tail, item.asGraph(), definition) + .add(getAllRootsRecursive(item.asGraph().head, item.asGraph(), definition))); } return result; } diff --git a/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java b/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java index 25337cd7..b0e819d7 100644 --- a/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java +++ b/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java @@ -307,7 +307,7 @@ public CustomToken() { } @Override - protected Optional parseImpl(String scope, Environment environment, Encoding encoding) throws IOException { + protected Optional parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { return token.parse(scope, environment, encoding); } } @@ -329,4 +329,37 @@ public void getAllRootsEmpty() { assertEquals(1, getAllRoots(ParseGraph.EMPTY, ParseGraph.NONE).size); } + @Test + public void getAllRootsOrderRepDef() throws IOException { + final ParseGraph graph = parseResultGraph(stream(0, 1, 2), rep(DEF1)); + final ImmutableList items = getAllRoots(graph, DEF1); + assertThat(items.size, is(equalTo(3L))); + assertThat(items.head.asValue().asNumeric().intValue(), is(equalTo(2))); + assertThat(items.tail.head.asValue().asNumeric().intValue(), is(equalTo(1))); + assertThat(items.tail.tail.head.asValue().asNumeric().intValue(), is(equalTo(0))); + } + + @Test + public void getAllRootsOrderSeqSub() { + final ParseGraph graph = parseResultGraph(stream(4, 2, 2, 3, 4, 5), SEQ_SUB); + final ImmutableList items = getAllRoots(graph, TWO_BYTES); + assertThat(items.size, is(equalTo(2L))); + assertThat(items.head.asValue().asNumeric().intValue(), is(equalTo(0x0203))); + assertThat(items.tail.head.asValue().asNumeric().intValue(), is(equalTo(0x0405))); + } + + @Test + public void getAllRootsOrderMutualRecursive() { + final ParseGraph graph = parseResultGraph(stream(0, 1, 2, 3, 4, 5), MUT_REC_1); + final ImmutableList items = getAllRoots(graph, MUT_REC_1); + assertThat(items.size, is(equalTo(2L))); + + final ImmutableList firstMutRecValues = getAll(items.head.asGraph(), DEF1); + assertThat(firstMutRecValues.size, is(equalTo(1L))); + assertThat(firstMutRecValues.head.asValue().asNumeric().intValue(), is(equalTo(3))); + + final ImmutableList secondMutRecValues = getAll(items.tail.head.asGraph(), DEF1); + assertThat(secondMutRecValues.size, is(equalTo(2L))); + assertThat(secondMutRecValues.tail.head.asValue().asNumeric().intValue(), is(equalTo(0))); + } } From a0af3af596c35bf9c07be39048903c81d0e6def6 Mon Sep 17 00:00:00 2001 From: Christophe Creeten Date: Thu, 23 Mar 2017 10:47:48 +0100 Subject: [PATCH 03/10] Added self recursive test. --- .../metal/data/selection/ByTokenTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java b/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java index b0e819d7..61f00317 100644 --- a/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java +++ b/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java @@ -34,6 +34,7 @@ import static io.parsingdata.metal.Shorthand.repn; import static io.parsingdata.metal.Shorthand.seq; import static io.parsingdata.metal.Shorthand.sub; +import static io.parsingdata.metal.Shorthand.token; import static io.parsingdata.metal.data.selection.ByName.getAllValues; import static io.parsingdata.metal.data.selection.ByToken.get; import static io.parsingdata.metal.data.selection.ByToken.getAll; @@ -56,6 +57,7 @@ import io.parsingdata.metal.data.ParseGraph; import io.parsingdata.metal.data.ParseItem; import io.parsingdata.metal.data.ParseValue; +import io.parsingdata.metal.data.transformation.Reversal; import io.parsingdata.metal.encoding.Encoding; import io.parsingdata.metal.expression.value.Value; import io.parsingdata.metal.token.Token; @@ -81,6 +83,13 @@ protected Optional parseImpl(final String scope, final Environment }); private static final Token MUT_REC_2 = seq(REPN_DEF2, opt(MUT_REC_1)); + + private static final Token SELF_REC = + seq("selfRec", + DEF1, + def("childCount", 1), + repn( + token("selfRec"), last(ref("childCount")))); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -354,12 +363,32 @@ public void getAllRootsOrderMutualRecursive() { final ImmutableList items = getAllRoots(graph, MUT_REC_1); assertThat(items.size, is(equalTo(2L))); + // item.head is the MUT_REC_1 graph containing [3, 4, 5], with '3' having the DEF1 definition final ImmutableList firstMutRecValues = getAll(items.head.asGraph(), DEF1); assertThat(firstMutRecValues.size, is(equalTo(1L))); assertThat(firstMutRecValues.head.asValue().asNumeric().intValue(), is(equalTo(3))); + // item.tail.head is the MUT_REC_1 graph containing [0, 1, 2, 3, 4, 5], with '0' and '3' having the DEF1 definition final ImmutableList secondMutRecValues = getAll(items.tail.head.asGraph(), DEF1); assertThat(secondMutRecValues.size, is(equalTo(2L))); assertThat(secondMutRecValues.tail.head.asValue().asNumeric().intValue(), is(equalTo(0))); } + + @Test + public void getAllRootsSelfRecursive() throws IOException { + final ParseGraph graph = parseResultGraph(stream(0xA, 3, 0xB, 2, 0xC, 0, 0xD, 0, 0xE, 0, 0xF, 0), SELF_REC); + ImmutableList items = ByToken.getAllRoots(graph, SELF_REC); + assertThat(items.size, is(equalTo(6L))); + + for (int value = 0xF; value >= 0xA; value--) { + final ImmutableList values = getAll(items.head.asGraph(), DEF1); + assertThat(lastItem(values).asValue().asNumeric().intValue(), is(equalTo(value))); + items = items.tail; + } + } + + private static T lastItem(final ImmutableList items) { + return Reversal.reverse(items).head; + } + } From 19d361645a54f6bf50f787ea8fa2357ac2ec9e82 Mon Sep 17 00:00:00 2001 From: Christophe Creeten Date: Thu, 23 Mar 2017 10:59:11 +0100 Subject: [PATCH 04/10] Small refactoring of roots implementation and test. --- .../java/io/parsingdata/metal/data/selection/ByToken.java | 4 ++-- .../java/io/parsingdata/metal/data/selection/ByTokenTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java b/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java index 46341a1e..d73a721f 100644 --- a/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java +++ b/core/src/main/java/io/parsingdata/metal/data/selection/ByToken.java @@ -96,8 +96,8 @@ private static ImmutableList getAllRootsRecursive(final ParseItem ite : new ImmutableList<>(); if (item.isGraph() && !item.asGraph().isEmpty()) { return result - .add(getAllRootsRecursive(item.asGraph().tail, item.asGraph(), definition) - .add(getAllRootsRecursive(item.asGraph().head, item.asGraph(), definition))); + .add(getAllRootsRecursive(item.asGraph().tail, item.asGraph(), definition)) + .add(getAllRootsRecursive(item.asGraph().head, item.asGraph(), definition)); } return result; } diff --git a/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java b/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java index 61f00317..f07f144e 100644 --- a/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java +++ b/core/src/test/java/io/parsingdata/metal/data/selection/ByTokenTest.java @@ -366,12 +366,12 @@ public void getAllRootsOrderMutualRecursive() { // item.head is the MUT_REC_1 graph containing [3, 4, 5], with '3' having the DEF1 definition final ImmutableList firstMutRecValues = getAll(items.head.asGraph(), DEF1); assertThat(firstMutRecValues.size, is(equalTo(1L))); - assertThat(firstMutRecValues.head.asValue().asNumeric().intValue(), is(equalTo(3))); + assertThat(lastItem(firstMutRecValues).asValue().asNumeric().intValue(), is(equalTo(3))); // item.tail.head is the MUT_REC_1 graph containing [0, 1, 2, 3, 4, 5], with '0' and '3' having the DEF1 definition final ImmutableList secondMutRecValues = getAll(items.tail.head.asGraph(), DEF1); assertThat(secondMutRecValues.size, is(equalTo(2L))); - assertThat(secondMutRecValues.tail.head.asValue().asNumeric().intValue(), is(equalTo(0))); + assertThat(lastItem(secondMutRecValues).asValue().asNumeric().intValue(), is(equalTo(0))); } @Test From a5bd5deb395f1febc587e241925c9f775f46f2b8 Mon Sep 17 00:00:00 2001 From: Marja van Aken Date: Fri, 21 Apr 2017 14:10:32 +0200 Subject: [PATCH 05/10] Forced argument check at compile time for the seq and cho shorthands. Moved the exception tests to the ArgumentsTest. --- .../java/io/parsingdata/metal/Shorthand.java | 21 +++++++++----- .../io/parsingdata/metal/ArgumentsTest.java | 6 +++- .../io/parsingdata/metal/ShorthandsTest.java | 29 ------------------- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/Shorthand.java b/core/src/main/java/io/parsingdata/metal/Shorthand.java index 90c2f35c..bd8e6d4b 100644 --- a/core/src/main/java/io/parsingdata/metal/Shorthand.java +++ b/core/src/main/java/io/parsingdata/metal/Shorthand.java @@ -21,6 +21,7 @@ import java.util.function.BiFunction; import java.util.function.BinaryOperator; +import java.util.stream.Stream; import io.parsingdata.metal.encoding.Encoding; import io.parsingdata.metal.expression.Expression; @@ -90,10 +91,10 @@ private Shorthand() {} public static Token def(final String name, final long size, final Encoding encoding) { return def(name, con(size), encoding); } public static Token def(final String name, final long size) { return def(name, size, (Encoding)null); } public static final Token empty = def(NO_NAME, 0L); - public static Token cho(final String name, final Encoding encoding, final Token... tokens) { return new Cho(name, encoding, tokens); } - public static Token cho(final String name, final Token... tokens) { return cho(name, null, tokens); } - public static Token cho(final Encoding encoding, final Token... tokens) { return cho(NO_NAME, encoding, tokens); } - public static Token cho(final Token... tokens) { return cho((Encoding)null, tokens); } + public static Token cho(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return new Cho(name, encoding, concatVarArgTokens(token1, token2, tokens)); } + public static Token cho(final String name, final Token token1, final Token token2, final Token... tokens) { return cho(name, null, token1, token2, tokens); } + public static Token cho(final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return cho(NO_NAME, encoding, token1, token2, tokens); } + public static Token cho(final Token token1, final Token token2, final Token... tokens) { return cho((Encoding)null, token1, token2, tokens); } public static Token rep(final String name, final Token token, final Encoding encoding) { return new Rep(name, token, encoding); } public static Token rep(final String name, final Token token) { return rep(name, token, null); } public static Token rep(final Token token, final Encoding encoding) { return rep(NO_NAME, token, encoding); } @@ -102,10 +103,10 @@ private Shorthand() {} public static Token repn(final String name, final Token token, final ValueExpression n) { return repn(name, token, n, null); } public static Token repn(final Token token, final ValueExpression n, final Encoding encoding) { return repn(NO_NAME, token, n, encoding); } public static Token repn(final Token token, final ValueExpression n) { return repn(token, n, null); } - public static Token seq(final String name, final Encoding encoding, final Token... tokens) { return new Seq(name, encoding, tokens); } - public static Token seq(final String name, final Token... tokens) { return seq(name, null, tokens); } - public static Token seq(final Encoding encoding, final Token... tokens) { return seq(NO_NAME, encoding, tokens); } - public static Token seq(final Token... tokens) { return seq((Encoding)null, tokens); } + public static Token seq(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return new Seq(name, encoding, concatVarArgTokens(token1, token2, tokens)); } + public static Token seq(final String name, final Token token1, final Token token2, final Token... tokens) { return seq(name, null, token1, token2, tokens); } + public static Token seq(final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return seq(NO_NAME, encoding, token1, token2, tokens); } + public static Token seq(final Token token1, final Token token2, final Token... tokens) { return seq((Encoding)null, token1, token2, tokens); } public static Token sub(final String name, final Token token, final ValueExpression address, final Encoding encoding) { return new io.parsingdata.metal.token.Sub(name, token, address, encoding); } public static Token sub(final String name, final Token token, final ValueExpression address) { return sub(name, token, address, null); } public static Token sub(final Token token, final ValueExpression address, final Encoding encoding) { return sub(NO_NAME, token, address, encoding); } @@ -203,4 +204,8 @@ public static byte[] toByteArray(final int... bytes) { return outBytes; } + private static Token[] concatVarArgTokens(final Token token1, final Token token2, final Token... tokens) { + return Stream.concat(Stream.of(token1), Stream.concat(Stream.of(token2), Stream.of(tokens))).toArray(Token[]::new); + } + } diff --git a/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java b/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java index fefff246..bed7db60 100644 --- a/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java +++ b/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java @@ -112,6 +112,8 @@ public static Collection arguments() { { Cho.class, new Object[] { null, null, new Token[] { VALID_T, VALID_T } } }, { Cho.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T, null } } }, { Cho.class, new Object[] { VALID_NAME, null, new Token[] { null, VALID_T } } }, + { Cho.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T } } }, + { Cho.class, new Object[] { VALID_NAME, null, new Token[] { } } }, { Cho.class, new Object[] { VALID_NAME, null, null } }, { Def.class, new Object[] { VALID_NAME, null, null } }, { Def.class, new Object[] { null, VALID_VE, null } }, @@ -127,6 +129,8 @@ public static Collection arguments() { { Seq.class, new Object[] { null, null, new Token[] { VALID_T, VALID_T } } }, { Seq.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T, null } } }, { Seq.class, new Object[] { VALID_NAME, null, new Token[] { null, VALID_T } } }, + { Seq.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T } } }, + { Seq.class, new Object[] { VALID_NAME, null, new Token[] { } } }, { Seq.class, new Object[] { VALID_NAME, null, null } }, { Sub.class, new Object[] { null, VALID_T, VALID_VE, null } }, { Sub.class, new Object[] { VALID_NAME, VALID_T, null, null } }, @@ -156,7 +160,7 @@ public void runConstructor() throws Throwable { catch (final InvocationTargetException e) { assertEquals(IllegalArgumentException.class, e.getCause().getClass()); final String message = e.getCause().getMessage(); - assertTrue(message.endsWith("may not be null.") || message.endsWith("may not be empty.")); + assertTrue(message.endsWith("may not be null.") || message.endsWith("may not be empty.") || message.endsWith("two Tokens are required.")); } } diff --git a/core/src/test/java/io/parsingdata/metal/ShorthandsTest.java b/core/src/test/java/io/parsingdata/metal/ShorthandsTest.java index babc7d92..ea038e2f 100644 --- a/core/src/test/java/io/parsingdata/metal/ShorthandsTest.java +++ b/core/src/test/java/io/parsingdata/metal/ShorthandsTest.java @@ -168,35 +168,6 @@ private void checkNameAndValue(final String name, final int value, final Environ @Rule public ExpectedException thrown = ExpectedException.none(); - @Test - public void choSingle() { - setUpArgumentException(); - cho(any("a")); - } - - @Test - public void choEmpty() { - setUpArgumentException(); - cho(); - } - - @Test - public void seqSingle() { - setUpArgumentException(); - seq(any("a")); - } - - @Test - public void seqEmpty() { - setUpArgumentException(); - seq(); - } - - private void setUpArgumentException() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("At least two Tokens are required."); - } - public static final Token DEFA = any("a"); public static final Token DEFB = any("b"); From 51bc8f64f9cd63482d6109aaab3db7724c5f25ab Mon Sep 17 00:00:00 2001 From: Marja van Aken Date: Fri, 21 Apr 2017 15:06:05 +0200 Subject: [PATCH 06/10] Simplified concatenation of tokens. --- core/src/main/java/io/parsingdata/metal/Shorthand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/io/parsingdata/metal/Shorthand.java b/core/src/main/java/io/parsingdata/metal/Shorthand.java index bd8e6d4b..c8b8e4e9 100644 --- a/core/src/main/java/io/parsingdata/metal/Shorthand.java +++ b/core/src/main/java/io/parsingdata/metal/Shorthand.java @@ -205,7 +205,7 @@ public static byte[] toByteArray(final int... bytes) { } private static Token[] concatVarArgTokens(final Token token1, final Token token2, final Token... tokens) { - return Stream.concat(Stream.of(token1), Stream.concat(Stream.of(token2), Stream.of(tokens))).toArray(Token[]::new); + return Stream.concat(Stream.of(token1, token2), Stream.of(tokens)).toArray(Token[]::new); } } From 23778e049a1dfd5840d9476944df4598f18436bc Mon Sep 17 00:00:00 2001 From: Marja van Aken Date: Tue, 25 Apr 2017 22:16:11 +0200 Subject: [PATCH 07/10] Pushed mandatory tokens for Cho and Seq to constructors --- .../java/io/parsingdata/metal/Shorthand.java | 8 ++----- .../java/io/parsingdata/metal/token/Cho.java | 13 ++++++----- .../java/io/parsingdata/metal/token/Seq.java | 12 +++++----- .../io/parsingdata/metal/ArgumentsTest.java | 22 +++++++++---------- 4 files changed, 25 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/Shorthand.java b/core/src/main/java/io/parsingdata/metal/Shorthand.java index c8b8e4e9..0835c993 100644 --- a/core/src/main/java/io/parsingdata/metal/Shorthand.java +++ b/core/src/main/java/io/parsingdata/metal/Shorthand.java @@ -91,7 +91,7 @@ private Shorthand() {} public static Token def(final String name, final long size, final Encoding encoding) { return def(name, con(size), encoding); } public static Token def(final String name, final long size) { return def(name, size, (Encoding)null); } public static final Token empty = def(NO_NAME, 0L); - public static Token cho(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return new Cho(name, encoding, concatVarArgTokens(token1, token2, tokens)); } + public static Token cho(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return new Cho(name, encoding, token1, token2, tokens); } public static Token cho(final String name, final Token token1, final Token token2, final Token... tokens) { return cho(name, null, token1, token2, tokens); } public static Token cho(final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return cho(NO_NAME, encoding, token1, token2, tokens); } public static Token cho(final Token token1, final Token token2, final Token... tokens) { return cho((Encoding)null, token1, token2, tokens); } @@ -103,7 +103,7 @@ private Shorthand() {} public static Token repn(final String name, final Token token, final ValueExpression n) { return repn(name, token, n, null); } public static Token repn(final Token token, final ValueExpression n, final Encoding encoding) { return repn(NO_NAME, token, n, encoding); } public static Token repn(final Token token, final ValueExpression n) { return repn(token, n, null); } - public static Token seq(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return new Seq(name, encoding, concatVarArgTokens(token1, token2, tokens)); } + public static Token seq(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return new Seq(name, encoding, token1, token2, tokens); } public static Token seq(final String name, final Token token1, final Token token2, final Token... tokens) { return seq(name, null, token1, token2, tokens); } public static Token seq(final Encoding encoding, final Token token1, final Token token2, final Token... tokens) { return seq(NO_NAME, encoding, token1, token2, tokens); } public static Token seq(final Token token1, final Token token2, final Token... tokens) { return seq((Encoding)null, token1, token2, tokens); } @@ -204,8 +204,4 @@ public static byte[] toByteArray(final int... bytes) { return outBytes; } - private static Token[] concatVarArgTokens(final Token token1, final Token token2, final Token... tokens) { - return Stream.concat(Stream.of(token1, token2), Stream.of(tokens)).toArray(Token[]::new); - } - } diff --git a/core/src/main/java/io/parsingdata/metal/token/Cho.java b/core/src/main/java/io/parsingdata/metal/token/Cho.java index 59e917e9..13dc66a2 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Cho.java +++ b/core/src/main/java/io/parsingdata/metal/token/Cho.java @@ -16,15 +16,15 @@ package io.parsingdata.metal.token; -import static io.parsingdata.metal.Util.checkContainsNoNulls; -import static io.parsingdata.metal.Util.failure; -import static io.parsingdata.metal.Util.success; +import static io.parsingdata.metal.Util.*; import static io.parsingdata.metal.data.ImmutableList.create; import java.io.IOException; import java.util.Objects; import java.util.Optional; +import java.util.stream.Stream; +import com.sun.deploy.util.ArrayUtil; import io.parsingdata.metal.data.Environment; import io.parsingdata.metal.data.ImmutableList; import io.parsingdata.metal.encoding.Encoding; @@ -40,10 +40,11 @@ public class Cho extends Token { public final ImmutableList tokens; - public Cho(final String name, final Encoding encoding, final Token... tokens) { + public Cho(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... additionalTokens) { super(name, encoding); - this.tokens = create(checkContainsNoNulls(tokens, "tokens")); - if (this.tokens.size < 2) { throw new IllegalArgumentException("At least two Tokens are required."); } + this.tokens = create(checkContainsNoNulls(additionalTokens, "tokens")) + .add(checkNotNull(token2, "token2")) + .add(checkNotNull(token1, "token1")); } @Override diff --git a/core/src/main/java/io/parsingdata/metal/token/Seq.java b/core/src/main/java/io/parsingdata/metal/token/Seq.java index 7cbd0c1b..1fc39847 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Seq.java +++ b/core/src/main/java/io/parsingdata/metal/token/Seq.java @@ -16,14 +16,13 @@ package io.parsingdata.metal.token; -import static io.parsingdata.metal.Util.checkContainsNoNulls; -import static io.parsingdata.metal.Util.failure; -import static io.parsingdata.metal.Util.success; +import static io.parsingdata.metal.Util.*; import static io.parsingdata.metal.data.ImmutableList.create; import java.io.IOException; import java.util.Objects; import java.util.Optional; +import java.util.stream.Stream; import io.parsingdata.metal.data.Environment; import io.parsingdata.metal.data.ImmutableList; @@ -40,10 +39,11 @@ public class Seq extends Token { public final ImmutableList tokens; - public Seq(final String name, final Encoding encoding, final Token... tokens) { + public Seq(final String name, final Encoding encoding, final Token token1, final Token token2, final Token... additionalTokens) { super(name, encoding); - this.tokens = create(checkContainsNoNulls(tokens, "tokens")); - if (this.tokens.size < 2) { throw new IllegalArgumentException("At least two Tokens are required."); } + this.tokens = create(checkContainsNoNulls(additionalTokens, "tokens")) + .add(checkNotNull(token2, "token2")) + .add(checkNotNull(token1, "token1")); } @Override diff --git a/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java b/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java index bed7db60..98df9755 100644 --- a/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java +++ b/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java @@ -109,12 +109,11 @@ public static Collection arguments() { // Derived from ComparisonExpression { Eq.class, new Object[] { VALID_VE, null } }, // Token implementations - { Cho.class, new Object[] { null, null, new Token[] { VALID_T, VALID_T } } }, - { Cho.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T, null } } }, - { Cho.class, new Object[] { VALID_NAME, null, new Token[] { null, VALID_T } } }, - { Cho.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T } } }, - { Cho.class, new Object[] { VALID_NAME, null, new Token[] { } } }, - { Cho.class, new Object[] { VALID_NAME, null, null } }, + { Cho.class, new Object[] { null, null, VALID_T, VALID_T, new Token[] { VALID_T } } }, + { Cho.class, new Object[] { VALID_NAME, null, null, VALID_T, new Token[] { VALID_T } } }, + { Cho.class, new Object[] { VALID_NAME, null, VALID_T, null, new Token[] { VALID_T } } }, + { Cho.class, new Object[] { VALID_NAME, null, VALID_T, VALID_T, new Token[] { null } } }, + { Cho.class, new Object[] { VALID_NAME, null, VALID_T, VALID_T, null } }, { Def.class, new Object[] { VALID_NAME, null, null } }, { Def.class, new Object[] { null, VALID_VE, null } }, { Nod.class, new Object[] { null, VALID_VE, null } }, @@ -126,12 +125,11 @@ public static Collection arguments() { { RepN.class, new Object[] { null, VALID_T, VALID_VE, null } }, { RepN.class, new Object[] { VALID_NAME, null, VALID_VE, null } }, { RepN.class, new Object[] { VALID_NAME, VALID_T, null, null } }, - { Seq.class, new Object[] { null, null, new Token[] { VALID_T, VALID_T } } }, - { Seq.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T, null } } }, - { Seq.class, new Object[] { VALID_NAME, null, new Token[] { null, VALID_T } } }, - { Seq.class, new Object[] { VALID_NAME, null, new Token[] { VALID_T } } }, - { Seq.class, new Object[] { VALID_NAME, null, new Token[] { } } }, - { Seq.class, new Object[] { VALID_NAME, null, null } }, + { Seq.class, new Object[] { null, null, VALID_T, VALID_T, new Token[] { VALID_T } } }, + { Seq.class, new Object[] { VALID_NAME, null, null, VALID_T, new Token[] { VALID_T } } }, + { Seq.class, new Object[] { VALID_NAME, null, VALID_T, null, new Token[] { VALID_T } } }, + { Seq.class, new Object[] { VALID_NAME, null, VALID_T, VALID_T, new Token[] { null } } }, + { Seq.class, new Object[] { VALID_NAME, null, VALID_T, VALID_T, null } }, { Sub.class, new Object[] { null, VALID_T, VALID_VE, null } }, { Sub.class, new Object[] { VALID_NAME, VALID_T, null, null } }, { Sub.class, new Object[] { VALID_NAME, null, VALID_VE, null } }, From edf6f5fe9b5fb9ae701194942abc6a6a73f218a2 Mon Sep 17 00:00:00 2001 From: Marja van Aken Date: Tue, 25 Apr 2017 22:21:24 +0200 Subject: [PATCH 08/10] Removed unused imports --- core/src/main/java/io/parsingdata/metal/Shorthand.java | 1 - core/src/main/java/io/parsingdata/metal/token/Cho.java | 2 -- core/src/main/java/io/parsingdata/metal/token/Seq.java | 1 - 3 files changed, 4 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/Shorthand.java b/core/src/main/java/io/parsingdata/metal/Shorthand.java index 0835c993..ff4599a8 100644 --- a/core/src/main/java/io/parsingdata/metal/Shorthand.java +++ b/core/src/main/java/io/parsingdata/metal/Shorthand.java @@ -21,7 +21,6 @@ import java.util.function.BiFunction; import java.util.function.BinaryOperator; -import java.util.stream.Stream; import io.parsingdata.metal.encoding.Encoding; import io.parsingdata.metal.expression.Expression; diff --git a/core/src/main/java/io/parsingdata/metal/token/Cho.java b/core/src/main/java/io/parsingdata/metal/token/Cho.java index 13dc66a2..1b2c58f9 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Cho.java +++ b/core/src/main/java/io/parsingdata/metal/token/Cho.java @@ -22,9 +22,7 @@ import java.io.IOException; import java.util.Objects; import java.util.Optional; -import java.util.stream.Stream; -import com.sun.deploy.util.ArrayUtil; import io.parsingdata.metal.data.Environment; import io.parsingdata.metal.data.ImmutableList; import io.parsingdata.metal.encoding.Encoding; diff --git a/core/src/main/java/io/parsingdata/metal/token/Seq.java b/core/src/main/java/io/parsingdata/metal/token/Seq.java index 1fc39847..eb5601eb 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Seq.java +++ b/core/src/main/java/io/parsingdata/metal/token/Seq.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.Objects; import java.util.Optional; -import java.util.stream.Stream; import io.parsingdata.metal.data.Environment; import io.parsingdata.metal.data.ImmutableList; From 31944dd46fd083c5b2880a1db1650d49816f4bf7 Mon Sep 17 00:00:00 2001 From: Marja van Aken Date: Tue, 25 Apr 2017 22:39:20 +0200 Subject: [PATCH 09/10] Removed error message check for erroneous number of arguments in ArgumentsTest. An error with this message does not occur anymore. --- core/src/test/java/io/parsingdata/metal/ArgumentsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java b/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java index 98df9755..a3ea9412 100644 --- a/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java +++ b/core/src/test/java/io/parsingdata/metal/ArgumentsTest.java @@ -158,7 +158,7 @@ public void runConstructor() throws Throwable { catch (final InvocationTargetException e) { assertEquals(IllegalArgumentException.class, e.getCause().getClass()); final String message = e.getCause().getMessage(); - assertTrue(message.endsWith("may not be null.") || message.endsWith("may not be empty.") || message.endsWith("two Tokens are required.")); + assertTrue(message.endsWith("may not be null.") || message.endsWith("may not be empty.")); } } From 053491a4e3a80ff75a62f2d195ea4086f9dfbedc Mon Sep 17 00:00:00 2001 From: Marja van Aken Date: Mon, 1 May 2017 19:54:04 +0200 Subject: [PATCH 10/10] Use explicit imports instead of imports on demand. --- core/src/main/java/io/parsingdata/metal/token/Cho.java | 5 ++++- core/src/main/java/io/parsingdata/metal/token/Seq.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/io/parsingdata/metal/token/Cho.java b/core/src/main/java/io/parsingdata/metal/token/Cho.java index 1b2c58f9..87eca05d 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Cho.java +++ b/core/src/main/java/io/parsingdata/metal/token/Cho.java @@ -16,7 +16,10 @@ package io.parsingdata.metal.token; -import static io.parsingdata.metal.Util.*; +import static io.parsingdata.metal.Util.checkContainsNoNulls; +import static io.parsingdata.metal.Util.checkNotNull; +import static io.parsingdata.metal.Util.failure; +import static io.parsingdata.metal.Util.success; import static io.parsingdata.metal.data.ImmutableList.create; import java.io.IOException; diff --git a/core/src/main/java/io/parsingdata/metal/token/Seq.java b/core/src/main/java/io/parsingdata/metal/token/Seq.java index eb5601eb..39a33e76 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Seq.java +++ b/core/src/main/java/io/parsingdata/metal/token/Seq.java @@ -16,7 +16,10 @@ package io.parsingdata.metal.token; -import static io.parsingdata.metal.Util.*; +import static io.parsingdata.metal.Util.checkContainsNoNulls; +import static io.parsingdata.metal.Util.checkNotNull; +import static io.parsingdata.metal.Util.failure; +import static io.parsingdata.metal.Util.success; import static io.parsingdata.metal.data.ImmutableList.create; import java.io.IOException;