Skip to content

Commit

Permalink
Merge pull request #361 from parsingdata/until-revised
Browse files Browse the repository at this point in the history
#360: Add variant to Until to allow parsing excluding terminator
  • Loading branch information
mvanaken committed Mar 2, 2023
2 parents e3a38c6 + 24207c3 commit ddb1541
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 65 deletions.
66 changes: 58 additions & 8 deletions core/src/main/java/io/parsingdata/metal/Shorthand.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,38 @@ private Shorthand() {}
/** "DEFinition": Instantiates a {@link Def} with {@code size = con(size)} and {@code encoding = null}, nested in a {@link Post}. */
public static Token def(final String name, final long size, final Expression predicate) { return def(name, size, predicate, null); }


/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined. */
public static Token def(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final ValueExpression maxSize, final Token terminator, final Encoding encoding) { return new Until(name, initialSize, stepSize, maxSize, terminator, encoding); }

/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined with {@code encoding = null}. */
public static Token def(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final ValueExpression maxSize, final Token terminator) { return def(name, initialSize, stepSize, maxSize, terminator, null); }

/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined with {@code maxSize = null}. */
public static Token def(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final Token terminator, final Encoding encoding) { return def(name, initialSize, stepSize, null, terminator, encoding); }

/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined with {@code maxSize = null} and {@code encoding = null}. */
public static Token def(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final Token terminator) { return def(name, initialSize, stepSize, null, terminator, null); }

/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined with {@code stepSize = null} and {@code maxSize = null}. */
public static Token def(final String name, final ValueExpression initialSize, final Token terminator, final Encoding encoding) { return def(name, initialSize, null, terminator, encoding); }

/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined with {@code stepSize = null}, {@code maxSize = null} and {@code encoding = null}. */
public static Token def(final String name, final ValueExpression initialSize, final Token terminator) { return def(name, initialSize, null, terminator, null); }

/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined with {@code initialSize = null}, {@code stepSize = null} and {@code maxSize = null}. */
public static Token def(final String name, final Token terminator, final Encoding encoding) { return def(name, null, terminator, encoding); }

/** "DEFinition": Instantiates a {@link Until} where the size of the def is dynamically determined with {@code initialSize = null}, {@code stepSize = null}, {@code maxSize = null} and {@code encoding = null}. */
public static Token def(final String name, final Token terminator) { return def(name, terminator, null); }

/** "DEFinition": Instantiates a {@link Until} with the expression nested in a {@link Post} and {@code initialSize = con(1)}. */
public static Token def(final String name, final Expression predicate, final Encoding encoding) { return def(name, con(1), post(EMPTY, predicate), encoding); }

/** "DEFinition": Instantiates a {@link Until} where the terminator is the expression nested in a {@link Post}, {@code initialSize = con(1)} and {@code encoding = null}. */
public static Token def(final String name, final Expression predicate) { return def(name, predicate, null); }


/** "NO Data": denotes data that is not required during parsing and afterwards. Instantiates a {@link Def} with {@code name = EMPTY_NAME} and {@code encoding = null}. */
public static Token nod(final SingleValueExpression size) { return def(EMPTY_NAME, size); }

Expand Down Expand Up @@ -180,14 +212,32 @@ private Shorthand() {}
/** @see Tie */ public static Token tie(final String name, final Token token, final ValueExpression dataExpression) { return tie(name, token, dataExpression, null); }
/** @see Tie */ public static Token tie(final Token token, final ValueExpression dataExpression, final Encoding encoding) { return tie(NO_NAME, token, dataExpression, encoding); }
/** @see Tie */ public static Token tie(final Token token, final ValueExpression dataExpression) { return tie(token, dataExpression, null); }
/** @see Until */ public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final ValueExpression maxSize, final Token terminator, final Encoding encoding) { return new Until(name, initialSize, stepSize, maxSize, terminator, encoding); }
/** @see Until */ public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final ValueExpression maxSize, final Token terminator) { return until(name, initialSize, stepSize, maxSize, terminator, null); }
/** @see Until */ public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final Token terminator, final Encoding encoding) { return until(name, initialSize, stepSize, null, terminator, encoding); }
/** @see Until */ public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final Token terminator) { return until(name, initialSize, stepSize, null, terminator, null); }
/** @see Until */ public static Token until(final String name, final ValueExpression initialSize, final Token terminator, final Encoding encoding) { return until(name, initialSize, null, terminator, encoding); }
/** @see Until */ public static Token until(final String name, final ValueExpression initialSize, final Token terminator) { return until(name, initialSize, null, terminator, null); }
/** @see Until */ public static Token until(final String name, final Token terminator, final Encoding encoding) { return until(name, null, terminator, encoding); }
/** @see Until */ public static Token until(final String name, final Token terminator) { return until(name, terminator, null); }


/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq}. */
public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final ValueExpression maxSize, final Token terminator, final Encoding encoding) { return seq(def(name, initialSize, stepSize, maxSize, terminator, encoding), terminator); }

/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq} with {@code encoding = null}. */
public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final ValueExpression maxSize, final Token terminator) { return until(name, initialSize, stepSize, maxSize, terminator, null); }

/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq} with {@code maxSize = null}. */
public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final Token terminator, final Encoding encoding) { return until(name, initialSize, stepSize, null, terminator, encoding); }

/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq} with {@code maxSize = null} and {@code encoding = null}. */
public static Token until(final String name, final ValueExpression initialSize, final ValueExpression stepSize, final Token terminator) { return until(name, initialSize, stepSize, null, terminator, null); }

/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq} with {@code stepSize = null} and {@code maxSize = null}. */
public static Token until(final String name, final ValueExpression initialSize, final Token terminator, final Encoding encoding) { return until(name, initialSize, null, terminator, encoding); }

/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq} with {@code stepSize = null}, {@code maxSize = null} and {@code encoding = null}. */
public static Token until(final String name, final ValueExpression initialSize, final Token terminator) { return until(name, initialSize, null, terminator, null); }

/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq} with {@code initialSize = null}, {@code stepSize = null} and {@code maxSize = null}. */
public static Token until(final String name, final Token terminator, final Encoding encoding) { return until(name, null, terminator, encoding); }

/** "DEFinition": Instantiates a {@link Until} and its terminator nested in a {@link Seq} with {@code initialSize = null}, {@code stepSize = null}, {@code maxSize = null} and {@code encoding = null}. */
public static Token until(final String name, final Token terminator) { return until(name, terminator, null); }


/** "WHEN": denotes a logical implication, parses the {@code token} only if the {@code predicate} evaluates to {code true} and subsequently only fails if {@code token} does not successfully parse. A composition of {@link Cho} and {@link Pre}. */
public static Token when(final String name, final Token token, final Expression predicate, final Encoding encoding) { return cho(name, encoding, pre(def(EMPTY_NAME, 0), not(predicate)), token); }
Expand Down
8 changes: 6 additions & 2 deletions core/src/main/java/io/parsingdata/metal/token/Until.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
* <code>terminator</code> is made. Parsing fails if no combination of any size
* is found where the <code>terminator</code> parses successfully.
* <p>
* Whether the resulting <code>ParseState</code> includes the parsed
* terminator, depends on the value of the <code>includeTerminator</code>
* argument.
* <p>
* If the <code>ValueExpressions</code> evaluate to lists, they are treated
* as sets of values to attempt. If <code>stepSize</code> is negative,
* <code>maxSize</code> must be smaller than <code>initialSize</code>.
Expand Down Expand Up @@ -114,9 +118,9 @@ private Trampoline<Optional<ParseState>> iterate(final Environment environment,

private Trampoline<Optional<ParseState>> parseSlice(final Environment environment, final BigInteger currentSize, final BigInteger stepSize, final BigInteger maxSize, final Slice slice) {
return (currentSize.compareTo(ZERO) == 0 ? Optional.of(environment.parseState) : environment.parseState.add(new ParseValue(environment.scope, this, slice, environment.encoding)).seek(environment.parseState.offset.add(currentSize)))
.map(preparedParseState -> terminator.parse(environment.withParseState(preparedParseState)))
.map(preparedParseState -> terminator.parse(environment.withParseState(preparedParseState)).map(ignore -> preparedParseState))
.orElseGet(Util::failure)
.map(parsedParseState -> complete(() -> success(parsedParseState)))
.map(parseState -> complete(() -> success(parseState)))
.orElseGet(() -> intermediate(() -> iterate(environment, currentSize.add(stepSize), stepSize, maxSize)));
}

Expand Down
2 changes: 2 additions & 0 deletions core/src/test/java/io/parsingdata/metal/AutoEqualityTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ public class AutoEqualityTest {
private static final List<Supplier<Object>> BIG_INTEGERS = Arrays.asList(() -> ONE, () -> BigInteger.valueOf(3));
private static final List<Supplier<Object>> PARSE_STATES = Arrays.asList(() -> createFromByteStream(DUMMY_STREAM), () -> createFromByteStream(DUMMY_STREAM, ONE), () -> new ParseState(GRAPH_WITH_REFERENCE, DUMMY_BYTE_STREAM_SOURCE, TEN, new ImmutableList<>(), new ImmutableList<>()));
private static final List<Supplier<Object>> IMMUTABLE_LISTS = Arrays.asList(ImmutableList::new, () -> ImmutableList.create("TEST"), () -> ImmutableList.create(1), () -> ImmutableList.create(1).add(2));
private static final List<Supplier<Object>> BOOLEANS = Arrays.asList(() -> true, () -> false);
private static final Map<Class, List<Supplier<Object>>> mapping = buildMap();

private static Map<Class, List<Supplier<Object>>> buildMap() {
Expand All @@ -190,6 +191,7 @@ private static Map<Class, List<Supplier<Object>>> buildMap() {
result.put(BigInteger.class, BIG_INTEGERS);
result.put(ParseState.class, PARSE_STATES);
result.put(ImmutableList.class, IMMUTABLE_LISTS);
result.put(boolean.class, BOOLEANS);
return result;
}

Expand Down
Loading

0 comments on commit ddb1541

Please sign in to comment.