Skip to content

Commit

Permalink
#162: Merged with master in order to modify latest version of ByToken…
Browse files Browse the repository at this point in the history
….getAllRoots().
  • Loading branch information
jvdb committed Jun 9, 2017
2 parents b5e0d7f + bfd8663 commit f0b3b31
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 60 deletions.
16 changes: 8 additions & 8 deletions core/src/main/java/io/parsingdata/metal/Shorthand.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,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, 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); }
Expand All @@ -102,10 +102,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, 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); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ public static ImmutableList<ParseItem> getAllRoots(final ParseGraph graph, final

private static ImmutableList<ParseItem> getAllRootsRecursive(final ParseItem item, final ParseGraph parent, final Token definition) {
final ImmutableList<ParseItem> 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;
}
Expand Down
8 changes: 5 additions & 3 deletions core/src/main/java/io/parsingdata/metal/token/Cho.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static io.parsingdata.metal.Trampoline.complete;
import static io.parsingdata.metal.Trampoline.intermediate;
import static io.parsingdata.metal.Util.checkContainsNoNulls;
import static io.parsingdata.metal.Util.checkNotNull;
import static io.parsingdata.metal.Util.success;
import static io.parsingdata.metal.data.ImmutableList.create;

Expand All @@ -43,10 +44,11 @@ public class Cho extends Token {

public final ImmutableList<Token> 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, "additionalTokens"))
.add(checkNotNull(token2, "token2"))
.add(checkNotNull(token1, "token1"));
}

@Override
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/io/parsingdata/metal/token/Def.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
* A Def consists of a <code>size</code> (a {@link ValueExpression}.
* <p>
* Parsing will succeed if <code>size</code> 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
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/io/parsingdata/metal/token/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public Post(final String name, final Token token, final Expression predicate, fi
protected Optional<Environment> parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException {
final Optional<Environment> 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();
}
Expand Down
8 changes: 5 additions & 3 deletions core/src/main/java/io/parsingdata/metal/token/Seq.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static io.parsingdata.metal.Trampoline.complete;
import static io.parsingdata.metal.Trampoline.intermediate;
import static io.parsingdata.metal.Util.checkContainsNoNulls;
import static io.parsingdata.metal.Util.checkNotNull;
import static io.parsingdata.metal.Util.success;
import static io.parsingdata.metal.data.ImmutableList.create;

Expand All @@ -43,10 +44,11 @@ public class Seq extends Token {

public final ImmutableList<Token> 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, "additionalTokens"))
.add(checkNotNull(token2, "token2"))
.add(checkNotNull(token1, "token1"));
}

@Override
Expand Down
18 changes: 10 additions & 8 deletions core/src/test/java/io/parsingdata/metal/ArgumentsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,11 @@ public static Collection<Object[]> 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, 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 } },
Expand All @@ -124,10 +125,11 @@ public static Collection<Object[]> 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, 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 } },
Expand Down
29 changes: 0 additions & 29 deletions core/src/test/java/io/parsingdata/metal/ShorthandsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -82,6 +84,13 @@ protected Optional<Environment> 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();

Expand Down Expand Up @@ -307,7 +316,7 @@ public CustomToken() {
}

@Override
protected Optional<Environment> parseImpl(String scope, Environment environment, Encoding encoding) throws IOException {
protected Optional<Environment> parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException {
return token.parse(scope, environment, encoding);
}
}
Expand All @@ -329,4 +338,57 @@ 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<ParseItem> 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<ParseItem> 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<ParseItem> 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<ParseItem> firstMutRecValues = getAll(items.head.asGraph(), DEF1);
assertThat(firstMutRecValues.size, is(equalTo(1L)));
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<ParseItem> secondMutRecValues = getAll(items.tail.head.asGraph(), DEF1);
assertThat(secondMutRecValues.size, is(equalTo(2L)));
assertThat(lastItem(secondMutRecValues).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<ParseItem> items = ByToken.getAllRoots(graph, SELF_REC);
assertThat(items.size, is(equalTo(6L)));

for (int value = 0xF; value >= 0xA; value--) {
final ImmutableList<ParseItem> values = getAll(items.head.asGraph(), DEF1);
assertThat(lastItem(values).asValue().asNumeric().intValue(), is(equalTo(value)));
items = items.tail;
}
}

private static <T> T lastItem(final ImmutableList<T> items) {
return Reversal.reverse(items).head;
}

}

0 comments on commit f0b3b31

Please sign in to comment.