From 4f0a8d9fba1db9785795494045e23bf8c0730572 Mon Sep 17 00:00:00 2001 From: Jeroen van den Bos Date: Tue, 13 Jun 2017 10:24:00 +0200 Subject: [PATCH] #162: Simplified and unified parseImple() and iterate() methods in Token implementations. --- .../java/io/parsingdata/metal/token/Post.java | 10 ++++------ .../java/io/parsingdata/metal/token/Pre.java | 3 +-- .../java/io/parsingdata/metal/token/Rep.java | 11 +++++------ .../java/io/parsingdata/metal/token/RepN.java | 13 ++++++------- .../java/io/parsingdata/metal/token/Seq.java | 13 ++++++------- .../java/io/parsingdata/metal/token/Sub.java | 17 +++++++++-------- .../java/io/parsingdata/metal/token/Tie.java | 12 ++++++------ .../java/io/parsingdata/metal/token/While.java | 15 +++++++-------- 8 files changed, 44 insertions(+), 50 deletions(-) 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 72510c1c..2006f91b 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Post.java +++ b/core/src/main/java/io/parsingdata/metal/token/Post.java @@ -24,6 +24,7 @@ import java.util.Objects; import java.util.Optional; +import io.parsingdata.metal.Util; import io.parsingdata.metal.data.Environment; import io.parsingdata.metal.encoding.Encoding; import io.parsingdata.metal.expression.Expression; @@ -52,12 +53,9 @@ public Post(final String name, final Token token, final Expression predicate, fi @Override 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(); - return predicate.eval(newEnvironment.order, encoding) ? success(newEnvironment.closeBranch()) : failure(); - } - return failure(); + return token.parse(scope, environment.addBranch(this), encoding) + .map(nextEnvironment -> predicate.eval(nextEnvironment.order, encoding) ? success(nextEnvironment.closeBranch()) : failure()) + .orElseGet(Util::failure); } @Override diff --git a/core/src/main/java/io/parsingdata/metal/token/Pre.java b/core/src/main/java/io/parsingdata/metal/token/Pre.java index 15f41088..5c6e3b81 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Pre.java +++ b/core/src/main/java/io/parsingdata/metal/token/Pre.java @@ -57,8 +57,7 @@ protected Optional parseImpl(final String scope, final Environment if (!predicate.eval(environment.order, encoding)) { return failure(); } - final Optional result = token.parse(scope, environment.addBranch(this), encoding); - return result + return token.parse(scope, environment.addBranch(this), encoding) .map(resultEnvironment -> success(resultEnvironment.closeBranch())) .orElseGet(Util::failure); } diff --git a/core/src/main/java/io/parsingdata/metal/token/Rep.java b/core/src/main/java/io/parsingdata/metal/token/Rep.java index fe4c739e..a4f871c0 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Rep.java +++ b/core/src/main/java/io/parsingdata/metal/token/Rep.java @@ -49,14 +49,13 @@ public Rep(final String name, final Token token, final Encoding encoding) { @Override protected Optional parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { - final Environment input = environment.addBranch(this); - return iterate(scope, Optional.of(input), encoding, input).computeResult(); + return iterate(scope, environment.addBranch(this), encoding).computeResult(); } - private Trampoline> iterate(final String scope, final Optional environment, final Encoding encoding, final Environment previous) { - return environment - .map(result -> intermediate(() -> iterate(scope, token.parse(scope, result, encoding), encoding, result))) - .orElseGet(() -> complete(() -> success(previous.closeBranch()))); + private Trampoline> iterate(final String scope, final Environment environment, final Encoding encoding) throws IOException { + return token.parse(scope, environment, encoding) + .map(nextEnvironment -> intermediate(() -> iterate(scope, nextEnvironment, encoding))) + .orElseGet(() -> complete(() -> success(environment.closeBranch()))); } @Override diff --git a/core/src/main/java/io/parsingdata/metal/token/RepN.java b/core/src/main/java/io/parsingdata/metal/token/RepN.java index 0e4d434a..176af28d 100644 --- a/core/src/main/java/io/parsingdata/metal/token/RepN.java +++ b/core/src/main/java/io/parsingdata/metal/token/RepN.java @@ -63,17 +63,16 @@ protected Optional parseImpl(final String scope, final Environment if (counts.size != 1 || !counts.head.isPresent()) { return failure(); } - return iterate(scope, Optional.of(environment.addBranch(this)), encoding, counts.head.get().asNumeric().longValue()).computeResult(); + return iterate(scope, environment.addBranch(this), encoding, counts.head.get().asNumeric().longValue()).computeResult(); } - private Trampoline> iterate(final String scope, final Optional environment, final Encoding encoding, final long count) { - if (!environment.isPresent()) { - return complete(Util::failure); - } + private Trampoline> iterate(final String scope, final Environment environment, final Encoding encoding, final long count) throws IOException { if (count <= 0) { - return complete(() -> success(environment.get().closeBranch())); + return complete(() -> success(environment.closeBranch())); } - return intermediate(() -> iterate(scope, token.parse(scope, environment.get(), encoding), encoding, count - 1)); + return token.parse(scope, environment, encoding) + .map(nextEnvironment -> intermediate(() -> iterate(scope, nextEnvironment, encoding, count - 1))) + .orElseGet(() -> complete(Util::failure)); } @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 371fa158..15194d1e 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Seq.java +++ b/core/src/main/java/io/parsingdata/metal/token/Seq.java @@ -53,17 +53,16 @@ public Seq(final String name, final Encoding encoding, final Token token1, final @Override protected Optional parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { - return iterate(scope, Optional.of(environment.addBranch(this)), encoding, tokens).computeResult(); + return iterate(scope, environment.addBranch(this), encoding, tokens).computeResult(); } - private Trampoline> iterate(final String scope, final Optional environment, final Encoding encoding, final ImmutableList list) { - if (!environment.isPresent()) { - return complete(Util::failure); - } + private Trampoline> iterate(final String scope, final Environment environment, final Encoding encoding, final ImmutableList list) throws IOException { if (list.isEmpty()) { - return complete(() -> success(environment.get().closeBranch())); + return complete(() -> success(environment.closeBranch())); } - return intermediate(() -> iterate(scope, list.head.parse(scope, environment.get(), encoding), encoding, list.tail)); + return list.head.parse(scope, environment, encoding) + .map(nextEnvironment -> intermediate(() -> iterate(scope, nextEnvironment, encoding, list.tail))) + .orElseGet(() -> complete(Util::failure)); } @Override diff --git a/core/src/main/java/io/parsingdata/metal/token/Sub.java b/core/src/main/java/io/parsingdata/metal/token/Sub.java index 79ac7454..23e754ab 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Sub.java +++ b/core/src/main/java/io/parsingdata/metal/token/Sub.java @@ -68,19 +68,20 @@ protected Optional parseImpl(final String scope, final Environment if (addresses.isEmpty()) { return failure(); } - return iterate(scope, addresses, environment.offset, environment.addBranch(this), encoding).computeResult(); + return iterate(scope, addresses, environment.addBranch(this), encoding).computeResult() + .flatMap(nextEnvironment -> success(nextEnvironment.seek(environment.offset))); } - private Trampoline> iterate(final String scope, final ImmutableList> addresses, final long returnOffset, final Environment environment, final Encoding encoding) throws IOException { + private Trampoline> iterate(final String scope, final ImmutableList> addresses, final Environment environment, final Encoding encoding) throws IOException { + if (addresses.isEmpty()) { + return complete(() -> success(environment.closeBranch())); + } if (!addresses.head.isPresent()) { return complete(Util::failure); } - final Optional result = parse(scope, addresses.head.get().asNumeric().longValue(), environment.source, environment, encoding); - if (result.isPresent()) { - if (addresses.tail.isEmpty()) { return complete(() -> success(result.get().closeBranch().seek(returnOffset))); } - return intermediate(() -> iterate(scope, addresses.tail, returnOffset, result.get(), encoding)); - } - return complete(Util::failure); + return parse(scope, addresses.head.get().asNumeric().longValue(), environment.source, environment, encoding) + .map(nextEnvironment -> intermediate(() -> iterate(scope, addresses.tail, nextEnvironment, encoding))) + .orElseGet(() -> complete(Util::failure)); } private Optional parse(final String scope, final long offset, final Source source, final Environment environment, final Encoding encoding) throws IOException { diff --git a/core/src/main/java/io/parsingdata/metal/token/Tie.java b/core/src/main/java/io/parsingdata/metal/token/Tie.java index 714c3b89..1f4389ea 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Tie.java +++ b/core/src/main/java/io/parsingdata/metal/token/Tie.java @@ -69,15 +69,15 @@ protected Optional parseImpl(final String scope, final Environment } private Trampoline> iterate(final String scope, final ImmutableList> values, final int index, final Environment returnEnvironment, final Environment environment, final Encoding encoding) throws IOException { + if (values.isEmpty()) { + return complete(() -> success(new Environment(environment.closeBranch().order, returnEnvironment.source, returnEnvironment.offset, returnEnvironment.callbacks))); + } if (!values.head.isPresent()) { return complete(Util::failure); } - final Optional result = token.parse(scope, environment.source(dataExpression, index, environment, encoding), encoding); - if (result.isPresent()) { - if (values.tail.isEmpty()) { return complete(() -> success(new Environment(result.get().closeBranch().order, returnEnvironment.source, returnEnvironment.offset, returnEnvironment.callbacks))); } - return intermediate(() -> iterate(scope, values.tail, index + 1, returnEnvironment, result.get(), encoding)); - } - return complete(Util::failure); + return token.parse(scope, environment.source(dataExpression, index, environment, encoding), encoding) + .map(nextEnvironment -> intermediate(() -> iterate(scope, values.tail, index + 1, returnEnvironment, nextEnvironment, encoding))) + .orElseGet(() -> complete(Util::failure)); } @Override diff --git a/core/src/main/java/io/parsingdata/metal/token/While.java b/core/src/main/java/io/parsingdata/metal/token/While.java index 6ed01e86..8608c3c7 100644 --- a/core/src/main/java/io/parsingdata/metal/token/While.java +++ b/core/src/main/java/io/parsingdata/metal/token/While.java @@ -58,17 +58,16 @@ public While(final String name, final Token token, final Expression predicate, f @Override protected Optional parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { - return iterate(scope, Optional.of(environment.addBranch(this)), encoding).computeResult(); + return iterate(scope, environment.addBranch(this), encoding).computeResult(); } - private Trampoline> iterate(final String scope, final Optional environment, final Encoding encoding) { - if (!environment.isPresent()) { - return complete(Util::failure); + private Trampoline> iterate(final String scope, final Environment environment, final Encoding encoding) throws IOException { + if (predicate.eval(environment.order, encoding)) { + return token.parse(scope, environment, encoding) + .map(nextEnvironment -> intermediate(() -> iterate(scope, nextEnvironment, encoding))) + .orElseGet(() -> complete(Util::failure)); } - if (predicate.eval(environment.get().order, encoding)) { - return intermediate(() -> iterate(scope, token.parse(scope, environment.get(), encoding), encoding)); - } - return complete(() -> success(environment.get().closeBranch())); + return complete(() -> success(environment.closeBranch())); } @Override