Replace DslException with the DslError interface and the SyntaxException wrapper
This commit is contained in:
parent
0d89711772
commit
ebbf8b013a
@ -5,23 +5,23 @@ import java.util.List;
|
||||
/**
|
||||
* Thrown when processing DSL code which contains one or more errors.
|
||||
*
|
||||
* Contains a list of {@link DslException}s, which should not be empty.
|
||||
* Contains a list of {@link DslError}s, which should not be empty.
|
||||
*/
|
||||
public class DslAggregateException extends Exception {
|
||||
private final List<DslException> exceptions;
|
||||
private final List<DslError> errors;
|
||||
|
||||
/**
|
||||
* Constructs a <code>DslAggregateException</code> containing the specified list of exceptions.
|
||||
* @param exceptions The list of exceptions. Should not be empty.
|
||||
* Constructs a <code>DslAggregateException</code> containing the specified list of errors.
|
||||
* @param errors The list of errors. Should not be empty.
|
||||
*/
|
||||
public DslAggregateException(final List<DslException> exceptions) {
|
||||
this.exceptions = exceptions;
|
||||
public DslAggregateException(final List<DslError> errors) {
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The list of errors detected in the DSL code.
|
||||
*/
|
||||
public List<DslException> getExceptions() {
|
||||
return exceptions;
|
||||
public List<DslError> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package it.cavallium.warppi.math.rules.dsl;
|
||||
|
||||
/**
|
||||
* The superclass of all exceptions which represent errors in DSL code.
|
||||
* Represents an error in DSL code.
|
||||
*/
|
||||
public abstract class DslException extends Exception {
|
||||
public interface DslError {
|
||||
/**
|
||||
* @return The index at which the error starts in the source string.
|
||||
*/
|
||||
public abstract int getPosition();
|
||||
int getPosition();
|
||||
|
||||
/**
|
||||
* @return The length of the error in the source string.
|
||||
*/
|
||||
public abstract int getLength();
|
||||
int getLength();
|
||||
}
|
@ -11,7 +11,7 @@ public class RulesDsl {
|
||||
private RulesDsl() {}
|
||||
|
||||
public static List<Rule> makeRules(final String source) throws DslAggregateException {
|
||||
final List<DslException> errors = new ArrayList<>();
|
||||
final List<DslError> errors = new ArrayList<>();
|
||||
|
||||
final Lexer lexer = new Lexer(source, errors::add);
|
||||
final Parser parser = new Parser(lexer.lex(), errors::add);
|
||||
@ -20,7 +20,7 @@ public class RulesDsl {
|
||||
for (final PatternRule rule : rules) {
|
||||
undefinedSubFunctions(rule).stream()
|
||||
.flatMap(subFunc -> parser.getSubFunctionIdentifiers(rule.getRuleName(), subFunc).stream())
|
||||
.map(UndefinedSubFunctionException::new)
|
||||
.map(UndefinedSubFunction::new)
|
||||
.forEach(errors::add);
|
||||
}
|
||||
|
||||
|
@ -3,13 +3,13 @@ package it.cavallium.warppi.math.rules.dsl;
|
||||
import it.cavallium.warppi.math.rules.dsl.frontend.Token;
|
||||
|
||||
/**
|
||||
* Thrown when a sub-function is used in one of the replacement pattern of a <code>PatternRule</code>,
|
||||
* Occurs when a sub-function is used in one of the replacement pattern of a <code>PatternRule</code>,
|
||||
* but not defined (captured) in the target pattern.
|
||||
*/
|
||||
public class UndefinedSubFunctionException extends DslException {
|
||||
public class UndefinedSubFunction implements DslError {
|
||||
private final Token identifier;
|
||||
|
||||
public UndefinedSubFunctionException(final Token identifier) {
|
||||
public UndefinedSubFunction(final Token identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslException;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Thrown when DSL source code contains a number literal with a decimal separator which is not followed by digits.
|
||||
* Occurs when DSL source code contains a number literal with a decimal separator which is not followed by digits.
|
||||
* <p>
|
||||
* An example of an incomplete literal is <code>2.</code>, while <code>2</code> and <code>2.2</code> are valid.
|
||||
*/
|
||||
public class IncompleteNumberLiteralException extends DslException {
|
||||
public class IncompleteNumberLiteral implements DslError {
|
||||
private final int position;
|
||||
private final String literal;
|
||||
|
||||
public IncompleteNumberLiteralException(final int position, final String literal) {
|
||||
public IncompleteNumberLiteral(final int position, final String literal) {
|
||||
this.position = position;
|
||||
this.literal = literal;
|
||||
}
|
||||
@ -37,10 +37,10 @@ public class IncompleteNumberLiteralException extends DslException {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (!(o instanceof IncompleteNumberLiteralException)) {
|
||||
if (!(o instanceof IncompleteNumberLiteral)) {
|
||||
return false;
|
||||
}
|
||||
final IncompleteNumberLiteralException other = (IncompleteNumberLiteralException) o;
|
||||
final IncompleteNumberLiteral other = (IncompleteNumberLiteral) o;
|
||||
return this.position == other.position && this.literal.equals(other.literal);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslException;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -27,14 +27,14 @@ public class Lexer {
|
||||
));
|
||||
|
||||
private final String source;
|
||||
private final Consumer<? super DslException> errorReporter;
|
||||
private final Consumer<? super DslError> errorReporter;
|
||||
|
||||
private final List<Token> tokens = new ArrayList<>();
|
||||
private int startOfLexeme = 0;
|
||||
private int curPosition = 0;
|
||||
private UnexpectedCharactersException unexpectedCharacters = null;
|
||||
private UnexpectedCharacters unexpectedCharacters = null;
|
||||
|
||||
public Lexer(final String source, final Consumer<? super DslException> errorReporter) {
|
||||
public Lexer(final String source, final Consumer<? super DslError> errorReporter) {
|
||||
this.source = source;
|
||||
this.errorReporter = errorReporter;
|
||||
}
|
||||
@ -55,16 +55,23 @@ public class Lexer {
|
||||
try {
|
||||
lexToken();
|
||||
reportAndClearUnexpectedCharacters(); // After finding some expected characters
|
||||
} catch (UnexpectedCharactersException e) {
|
||||
if (unexpectedCharacters == null) {
|
||||
unexpectedCharacters = e;
|
||||
} catch (final SyntaxException e) {
|
||||
final DslError error = e.getError();
|
||||
if (error instanceof UnexpectedCharacters) {
|
||||
addUnexpectedCharacters((UnexpectedCharacters) error);
|
||||
} else {
|
||||
unexpectedCharacters = unexpectedCharacters.concat(e);
|
||||
// If there are multiple errors, report them in the order in which they occur in the source
|
||||
reportAndClearUnexpectedCharacters();
|
||||
errorReporter.accept(error);
|
||||
}
|
||||
} catch (IncompleteNumberLiteralException e) {
|
||||
// If there are multiple errors, report them in the order in which they occur in the source
|
||||
reportAndClearUnexpectedCharacters();
|
||||
errorReporter.accept(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addUnexpectedCharacters(final UnexpectedCharacters unexpected) {
|
||||
if (unexpectedCharacters == null) {
|
||||
unexpectedCharacters = unexpected;
|
||||
} else {
|
||||
unexpectedCharacters = unexpectedCharacters.concat(unexpected);
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +83,7 @@ public class Lexer {
|
||||
unexpectedCharacters = null;
|
||||
}
|
||||
|
||||
private void lexToken() throws UnexpectedCharactersException, IncompleteNumberLiteralException {
|
||||
private void lexToken() throws SyntaxException {
|
||||
char current = popChar();
|
||||
switch (current) {
|
||||
case ':': emitToken(COLON); break;
|
||||
@ -121,7 +128,9 @@ public class Lexer {
|
||||
} else if (Character.isJavaIdentifierStart(current)) {
|
||||
keywordOrIdentifier();
|
||||
} else if (!Character.isWhitespace(current)) {
|
||||
throw new UnexpectedCharactersException(curPosition - 1, String.valueOf(current));
|
||||
throw new SyntaxException(
|
||||
new UnexpectedCharacters(curPosition - 1, String.valueOf(current))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,10 +145,12 @@ public class Lexer {
|
||||
}
|
||||
}
|
||||
|
||||
private void number() throws IncompleteNumberLiteralException {
|
||||
private void number() throws SyntaxException {
|
||||
matchWhile(Lexer::isAsciiDigit);
|
||||
if (matchChar('.') && matchWhile(Lexer::isAsciiDigit) == 0) {
|
||||
throw new IncompleteNumberLiteralException(startOfLexeme, currentLexeme());
|
||||
throw new SyntaxException(
|
||||
new IncompleteNumberLiteral(startOfLexeme, currentLexeme())
|
||||
);
|
||||
}
|
||||
emitToken(NUMBER);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.MathematicalSymbols;
|
||||
import it.cavallium.warppi.math.rules.RuleType;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslException;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
import it.cavallium.warppi.math.rules.dsl.Pattern;
|
||||
import it.cavallium.warppi.math.rules.dsl.PatternRule;
|
||||
import it.cavallium.warppi.math.rules.dsl.patterns.*;
|
||||
@ -27,14 +27,14 @@ public class Parser {
|
||||
);
|
||||
|
||||
private final List<Token> tokens;
|
||||
private final Consumer<? super DslException> errorReporter;
|
||||
private final Consumer<? super DslError> errorReporter;
|
||||
private int current = 0;
|
||||
|
||||
// For error reporting
|
||||
private String currentRuleName;
|
||||
private final Map<String, Map<SubFunctionPattern, List<Token>>> subFunctionIdentifiers = new HashMap<>();
|
||||
|
||||
public Parser(final List<Token> tokens, final Consumer<? super DslException> errorReporter) {
|
||||
public Parser(final List<Token> tokens, final Consumer<? super DslError> errorReporter) {
|
||||
this.tokens = tokens;
|
||||
this.errorReporter = errorReporter;
|
||||
}
|
||||
@ -53,8 +53,8 @@ public class Parser {
|
||||
while (!atEnd()) {
|
||||
try {
|
||||
rules.add(rule());
|
||||
} catch (UnexpectedTokenException e) {
|
||||
errorReporter.accept(e);
|
||||
} catch (final SyntaxException e) {
|
||||
errorReporter.accept(e.getError());
|
||||
synchronizeTo(ruleTypes.keySet()); // Skip to the next rule to minimize "false" errors
|
||||
}
|
||||
}
|
||||
@ -64,7 +64,7 @@ public class Parser {
|
||||
// rule = rule header , rule body ;
|
||||
// rule header = rule type , IDENTIFIER , COLON ;
|
||||
// rule body = pattern , ARROW , replacements ;
|
||||
private PatternRule rule() throws UnexpectedTokenException {
|
||||
private PatternRule rule() throws SyntaxException {
|
||||
final RuleType type = ruleType();
|
||||
final String name = matchOrFail(IDENTIFIER).lexeme;
|
||||
currentRuleName = name; // This field must be set before calling pattern() and replacements()
|
||||
@ -76,23 +76,25 @@ public class Parser {
|
||||
}
|
||||
|
||||
// rule type = REDUCTION | EXPANSION | CALCULATION | EXISTENCE ;
|
||||
private RuleType ruleType() throws UnexpectedTokenException {
|
||||
private RuleType ruleType() throws SyntaxException {
|
||||
final Token curToken = pop();
|
||||
if (!ruleTypes.containsKey(curToken.type)) {
|
||||
throw new UnexpectedTokenException(curToken, ruleTypes.keySet());
|
||||
throw new SyntaxException(
|
||||
new UnexpectedToken(curToken, ruleTypes.keySet())
|
||||
);
|
||||
}
|
||||
return ruleTypes.get(curToken.type);
|
||||
}
|
||||
|
||||
// pattern = equation ;
|
||||
private Pattern pattern() throws UnexpectedTokenException {
|
||||
private Pattern pattern() throws SyntaxException {
|
||||
return equation();
|
||||
}
|
||||
|
||||
// replacements = pattern
|
||||
// | LEFT_BRACKET , patterns , RIGHT_BRACKET ;
|
||||
// patterns = [ pattern , { COMMA , pattern } , [ COMMA ] ] ;
|
||||
private List<Pattern> replacements() throws UnexpectedTokenException {
|
||||
private List<Pattern> replacements() throws SyntaxException {
|
||||
if (match(LEFT_BRACKET) == null) {
|
||||
return Collections.singletonList(pattern());
|
||||
}
|
||||
@ -110,7 +112,7 @@ public class Parser {
|
||||
}
|
||||
|
||||
// equation = sum , [ EQUALS , sum ] ;
|
||||
private Pattern equation() throws UnexpectedTokenException {
|
||||
private Pattern equation() throws SyntaxException {
|
||||
Pattern pat = sum();
|
||||
if (match(EQUALS) != null) {
|
||||
pat = new EquationPattern(pat, sum());
|
||||
@ -119,7 +121,7 @@ public class Parser {
|
||||
}
|
||||
|
||||
// sum = product , { ( PLUS | MINUS | PLUS_MINUS ) product } ;
|
||||
private Pattern sum() throws UnexpectedTokenException {
|
||||
private Pattern sum() throws SyntaxException {
|
||||
return matchLeftAssoc(this::product, Map.ofEntries(
|
||||
Map.entry(PLUS, SumPattern::new),
|
||||
Map.entry(MINUS, SubtractionPattern::new),
|
||||
@ -128,7 +130,7 @@ public class Parser {
|
||||
}
|
||||
|
||||
// product = unary , { ( TIMES | DIVIDE ) unary } ;
|
||||
private Pattern product() throws UnexpectedTokenException {
|
||||
private Pattern product() throws SyntaxException {
|
||||
return matchLeftAssoc(this::unary, Map.ofEntries(
|
||||
Map.entry(TIMES, MultiplicationPattern::new),
|
||||
Map.entry(DIVIDE, DivisionPattern::new)
|
||||
@ -137,7 +139,7 @@ public class Parser {
|
||||
|
||||
// unary = ( PLUS | MINUS ) unary
|
||||
// | power ;
|
||||
private Pattern unary() throws UnexpectedTokenException {
|
||||
private Pattern unary() throws SyntaxException {
|
||||
if (match(PLUS) != null) {
|
||||
return unary();
|
||||
} else if (match(MINUS) != null) {
|
||||
@ -148,7 +150,7 @@ public class Parser {
|
||||
}
|
||||
|
||||
// power = ( function | primary ) , [ POWER , power ] ;
|
||||
private Pattern power() throws UnexpectedTokenException {
|
||||
private Pattern power() throws SyntaxException {
|
||||
Pattern pat = functionOrPrimary();
|
||||
if (match(POWER) != null) {
|
||||
pat = new PowerPattern(pat, power());
|
||||
@ -156,14 +158,14 @@ public class Parser {
|
||||
return pat;
|
||||
}
|
||||
|
||||
private Pattern functionOrPrimary() throws UnexpectedTokenException {
|
||||
private Pattern functionOrPrimary() throws SyntaxException {
|
||||
final Pattern function = tryFunction();
|
||||
return function != null ? function : primary();
|
||||
}
|
||||
|
||||
// function = ( ARCCOS | ARCSIN | ARCTAN | COS | SIN | SQRT | TAN ) , LEFT_PAREN , sum , RIGHT_PAREN
|
||||
// | ( LOG | ROOT ) LEFT_PAREN , sum , COMMA , sum , RIGHT_PAREN ;
|
||||
private Pattern tryFunction() throws UnexpectedTokenException {
|
||||
private Pattern tryFunction() throws SyntaxException {
|
||||
final Map<TokenType, Function<Pattern, Pattern>> oneArg = Map.ofEntries(
|
||||
Map.entry(ARCCOS, ArcCosinePattern::new),
|
||||
Map.entry(ARCSIN, ArcSinePattern::new),
|
||||
@ -190,14 +192,14 @@ public class Parser {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Pattern oneArgFunction(final Function<Pattern, Pattern> constructor) throws UnexpectedTokenException {
|
||||
private Pattern oneArgFunction(final Function<Pattern, Pattern> constructor) throws SyntaxException {
|
||||
matchOrFail(LEFT_PAREN);
|
||||
final Pattern arg = pattern();
|
||||
matchOrFail(RIGHT_PAREN);
|
||||
return constructor.apply(arg);
|
||||
}
|
||||
|
||||
private Pattern twoArgFunction(final BiFunction<Pattern, Pattern, Pattern> constructor) throws UnexpectedTokenException {
|
||||
private Pattern twoArgFunction(final BiFunction<Pattern, Pattern, Pattern> constructor) throws SyntaxException {
|
||||
matchOrFail(LEFT_PAREN);
|
||||
final Pattern firstArg = pattern();
|
||||
matchOrFail(COMMA);
|
||||
@ -209,7 +211,7 @@ public class Parser {
|
||||
// primary = NUMBER | constant | IDENTIFIER | UNDEFINED
|
||||
// | LEFT_PAREN sum RIGHT_PAREN ;
|
||||
// constant = PI | E ;
|
||||
private Pattern primary() throws UnexpectedTokenException {
|
||||
private Pattern primary() throws SyntaxException {
|
||||
final Token curToken = pop();
|
||||
switch (curToken.type) {
|
||||
case PI:
|
||||
@ -229,7 +231,7 @@ public class Parser {
|
||||
matchOrFail(RIGHT_PAREN);
|
||||
return grouped;
|
||||
}
|
||||
throw new UnexpectedTokenException(curToken);
|
||||
throw new SyntaxException(new UnexpectedToken(curToken));
|
||||
}
|
||||
|
||||
private void saveSubFunctionIdentifier(final SubFunctionPattern subFunction, final Token curToken) {
|
||||
@ -247,7 +249,7 @@ public class Parser {
|
||||
private Pattern matchLeftAssoc(
|
||||
final PatternParser operandParser,
|
||||
final Map<TokenType, BiFunction<Pattern, Pattern, Pattern>> operators
|
||||
) throws UnexpectedTokenException {
|
||||
) throws SyntaxException {
|
||||
Pattern pat = operandParser.parse();
|
||||
while (operators.containsKey(peek().type)) {
|
||||
final Token operatorToken = pop();
|
||||
@ -257,10 +259,12 @@ public class Parser {
|
||||
return pat;
|
||||
}
|
||||
|
||||
private Token matchOrFail(final TokenType expectedType) throws UnexpectedTokenException {
|
||||
private Token matchOrFail(final TokenType expectedType) throws SyntaxException {
|
||||
final Token matched = match(expectedType);
|
||||
if (matched == null) {
|
||||
throw new UnexpectedTokenException(tokens.get(current), expectedType);
|
||||
throw new SyntaxException(
|
||||
new UnexpectedToken(tokens.get(current), expectedType)
|
||||
);
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
@ -280,10 +284,10 @@ public class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
private Token pop() throws UnexpectedTokenException {
|
||||
private Token pop() throws SyntaxException {
|
||||
final Token curToken = tokens.get(current);
|
||||
if (atEnd()) {
|
||||
throw new UnexpectedTokenException(curToken); // Avoid popping EOF
|
||||
throw new SyntaxException(new UnexpectedToken(curToken)); // Avoid popping EOF
|
||||
}
|
||||
current++;
|
||||
return curToken;
|
||||
@ -299,6 +303,6 @@ public class Parser {
|
||||
|
||||
@FunctionalInterface
|
||||
private interface PatternParser {
|
||||
Pattern parse() throws UnexpectedTokenException;
|
||||
Pattern parse() throws SyntaxException;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
|
||||
/**
|
||||
* Thrown when DSL source code contains a syntax error.
|
||||
* <p>
|
||||
* Used for error reporting and recovery in the implementation of {@link Lexer} and {@link Parser}.
|
||||
*/
|
||||
class SyntaxException extends Exception {
|
||||
private final DslError error;
|
||||
|
||||
SyntaxException(final DslError error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public DslError getError() {
|
||||
return error;
|
||||
}
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslException;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Thrown when DSL source code contains one or more (consecutive) characters which are not expected by the lexer.
|
||||
* Occurs when DSL source code contains one or more (consecutive) characters which are not expected by the lexer.
|
||||
*/
|
||||
public class UnexpectedCharactersException extends DslException {
|
||||
public class UnexpectedCharacters implements DslError {
|
||||
private final int position;
|
||||
private final String unexpectedCharacters;
|
||||
|
||||
public UnexpectedCharactersException(final int position, final String unexpectedCharacters) {
|
||||
public UnexpectedCharacters(final int position, final String unexpectedCharacters) {
|
||||
this.position = position;
|
||||
this.unexpectedCharacters = unexpectedCharacters;
|
||||
}
|
||||
@ -33,16 +33,16 @@ public class UnexpectedCharactersException extends DslException {
|
||||
return unexpectedCharacters;
|
||||
}
|
||||
|
||||
UnexpectedCharactersException concat(UnexpectedCharactersException other) {
|
||||
return new UnexpectedCharactersException(this.position, this.unexpectedCharacters + other.unexpectedCharacters);
|
||||
UnexpectedCharacters concat(UnexpectedCharacters other) {
|
||||
return new UnexpectedCharacters(this.position, this.unexpectedCharacters + other.unexpectedCharacters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (!(o instanceof UnexpectedCharactersException)) {
|
||||
if (!(o instanceof UnexpectedCharacters)) {
|
||||
return false;
|
||||
}
|
||||
final UnexpectedCharactersException other = (UnexpectedCharactersException) o;
|
||||
final UnexpectedCharacters other = (UnexpectedCharacters) o;
|
||||
return this.position == other.position && this.unexpectedCharacters.equals(other.unexpectedCharacters);
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslException;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Thrown when DSL source code contains a token which doesn't match the grammar.
|
||||
* Occurs when DSL source code contains a token which doesn't match the grammar.
|
||||
*/
|
||||
public class UnexpectedTokenException extends DslException {
|
||||
public class UnexpectedToken implements DslError {
|
||||
private final Token unexpected;
|
||||
private final Set<TokenType> suggested;
|
||||
|
||||
public UnexpectedTokenException(final Token unexpected, final Set<TokenType> suggested) {
|
||||
public UnexpectedToken(final Token unexpected, final Set<TokenType> suggested) {
|
||||
this.unexpected = unexpected;
|
||||
this.suggested = suggested;
|
||||
}
|
||||
|
||||
public UnexpectedTokenException(final Token unexpected, final TokenType... suggested) {
|
||||
public UnexpectedToken(final Token unexpected, final TokenType... suggested) {
|
||||
this.unexpected = unexpected;
|
||||
this.suggested = Set.of(suggested);
|
||||
}
|
||||
@ -50,10 +50,10 @@ public class UnexpectedTokenException extends DslException {
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (!(o instanceof UnexpectedTokenException)) {
|
||||
if (!(o instanceof UnexpectedToken)) {
|
||||
return false;
|
||||
}
|
||||
final UnexpectedTokenException other = (UnexpectedTokenException) o;
|
||||
final UnexpectedToken other = (UnexpectedToken) o;
|
||||
return this.unexpected.equals(other.unexpected) && this.suggested.equals(other.suggested);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.rules.dsl.DslException;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -13,7 +13,7 @@ import static it.cavallium.warppi.math.rules.dsl.frontend.TokenType.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class LexerTest {
|
||||
private final List<DslException> errors = new ArrayList<>();
|
||||
private final List<DslError> errors = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@ -87,8 +87,8 @@ public class LexerTest {
|
||||
);
|
||||
assertEquals(expectedTokens, lexer.lex());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(
|
||||
new IncompleteNumberLiteralException(0, "2.")
|
||||
final List<DslError> expectedErrors = Collections.singletonList(
|
||||
new IncompleteNumberLiteral(0, "2.")
|
||||
);
|
||||
assertEquals(expectedErrors, errors);
|
||||
}
|
||||
@ -102,8 +102,8 @@ public class LexerTest {
|
||||
);
|
||||
assertEquals(expectedTokens, lexer.lex());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(
|
||||
new IncompleteNumberLiteralException(0, "2.")
|
||||
final List<DslError> expectedErrors = Collections.singletonList(
|
||||
new IncompleteNumberLiteral(0, "2.")
|
||||
);
|
||||
assertEquals(expectedErrors, errors);
|
||||
}
|
||||
@ -119,10 +119,10 @@ public class LexerTest {
|
||||
);
|
||||
assertEquals(expectedTokens, lexer.lex());
|
||||
|
||||
final List<DslException> expectedErrors = Arrays.asList(
|
||||
new UnexpectedCharactersException(10, "@|"),
|
||||
new UnexpectedCharactersException(13, "."),
|
||||
new UnexpectedCharactersException(16, "{}")
|
||||
final List<DslError> expectedErrors = Arrays.asList(
|
||||
new UnexpectedCharacters(10, "@|"),
|
||||
new UnexpectedCharacters(13, "."),
|
||||
new UnexpectedCharacters(16, "{}")
|
||||
);
|
||||
assertEquals(expectedErrors, errors);
|
||||
}
|
||||
@ -136,10 +136,10 @@ public class LexerTest {
|
||||
);
|
||||
assertEquals(expectedTokens, lexer.lex());
|
||||
|
||||
final List<DslException> expectedErrors = Arrays.asList(
|
||||
new UnexpectedCharactersException(0, "."),
|
||||
new IncompleteNumberLiteralException(1, "2."),
|
||||
new UnexpectedCharactersException(4, "@")
|
||||
final List<DslError> expectedErrors = Arrays.asList(
|
||||
new UnexpectedCharacters(0, "."),
|
||||
new IncompleteNumberLiteral(1, "2."),
|
||||
new UnexpectedCharacters(4, "@")
|
||||
);
|
||||
assertEquals(expectedErrors, errors);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package it.cavallium.warppi.math.rules.dsl.frontend;
|
||||
|
||||
import it.cavallium.warppi.math.MathematicalSymbols;
|
||||
import it.cavallium.warppi.math.rules.RuleType;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslException;
|
||||
import it.cavallium.warppi.math.rules.dsl.DslError;
|
||||
import it.cavallium.warppi.math.rules.dsl.Pattern;
|
||||
import it.cavallium.warppi.math.rules.dsl.PatternRule;
|
||||
import it.cavallium.warppi.math.rules.dsl.patterns.*;
|
||||
@ -19,7 +19,7 @@ import static it.cavallium.warppi.math.rules.dsl.frontend.TokenType.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ParserTest {
|
||||
private final List<DslException> errors = new ArrayList<>();
|
||||
private final List<DslError> errors = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@ -312,7 +312,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(EOF, "", 0)
|
||||
));
|
||||
assertEquals(expectedErrors, errors);
|
||||
@ -328,7 +328,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(IDENTIFIER, "test", 0),
|
||||
REDUCTION, EXPANSION, CALCULATION, EXISTENCE
|
||||
));
|
||||
@ -353,7 +353,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(CALCULATION, "calculation", 0)
|
||||
));
|
||||
assertEquals(expectedErrors, errors);
|
||||
@ -370,7 +370,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(COLON, ":", 0),
|
||||
IDENTIFIER
|
||||
));
|
||||
@ -391,7 +391,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(IDENTIFIER, "x", 0),
|
||||
COLON
|
||||
));
|
||||
@ -412,7 +412,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(IDENTIFIER, "y", 0),
|
||||
ARROW
|
||||
));
|
||||
@ -435,7 +435,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(EOF, "", 0),
|
||||
RIGHT_BRACKET
|
||||
));
|
||||
@ -460,7 +460,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(IDENTIFIER, "x", 0),
|
||||
LEFT_PAREN
|
||||
));
|
||||
@ -485,7 +485,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(ARROW, "->", 0),
|
||||
RIGHT_PAREN
|
||||
));
|
||||
@ -512,7 +512,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(IDENTIFIER, "x", 0),
|
||||
LEFT_PAREN
|
||||
));
|
||||
@ -539,7 +539,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(IDENTIFIER, "y", 0),
|
||||
COMMA
|
||||
));
|
||||
@ -566,7 +566,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(ARROW, "->", 0),
|
||||
RIGHT_PAREN
|
||||
));
|
||||
@ -590,7 +590,7 @@ public class ParserTest {
|
||||
|
||||
assertTrue(parser.parse().isEmpty());
|
||||
|
||||
final List<DslException> expectedErrors = Collections.singletonList(new UnexpectedTokenException(
|
||||
final List<DslError> expectedErrors = Collections.singletonList(new UnexpectedToken(
|
||||
new Token(ARROW, "->", 0),
|
||||
RIGHT_PAREN
|
||||
));
|
||||
@ -640,9 +640,9 @@ public class ParserTest {
|
||||
));
|
||||
assertEquals(expectedRules, parser.parse());
|
||||
|
||||
final List<DslException> expectedErrors = Arrays.asList(
|
||||
new UnexpectedTokenException(new Token(ARROW, "->", 0)),
|
||||
new UnexpectedTokenException(new Token(IDENTIFIER, "x", 0), COLON)
|
||||
final List<DslError> expectedErrors = Arrays.asList(
|
||||
new UnexpectedToken(new Token(ARROW, "->", 0)),
|
||||
new UnexpectedToken(new Token(IDENTIFIER, "x", 0), COLON)
|
||||
);
|
||||
assertEquals(expectedErrors, errors);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user