Properly report undefined sub-functions in replacement patterns
This commit is contained in:
parent
3a5ccdfc13
commit
f930242ee8
@ -5,10 +5,7 @@ import it.cavallium.warppi.math.rules.dsl.frontend.Lexer;
|
|||||||
import it.cavallium.warppi.math.rules.dsl.frontend.Parser;
|
import it.cavallium.warppi.math.rules.dsl.frontend.Parser;
|
||||||
import it.cavallium.warppi.math.rules.dsl.patterns.SubFunctionPattern;
|
import it.cavallium.warppi.math.rules.dsl.patterns.SubFunctionPattern;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class RulesDsl {
|
public class RulesDsl {
|
||||||
private RulesDsl() {}
|
private RulesDsl() {}
|
||||||
@ -21,7 +18,10 @@ public class RulesDsl {
|
|||||||
final List<PatternRule> rules = parser.parse();
|
final List<PatternRule> rules = parser.parse();
|
||||||
|
|
||||||
for (final PatternRule rule : rules) {
|
for (final PatternRule rule : rules) {
|
||||||
checkSubFunctionsDefined(rule);
|
undefinedSubFunctions(rule).stream()
|
||||||
|
.flatMap(subFunc -> parser.getSubFunctionIdentifiers(rule.getRuleName(), subFunc).stream())
|
||||||
|
.map(UndefinedSubFunctionException::new)
|
||||||
|
.forEach(errors::add);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
@ -32,18 +32,21 @@ public class RulesDsl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that all sub-functions in the replacement patterns of a <code>PatternRule</code>
|
* Finds any sub-functions that are used in the replacement patterns of a <code>PatternRule</code>
|
||||||
* are defined (captured) in the target pattern.
|
* without being defined (captured) in the target pattern.
|
||||||
*
|
*
|
||||||
* @param rule The rule to check.
|
* @param rule The rule to analyze.
|
||||||
* @throws RuntimeException if any replacement pattern uses undefined sub-functions.
|
* @return The (possibly empty) set of undefined sub-functions.
|
||||||
*/
|
*/
|
||||||
private static void checkSubFunctionsDefined(final PatternRule rule) {
|
private static Set<SubFunctionPattern> undefinedSubFunctions(final PatternRule rule) {
|
||||||
final Set<SubFunctionPattern> defined = rule.getTarget().getSubFunctions();
|
final Set<SubFunctionPattern> defined = rule.getTarget().getSubFunctions();
|
||||||
|
final Set<SubFunctionPattern> undefined = new HashSet<>();
|
||||||
for (final Pattern replacement : rule.getReplacements()) {
|
for (final Pattern replacement : rule.getReplacements()) {
|
||||||
if (!defined.containsAll(replacement.getSubFunctions())) {
|
undefined.addAll(replacement.getSubFunctions());
|
||||||
throw new RuntimeException("Undefined sub-function(s) in replacements for " + rule.getRuleName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
undefined.removeAll(defined);
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
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>,
|
||||||
|
* but not defined (captured) in the target pattern.
|
||||||
|
*/
|
||||||
|
public class UndefinedSubFunctionException extends DslException {
|
||||||
|
private final Token identifier;
|
||||||
|
|
||||||
|
public UndefinedSubFunctionException(final Token identifier) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPosition() {
|
||||||
|
return identifier.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLength() {
|
||||||
|
return identifier.lexeme.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The name of the undefined sub-function.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return identifier.lexeme;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user