diff options
Diffstat (limited to 'JPratt/src/main/java/bjc/pratt/tokens')
3 files changed, 82 insertions, 31 deletions
diff --git a/JPratt/src/main/java/bjc/pratt/tokens/ExpectionNotMet.java b/JPratt/src/main/java/bjc/pratt/tokens/ExpectionNotMet.java new file mode 100644 index 0000000..2bd45e2 --- /dev/null +++ b/JPratt/src/main/java/bjc/pratt/tokens/ExpectionNotMet.java @@ -0,0 +1,23 @@ +package bjc.pratt.tokens; + +import bjc.utils.parserutils.ParserException; + +/** + * The exception thrown when an expectation fails. + * + * @author EVE + * + */ +public class ExpectionNotMet extends ParserException { + private static final long serialVersionUID = 4299299480127680805L; + + /** + * Create a new exception with the specified message. + * + * @param msg + * The message of the exception. + */ + public ExpectionNotMet(final String msg) { + super(msg); + } +}
\ No newline at end of file diff --git a/JPratt/src/main/java/bjc/pratt/tokens/StringTokenStream.java b/JPratt/src/main/java/bjc/pratt/tokens/StringTokenStream.java index 044d19a..8c7fcec 100644 --- a/JPratt/src/main/java/bjc/pratt/tokens/StringTokenStream.java +++ b/JPratt/src/main/java/bjc/pratt/tokens/StringTokenStream.java @@ -4,6 +4,8 @@ import static bjc.pratt.tokens.StringToken.litToken; import java.util.Iterator; +import bjc.data.MarkListIterator; + /** * Simple implementation of token stream for strings. * @@ -14,8 +16,8 @@ import java.util.Iterator; * */ public class StringTokenStream extends TokenStream<String, String> { - private final Iterator<Token<String, String>> iter; - + private final MarkListIterator<Token<String, String>> iter; + private Token<String, String> curr; /** @@ -26,8 +28,7 @@ public class StringTokenStream extends TokenStream<String, String> { * */ public StringTokenStream(final Iterator<Token<String, String>> itr) { - iter = itr; - + iter = new MarkListIterator<>(itr); } @Override @@ -50,4 +51,29 @@ public class StringTokenStream extends TokenStream<String, String> { public boolean hasNext() { return iter.hasNext(); } + + @Override + public void mark() { + iter.mark(); + } + + @Override + public void commit() { + iter.commit(); + + if (!iter.hasMark()) { + // No marks outstanding; we can release the previous state + iter.reset(); + } + } + + @Override + public void rollback() { + iter.rollback(); + } + + @Override + public boolean hasMark() { + return iter.hasMark(); + } } 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. @@ -21,26 +20,6 @@ import bjc.utils.parserutils.ParserException; */ public abstract class TokenStream<K, V> implements Iterator<Token<K, V>> { /** - * 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. * * @return The current token. @@ -54,22 +33,44 @@ public abstract class TokenStream<K, V> implements Iterator<Token<K, V>> { 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. * * @param expectedKeys * The expected values * - * @throws ExpectationException + * @throws ExpectionNotMet * If the token is not one of the expected types. */ - public void expect(final Set<K> expectedKeys) throws ExpectationException { + public void expect(final Set<K> 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<K, V> implements Iterator<Token<K, V>> { * @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<K> keys = new HashSet<>(Arrays.asList(expectedKeys)); + expect(keys); } /** |
