use of org.drools.drl.parser.lang.ExpanderException in project drools by kiegroup.
the class DefaultExpanderTest method testLineNumberError.
@Test
public void testLineNumberError() throws Exception {
DSLMappingFile file = new DSLTokenizedMappingFile();
String dsl = "[when]foo=Foo()" + NL + "[then]bar {num}=baz({num});";
file.parseAndLoad(new StringReader(dsl));
DefaultExpander ex = new DefaultExpander();
ex.addDSLMapping(file.getMapping());
String source = "rule 'q'" + NL + "agenda-group 'x'" + NL + "when" + NL + " __ " + NL + "then" + NL + " bar 42" + NL + "\tgoober" + NL + "end";
ex.expand(source);
assertTrue(ex.hasErrors());
assertEquals(2, ex.getErrors().size());
ExpanderException err = (ExpanderException) ex.getErrors().get(0);
assertEquals(4, err.getLine());
err = (ExpanderException) ex.getErrors().get(1);
assertEquals(7, err.getLine());
}
use of org.drools.drl.parser.lang.ExpanderException in project drools by kiegroup.
the class KnowledgeBuilderImpl method dslrReaderToPackageDescr.
private PackageDescr dslrReaderToPackageDescr(Resource resource, Reader dslrReader) throws DroolsParserException {
boolean hasErrors;
PackageDescr pkg;
DrlParser parser = new DrlParser(configuration.getLanguageLevel());
DefaultExpander expander = getDslExpander();
try {
try {
if (expander == null) {
expander = new DefaultExpander();
}
String str = expander.expand(dslrReader);
if (expander.hasErrors()) {
for (ExpanderException error : expander.getErrors()) {
error.setResource(resource);
addBuilderResult(error);
}
}
pkg = parser.parse(resource, str);
this.results.addAll(parser.getErrors());
hasErrors = parser.hasErrors();
} finally {
if (dslrReader != null) {
dslrReader.close();
}
}
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return hasErrors ? null : pkg;
}
use of org.drools.drl.parser.lang.ExpanderException in project drools by kiegroup.
the class DefaultExpander method substitute.
/**
* Perform the substitutions.
*
* @param exp
* a DSLR source line to be expanded
* @param entries
* the appropriate DSL keys and values
* @param line
* line number
* @param use
* map for registering use
* @return the expanden line
*/
private String substitute(String exp, List<DSLMappingEntry> entries, int line, Map<String, Integer> use, boolean showSingleSteps) {
if (entries.size() == 0) {
if (line > 0) {
this.addError(new ExpanderException("No mapping entries for expanding: " + exp, line));
}
return exp;
}
if (showSingleSteps) {
logger.info("to expand: |" + exp + "|");
}
Map<String, String> key2value = new HashMap<String, String>();
for (final DSLMappingEntry entry : entries) {
Map<String, Integer> vars = entry.getVariables();
String mappingKey = entry.getMappingKey();
String vp = entry.getValuePattern();
Pattern kp = entry.getKeyPattern();
Matcher m = kp.matcher(exp);
int startPos = 0;
boolean match;
Integer count;
if (showUsage) {
count = use.get(mappingKey);
if (count == null)
use.put(mappingKey, 0);
}
while (startPos < exp.length() && m.find(startPos)) {
match = true;
if (showSingleSteps) {
logger.info(" matches: " + kp.toString());
}
if (showUsage) {
use.put(mappingKey, use.get(mappingKey) + 1);
}
// Replace the range of group 0.
String target = m.group(0);
if (!vars.keySet().isEmpty()) {
// Build a pattern matching any variable enclosed in braces.
StringBuilder sb = new StringBuilder();
String del = "\\{(";
for (String key : vars.keySet()) {
sb.append(del).append(Pattern.quote(key));
del = "|";
}
sb.append(")").append(funcPatStr).append("\\}");
Pattern allkeyPat = Pattern.compile(sb.toString());
vp = entry.getValuePattern();
Matcher allkeyMat = allkeyPat.matcher(vp);
// While the pattern matches, get the actual key and replace by '$' + index
while (allkeyMat.find()) {
String theKey = allkeyMat.group(1);
String theFunc = allkeyMat.group(2);
String foundValue = m.group(vars.get(theKey));
String theValue = applyFunc(theFunc, foundValue);
String newVp = vp.substring(0, allkeyMat.start()) + theValue + vp.substring(allkeyMat.end());
allkeyMat.reset(newVp);
key2value.put(theKey, foundValue);
if (newVp.equals(vp)) {
break;
} else {
vp = newVp;
}
}
}
// Try to find any matches from previous lines.
Matcher varRefMat = varRefPat.matcher(vp);
while (varRefMat.find()) {
String theKey = varRefMat.group(1);
String theFunc = varRefMat.group(2);
for (int ientry = substitutions.size() - 1; ientry >= 0; ientry--) {
String foundValue = substitutions.get(ientry).get(theKey);
if (foundValue != null) {
String theValue = applyFunc(theFunc, foundValue);
// replace it
vp = vp.substring(0, varRefMat.start()) + theValue + vp.substring(varRefMat.end());
varRefMat.reset(vp);
break;
}
}
}
// add the new set of substitutions
if (key2value.size() > 0) {
substitutions.add(key2value);
}
// now replace the target
exp = exp.substring(0, m.start()) + vp + exp.substring(m.end());
if (match && showSingleSteps) {
logger.info(" result: |" + exp + "|");
}
startPos = m.start() + vp.length();
m.reset(exp);
}
}
return exp;
}
use of org.drools.drl.parser.lang.ExpanderException in project drools by kiegroup.
the class DefaultExpander method expandConstructions.
/**
* Expand constructions like rules and queries
*
* @param drl
* @return
*/
private StringBuffer expandConstructions(final String drl) {
// display keys if requested
if (showKeyword) {
for (DSLMappingEntry entry : this.keywords) {
logger.info("keyword: " + entry.getMappingKey());
logger.info(" " + entry.getKeyPattern());
}
}
if (showWhen) {
for (DSLMappingEntry entry : this.condition) {
logger.info("when: " + entry.getMappingKey());
logger.info(" " + entry.getKeyPattern());
// logger.info( " " + entry.getValuePattern() );
}
}
if (showThen) {
for (DSLMappingEntry entry : this.consequence) {
logger.info("then: " + entry.getMappingKey());
logger.info(" " + entry.getKeyPattern());
}
}
// parse and expand specific areas
final Matcher m = finder.matcher(drl);
final StringBuffer buf = new StringBuffer();
int drlPos = 0;
int linecount = 0;
while (m.find()) {
final StringBuilder expanded = new StringBuilder();
int newPos = m.start();
linecount += countNewlines(drl, drlPos, newPos);
drlPos = newPos;
String constr = m.group().trim();
if (constr.startsWith("rule")) {
String headerFragment = m.group(1);
// adding rule header and attributes
expanded.append(headerFragment);
String lhsFragment = m.group(2);
expanded.append(this.expandLHS(lhsFragment, linecount + countNewlines(drl, drlPos, m.start(2)) + 1));
String thenFragment = m.group(3);
// adding "then" header
expanded.append(thenFragment);
String rhsFragment = this.expandRHS(m.group(4), linecount + countNewlines(drl, drlPos, m.start(4)) + 1);
expanded.append(rhsFragment);
// adding rule trailer
expanded.append(m.group(5));
} else if (constr.startsWith("query")) {
String fragment = m.group(6);
// adding query header and attributes
expanded.append(fragment);
String lhsFragment = this.expandLHS(m.group(7), linecount + countNewlines(drl, drlPos, m.start(7)) + 1);
expanded.append(lhsFragment);
// adding query trailer
expanded.append(m.group(8));
} else {
// strange behavior
this.addError(new ExpanderException("Unable to expand statement: " + constr, 0));
}
m.appendReplacement(buf, Matcher.quoteReplacement(expanded.toString()));
}
m.appendTail(buf);
return buf;
}
use of org.drools.drl.parser.lang.ExpanderException in project drools by kiegroup.
the class DrlParser method getExpandedDRL.
/**
* This will expand the DRL using the given expander resolver. useful for
* debugging.
*
* @param source -
* the source which use a DSL
* @param resolver -
* the DSL expander resolver itself.
* @throws DroolsParserException
* If unable to expand in any way.
*/
public String getExpandedDRL(final String source, final DefaultExpanderResolver resolver) throws DroolsParserException {
final Expander expander = resolver.get("*", null);
final String expanded = expander.expand(source);
if (expander.hasErrors()) {
String err = "";
for (ExpanderException ex : expander.getErrors()) {
err = err + "\n Line:[" + ex.getLine() + "] " + ex.getMessage();
}
throw new DroolsParserException(err);
}
return expanded;
}
Aggregations