Keep track of sub-function identifier tokens for error reporting

This commit is contained in:
Riccardo Azzolini 2019-01-30 19:58:47 +01:00
parent bdb1fc738e
commit 3a5ccdfc13
1 changed files with 24 additions and 1 deletions

View File

@ -30,6 +30,10 @@ public class Parser {
private final Consumer<? super DslException> 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) {
this.tokens = tokens;
this.errorReporter = errorReporter;
@ -39,6 +43,10 @@ public class Parser {
return rules();
}
public List<Token> getSubFunctionIdentifiers(final String ruleName, final SubFunctionPattern subFunction) {
return subFunctionIdentifiers.get(ruleName).get(subFunction);
}
// rules = { rule } , EOF ;
private List<PatternRule> rules() {
final List<PatternRule> rules = new ArrayList<>();
@ -59,6 +67,7 @@ public class Parser {
private PatternRule rule() throws UnexpectedTokenException {
final RuleType type = ruleType();
final String name = matchOrFail(IDENTIFIER).lexeme;
currentRuleName = name; // This field must be set before calling pattern() and replacements()
matchOrFail(COLON);
final Pattern target = pattern();
matchOrFail(ARROW);
@ -212,7 +221,9 @@ public class Parser {
case NUMBER:
return new NumberPattern(new BigDecimal(curToken.lexeme));
case IDENTIFIER:
return new SubFunctionPattern(curToken.lexeme);
final SubFunctionPattern subFunction = new SubFunctionPattern(curToken.lexeme);
saveSubFunctionIdentifier(subFunction, curToken);
return subFunction;
case LEFT_PAREN:
final Pattern grouped = sum();
matchOrFail(RIGHT_PAREN);
@ -221,6 +232,18 @@ public class Parser {
throw new UnexpectedTokenException(curToken);
}
private void saveSubFunctionIdentifier(final SubFunctionPattern subFunction, final Token curToken) {
final Map<SubFunctionPattern, List<Token>> ruleMap = subFunctionIdentifiers.computeIfAbsent(
currentRuleName,
key -> new HashMap<>()
);
final List<Token> subFunctionList = ruleMap.computeIfAbsent(
subFunction,
key -> new ArrayList<>()
);
subFunctionList.add(curToken);
}
private Pattern matchLeftAssoc(
final PatternParser operandParser,
final Map<TokenType, BiFunction<Pattern, Pattern, Pattern>> operators