Correctly handle and report unterminated multiline comments in Lexer

This commit is contained in:
Riccardo Azzolini 2019-02-11 16:31:03 +01:00
parent e86a7a6346
commit 04d01565da
3 changed files with 60 additions and 1 deletions

View File

@ -139,8 +139,11 @@ public class Lexer {
matchWhile(c -> c != '\n');
}
private void multiLineComment() {
private void multiLineComment() throws SyntaxException {
while (!(matchChar('*') && matchChar('/'))) {
if (atEnd()) {
throw new SyntaxException(new UnterminatedComment(startOfLexeme));
}
popChar();
}
}

View File

@ -0,0 +1,40 @@
package it.cavallium.warppi.math.rules.dsl.frontend;
import it.cavallium.warppi.math.rules.dsl.DslError;
import java.util.Objects;
/**
* Occurs when DSL source code contains a multiline comment which is never terminated (closed).
*/
public class UnterminatedComment implements DslError {
private final int position;
public UnterminatedComment(final int position) {
this.position = position;
}
@Override
public int getPosition() {
return position;
}
@Override
public int getLength() {
return 2; // Length of comment start marker: "/*"
}
@Override
public boolean equals(final Object o) {
if (!(o instanceof UnterminatedComment)) {
return false;
}
final UnterminatedComment other = (UnterminatedComment) o;
return this.position == other.position;
}
@Override
public int hashCode() {
return Objects.hash(position);
}
}

View File

@ -127,6 +127,22 @@ public class LexerTest {
assertEquals(expectedErrors, errors);
}
@Test
public void unterminatedComment() {
final Lexer lexer = new Lexer("reduction /* test:\n x -> x", errors::add);
final List<Token> expectedTokens = Arrays.asList(
new Token(REDUCTION, "reduction", 0),
new Token(EOF, "", 26)
);
assertEquals(expectedTokens, lexer.lex());
final List<DslError> expectedErrors = Collections.singletonList(
new UnterminatedComment(10)
);
assertEquals(expectedErrors, errors);
}
@Test
public void errorOrder() {
final Lexer lexer = new Lexer(".2. @", errors::add);