From cea3e47938322b97c318dea38dc0d649e196dc1b Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Tue, 16 Aug 2022 23:03:27 -0400 Subject: Refactor to add backtracking support This probably doesn't help w/ error messages, but it enables some cool ideas where syntax can be reused in cases where it would otherwise be invalid --- .../main/java/bjc/pratt/tokens/TokenStream.java | 56 +++++++++++----------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'JPratt/src/main/java/bjc/pratt/tokens/TokenStream.java') diff --git a/JPratt/src/main/java/bjc/pratt/tokens/TokenStream.java b/JPratt/src/main/java/bjc/pratt/tokens/TokenStream.java index 1c550de..dc09bcc 100644 --- a/JPratt/src/main/java/bjc/pratt/tokens/TokenStream.java +++ b/JPratt/src/main/java/bjc/pratt/tokens/TokenStream.java @@ -6,7 +6,6 @@ import java.util.Iterator; import java.util.Set; import bjc.utils.funcutils.StringUtils; -import bjc.utils.parserutils.ParserException; /** * A stream of tokens. @@ -20,26 +19,6 @@ import bjc.utils.parserutils.ParserException; * The value type of the token. */ public abstract class TokenStream implements Iterator> { - /** - * The exception thrown when an expectation fails. - * - * @author EVE - * - */ - public static class ExpectationException extends ParserException { - private static final long serialVersionUID = 4299299480127680805L; - - /** - * Create a new exception with the specified message. - * - * @param msg - * The message of the exception. - */ - public ExpectationException(final String msg) { - super(msg); - } - } - /** * Get the current token. * @@ -53,6 +32,28 @@ public abstract class TokenStream implements Iterator> { @Override public abstract boolean hasNext(); + /** + * Place a mark in the current stream, which can be either returned to or abandoned later on. + */ + public abstract void mark(); + + /** + * Reset the stream to the state it was in when the last mark was taken. + */ + public abstract void rollback(); + + /** + * Check if the stream has at least one mark. + * + * @return Whether or not at least one mark exists. + */ + public abstract boolean hasMark(); + + /** + * Remove the last mark placed into the stream. This prevents returning to it later on. + */ + public abstract void commit(); + /** * Utility method for checking that the next token is one of a specific * set of types, and then consuming it. @@ -60,16 +61,16 @@ public abstract class TokenStream implements Iterator> { * @param expectedKeys * The expected values * - * @throws ExpectationException + * @throws ExpectionNotMet * If the token is not one of the expected types. */ - public void expect(final Set expectedKeys) throws ExpectationException { + public void expect(final Set expectedKeys) throws ExpectionNotMet { final K curKey = current().getKey(); if(!expectedKeys.contains(curKey)) { final String expectedList = StringUtils.toEnglishList(expectedKeys.toArray(), false); - throw new ExpectationException("One of '" + expectedList + "' was expected, not " + curKey); + throw new ExpectionNotMet("One of '" + expectedList + "' was expected, not " + curKey); } next(); @@ -82,12 +83,13 @@ public abstract class TokenStream implements Iterator> { * @param expectedKeys * The expected values * - * @throws ExpectationException + * @throws ExpectionNotMet * If the token is not one of the expected types. */ @SafeVarargs - public final void expect(final K... expectedKeys) throws ExpectationException { - expect(new HashSet<>(Arrays.asList(expectedKeys))); + public final void expect(final K... expectedKeys) throws ExpectionNotMet { + HashSet keys = new HashSet<>(Arrays.asList(expectedKeys)); + expect(keys); } /** -- cgit v1.2.3