diff --git a/core/src/main/java/io/parsingdata/metal/token/Token.java b/core/src/main/java/io/parsingdata/metal/token/Token.java index 6a23bf46..c1a1fa0c 100644 --- a/core/src/main/java/io/parsingdata/metal/token/Token.java +++ b/core/src/main/java/io/parsingdata/metal/token/Token.java @@ -80,7 +80,7 @@ private String makeScope(final String scope) { public boolean isLocal() { return true; } - public Token getCanonical(final Environment environment) { return this; } + public Token getCanonical(final Environment environment) throws IOException { return this; } protected String makeNameFragment() { return name.isEmpty() ? NO_NAME : name + ","; diff --git a/core/src/main/java/io/parsingdata/metal/token/TokenRef.java b/core/src/main/java/io/parsingdata/metal/token/TokenRef.java index 989e5a82..374114ce 100644 --- a/core/src/main/java/io/parsingdata/metal/token/TokenRef.java +++ b/core/src/main/java/io/parsingdata/metal/token/TokenRef.java @@ -16,6 +16,8 @@ package io.parsingdata.metal.token; +import static io.parsingdata.metal.Trampoline.complete; +import static io.parsingdata.metal.Trampoline.intermediate; import static io.parsingdata.metal.Util.checkNotNull; import static io.parsingdata.metal.Util.failure; @@ -23,6 +25,7 @@ import java.util.Objects; import java.util.Optional; +import io.parsingdata.metal.Trampoline; import io.parsingdata.metal.data.Environment; import io.parsingdata.metal.data.ParseItem; import io.parsingdata.metal.encoding.Encoding; @@ -60,22 +63,22 @@ public TokenRef(final String name, final String referenceName, final Encoding en @Override protected Optional parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { - return lookup(environment.order, referenceName).parse(scope, environment, encoding); + return lookup(environment.order, referenceName).computeResult().parse(scope, environment, encoding); } - private Token lookup(final ParseItem item, final String referenceName) { + private Trampoline lookup(final ParseItem item, final String referenceName) throws IOException { if (item.getDefinition().name.equals(referenceName)) { - return item.getDefinition(); + return complete(() -> item.getDefinition()); } - if (!item.isGraph() || item.asGraph().isEmpty()) { return LOOKUP_FAILED; } - final Token headResult = lookup(item.asGraph().head, referenceName); - if (headResult != LOOKUP_FAILED) { return headResult; } - return lookup(item.asGraph().tail, referenceName); + if (!item.isGraph() || item.asGraph().isEmpty()) { return complete(() -> LOOKUP_FAILED); } + final Token headResult = lookup(item.asGraph().head, referenceName).computeResult(); + if (headResult != LOOKUP_FAILED) { return complete(() -> headResult); } + return intermediate(() -> lookup(item.asGraph().tail, referenceName)); } @Override - public Token getCanonical(final Environment environment) { - return lookup(environment.order, referenceName); + public Token getCanonical(final Environment environment) throws IOException { + return lookup(environment.order, referenceName).computeResult(); } @Override