Ensure that lex and parse methods are only called once per instance

This commit is contained in:
Riccardo Azzolini 2019-09-09 18:32:18 +02:00
parent c37f7f52b3
commit 12406c787b
4 changed files with 31 additions and 0 deletions

View File

@ -29,6 +29,7 @@ public class Lexer {
private final String source;
private final Consumer<? super DslError> errorReporter;
private boolean used = false;
private final List<Token> tokens = new ArrayList<>();
private int startOfLexeme = 0;
private int curPosition = 0;
@ -55,8 +56,14 @@ public class Lexer {
* If any errors are reported, this list should not be considered to represent a valid set of DSL rules,
* but it can still be parsed to potentially find additional errors (which may allow the user to fix more
* errors before having to rerun the <code>Lexer</code>).
* @throws IllegalStateException if called multiple times on the same instance.
*/
public List<Token> lex() {
if (used) {
throw new IllegalStateException("Lexer.lex can only be called once per instance");
}
used = true;
while (!atEnd()) {
startOfLexeme = curPosition;
lexAndHandleErrors();

View File

@ -29,6 +29,7 @@ public class Parser {
private final List<Token> tokens;
private final Consumer<? super DslError> errorReporter;
private boolean used = false;
private int currentIndex = 0;
// For error reporting
@ -57,8 +58,14 @@ public class Parser {
* but each rule can still be analyzed to look for undefined sub-functions in replacement patterns and
* report them (which may allow the user to fix more errors before having to rerun the <code>Lexer</code>
* and <code>Parser</code>).
* @throws IllegalStateException if called multiple times on the same instance.
*/
public List<PatternRule> parse() {
if (used) {
throw new IllegalStateException("Parser.parse can only be called once per instance");
}
used = true;
return rules();
}

View File

@ -29,6 +29,13 @@ class LexerTest {
assertEquals(expected, lexer.lex());
}
@Test
void multipleLexCalls() {
final Lexer lexer = new Lexer("", errors::add);
lexer.lex();
assertThrows(IllegalStateException.class, lexer::lex);
}
@Test
void validRule() {
final Lexer lexer = new Lexer(

View File

@ -38,6 +38,16 @@ class ParserTest {
assertEquals(Collections.emptyList(), parser.parse());
}
@Test
void multipleParseCalls() {
final List<Token> tokens = Collections.singletonList(
new Token(EOF, "", 0)
);
final Parser parser = new Parser(tokens, errors::add);
parser.parse();
assertThrows(IllegalStateException.class, parser::parse);
}
@Test
void validRuleMultipleReplacements() {
final List<Token> tokens = Arrays.asList(