Check that sub-functions in replacement patterns are defined

This commit is contained in:
Riccardo Azzolini 2019-01-27 21:10:59 +01:00
parent ba468d199a
commit bea2eb67c8
3 changed files with 38 additions and 1 deletions

View File

@ -53,6 +53,14 @@ public class PatternRule implements Rule {
return ruleType; return ruleType;
} }
Pattern getTarget() {
return target;
}
List<Pattern> getReplacements() {
return replacements;
}
@Override @Override
public ObjectArrayList<Function> execute(final Function func) throws Error, InterruptedException { public ObjectArrayList<Function> execute(final Function func) throws Error, InterruptedException {
return target.match(func) return target.match(func)

View File

@ -3,9 +3,11 @@ package it.cavallium.warppi.math.rules.dsl;
import it.cavallium.warppi.math.rules.Rule; import it.cavallium.warppi.math.rules.Rule;
import it.cavallium.warppi.math.rules.dsl.frontend.Lexer; 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 java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
public class RulesDsl { public class RulesDsl {
private RulesDsl() {} private RulesDsl() {}
@ -13,6 +15,28 @@ public class RulesDsl {
public static List<Rule> makeRules(final String source) { public static List<Rule> makeRules(final String source) {
final Lexer lexer = new Lexer(source); final Lexer lexer = new Lexer(source);
final Parser parser = new Parser(lexer.lex()); final Parser parser = new Parser(lexer.lex());
return Collections.unmodifiableList(parser.parse()); final List<PatternRule> rules = parser.parse();
for (final PatternRule rule : rules) {
checkSubFunctionsDefined(rule);
}
return Collections.unmodifiableList(rules);
}
/**
* Verifies that all sub-functions in the replacement patterns of a <code>PatternRule</code>
* are defined (captured) in the target pattern.
*
* @param rule The rule to check.
* @throws RuntimeException if any replacement pattern uses undefined sub-functions.
*/
private static void checkSubFunctionsDefined(final PatternRule rule) {
final Set<SubFunctionPattern> defined = rule.getTarget().getSubFunctions();
for (final Pattern replacement : rule.getReplacements()) {
if (!defined.containsAll(replacement.getSubFunctions())) {
throw new RuntimeException("Undefined sub-function(s) in replacements for " + rule.getRuleName());
}
}
} }
} }

View File

@ -61,4 +61,9 @@ public class RulesDslTest {
public void parserError() { public void parserError() {
RulesDsl.makeRules("existence test: x + y ->"); RulesDsl.makeRules("existence test: x + y ->");
} }
@Test(expected = RuntimeException.class)
public void undefinedSubFunction() {
RulesDsl.makeRules("expansion test: x -> x + y");
}
} }