This is an automated email from the ASF dual-hosted git repository.
mariofusco pushed a commit to branch dev-new-parser
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/dev-new-parser by this push:
new c65a1a0bfc Add error listener to DrlExprParser (#5778)
c65a1a0bfc is described below
commit c65a1a0bfcfc97410bbe946d04053812044cb427
Author: Jiří Locker <[email protected]>
AuthorDate: Wed Mar 13 16:51:43 2024 +0100
Add error listener to DrlExprParser (#5778)
---
.../compiler/rule/builder/PatternBuilder.java | 4 +-
.../org/drools/drl/ast/descr/OperatorDescr.java | 2 +-
.../drl/parser/antlr4/DRLExprParserTest.java | 47 +++++++++++++
.../drl/parser/antlr4/Drl6ExprParserAntlr4.java | 14 ++--
.../antlr4/DroolsParserExceptionFactory.java | 76 +++++++++-------------
.../org/drools/drl/parser/antlr4/ParserHelper.java | 13 +---
6 files changed, 91 insertions(+), 65 deletions(-)
diff --git
a/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java
b/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java
index a4c62c8226..33b7533ffb 100644
---
a/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java
+++
b/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java
@@ -1805,8 +1805,6 @@ public class PatternBuilder implements
RuleConditionBuilder<PatternDescr> {
final String
expression) {
DrlExprParser parser =
DrlExprParserFactory.getDrlExprParser(context.getConfiguration().getOption(LanguageLevelOption.KEY));
ConstraintConnectiveDescr result =
parser.parse(normalizeEval(expression));
- result.setResource(patternDescr.getResource());
- result.copyLocation(original);
if (parser.hasErrors()) {
for (DroolsParserException error : parser.getErrors()) {
registerDescrBuildError(context, patternDescr,
@@ -1814,6 +1812,8 @@ public class PatternBuilder implements
RuleConditionBuilder<PatternDescr> {
}
return null;
}
+ result.setResource(patternDescr.getResource());
+ result.copyLocation(original);
return result;
}
diff --git
a/drools-drl/drools-drl-ast/src/main/java/org/drools/drl/ast/descr/OperatorDescr.java
b/drools-drl/drools-drl-ast/src/main/java/org/drools/drl/ast/descr/OperatorDescr.java
index 220923bcbc..561bebe19a 100644
---
a/drools-drl/drools-drl-ast/src/main/java/org/drools/drl/ast/descr/OperatorDescr.java
+++
b/drools-drl/drools-drl-ast/src/main/java/org/drools/drl/ast/descr/OperatorDescr.java
@@ -55,7 +55,7 @@ public class OperatorDescr extends BaseDescr {
}
public void setOperator( String operator ) {
- this.operator = operator.trim();
+ this.operator = operator != null ? operator.trim() : null;
}
public boolean isNegated() {
diff --git
a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java
b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java
index f740b369ea..6fc7eecc6e 100644
---
a/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java
+++
b/drools-drl/drools-drl-parser-tests/src/test/java/org/drools/drl/parser/antlr4/DRLExprParserTest.java
@@ -26,6 +26,7 @@ import org.drools.drl.ast.descr.ConnectiveType;
import org.drools.drl.ast.descr.ConstraintConnectiveDescr;
import org.drools.drl.ast.descr.RelationalExprDescr;
import org.drools.drl.parser.DrlExprParser;
+import org.drools.drl.parser.DroolsParserException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -325,4 +326,50 @@ public class DRLExprParserTest {
assertThat(left.getExpression()).isEqualTo("a");
assertThat(right.getExpression()).isEqualTo("A");
}
+
+ @Test
+ public void testMismatchedInput() {
+ String source = "+";
+ parser.parse(source);
+ assertThat(parser.hasErrors()).isTrue();
+ assertThat(parser.getErrors()).hasSize(1);
+ DroolsParserException exception = parser.getErrors().get(0);
+ assertThat(exception.getErrorCode()).isEqualTo("ERR 102");
+ assertThat(exception.getLineNumber()).isEqualTo(1);
+ assertThat(exception.getColumn()).isEqualTo(1);
+ assertThat(exception.getOffset()).isEqualTo(1);
+ assertThat(exception.getMessage())
+ .startsWithIgnoringCase("[ERR 102] Line 1:1 mismatched input
'<EOF>' expecting ")
+ .contains("TIME_INTERVAL", "DRL_STRING_LITERAL", "?/",
"boolean", "byte", "char", "double", "float", "int", "long", "new", "short",
"super", "DECIMAL_LITERAL", "HEX_LITERAL", "FLOAT_LITERAL", "BOOL_LITERAL",
"STRING_LITERAL", "null", "(", "[", ".", "<", "!", "~", "++", "--", "+", "-",
"*", "/", "IDENTIFIER");
+ }
+
+ @Test
+ public void testExtraneousInput() {
+ String source = "a +; b";
+ parser.parse(source);
+ assertThat(parser.hasErrors()).isTrue();
+ assertThat(parser.getErrors()).hasSize(1);
+ DroolsParserException exception = parser.getErrors().get(0);
+ assertThat(exception.getErrorCode()).isEqualTo("ERR 109");
+ assertThat(exception.getLineNumber()).isEqualTo(1);
+ assertThat(exception.getColumn()).isEqualTo(3);
+ assertThat(exception.getOffset()).isEqualTo(3);
+ assertThat(exception.getMessage())
+ .startsWithIgnoringCase("[ERR 109] Line 1:3 extraneous input
';' expecting ")
+ .contains("TIME_INTERVAL", "DRL_STRING_LITERAL", "?/",
"boolean", "byte", "char", "double", "float", "int", "long", "new", "short",
"super", "DECIMAL_LITERAL", "HEX_LITERAL", "FLOAT_LITERAL", "BOOL_LITERAL",
"STRING_LITERAL", "null", "(", "[", ".", "<", "!", "~", "++", "--", "+", "-",
"*", "/", "IDENTIFIER");
+ }
+ @Test
+ public void testNoViableAlt() {
+ String source = "a~a";
+ parser.parse(source);
+ assertThat(parser.hasErrors()).isTrue();
+ assertThat(parser.getErrors()).hasSize(1);
+ DroolsParserException exception = parser.getErrors().get(0);
+ assertThat(exception.getErrorCode()).isEqualTo("ERR 101");
+ assertThat(exception.getLineNumber()).isEqualTo(1);
+ assertThat(exception.getColumn()).isEqualTo(2);
+ assertThat(exception.getOffset()).isEqualTo(2);
+ assertThat(exception.getMessage())
+ .isEqualToIgnoringCase("[ERR 101] Line 1:2 no viable
alternative at input 'a'");
+ }
}
diff --git
a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Drl6ExprParserAntlr4.java
b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Drl6ExprParserAntlr4.java
index 220c8bb066..4505ca428a 100644
---
a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Drl6ExprParserAntlr4.java
+++
b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/Drl6ExprParserAntlr4.java
@@ -21,9 +21,11 @@ package org.drools.drl.parser.antlr4;
import java.util.Collections;
import java.util.List;
+import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
import org.drools.drl.ast.descr.BaseDescr;
import org.drools.drl.ast.descr.ConstraintConnectiveDescr;
import org.drools.drl.parser.DrlExprParser;
@@ -47,11 +49,16 @@ public class Drl6ExprParserAntlr4 implements DrlExprParser {
/** Parse an expression from text */
public ConstraintConnectiveDescr parse(final String text) {
ConstraintConnectiveDescr constraint = null;
- try {
DRLLexer lexer = new DRLLexer(CharStreams.fromString(text));
CommonTokenStream input = new CommonTokenStream(lexer);
- helper = new ParserHelper(input, null, languageLevel);
+ helper = new ParserHelper(input, languageLevel);
DRLExpressions parser = new DRL6Expressions(input, helper);
+ parser.addErrorListener(new BaseErrorListener() {
+ @Override
+ public void syntaxError(Recognizer<?, ?> recognizer, Object
offendingSymbol, int line, int charPositionInLine, String msg,
RecognitionException e) {
+ helper.reportError(offendingSymbol, line,
charPositionInLine, msg, e);
+ }
+ });
parser.setBuildDescr(true);
parser.setLeftMostExpr(null); // setting initial value just in case
BaseDescr expr = parser.conditionalOrExpressionDescr();
@@ -59,9 +66,6 @@ public class Drl6ExprParserAntlr4 implements DrlExprParser {
constraint = ConstraintConnectiveDescr.newAnd();
constraint.addOrMerge(expr);
}
- } catch (RecognitionException e) {
- helper.reportError(e);
- }
return constraint;
}
diff --git
a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/DroolsParserExceptionFactory.java
b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/DroolsParserExceptionFactory.java
index 622ea8ae3b..c40636256f 100644
---
a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/DroolsParserExceptionFactory.java
+++
b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/DroolsParserExceptionFactory.java
@@ -20,13 +20,12 @@ package org.drools.drl.parser.antlr4;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.antlr.v4.runtime.FailedPredicateException;
+import org.antlr.v4.runtime.InputMismatchException;
import org.antlr.v4.runtime.NoViableAltException;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
@@ -42,8 +41,6 @@ import org.kie.internal.builder.conf.LanguageLevelOption;
* @see DroolsParserException
*/
public class DroolsParserExceptionFactory {
- public final static String NO_VIABLE_ALT_MESSAGE
= "Line %1$d:%2$d no viable alternative at input '%3$s'%4$s";
- public final static String FAILED_PREDICATE_MESSAGE
= "Line %1$d:%2$d rule '%3$s' failed predicate: {%4$s}?%5$s";
public final static String
TRAILING_SEMI_COLON_NOT_ALLOWED_MESSAGE = "Line %1$d:%2$d trailing semi-colon
not allowed%3$s";
public final static String
PARSER_LOCATION_MESSAGE_COMPLETE = " in %1$s %2$s";
public final static String
PARSER_LOCATION_MESSAGE_PART = " in %1$s";
@@ -103,58 +100,45 @@ public class DroolsParserExceptionFactory {
/**
* This method creates a DroolsParserException full of information.
*
- * @param e
- * original exception
+ * @param offendingSymbol
+ * @param line
+ * @param charPositionInLine
+ * @param e original exception
* @return DroolsParserException filled.
*/
- public DroolsParserException createDroolsException( RecognitionException e
) {
- List<String> codeAndMessage = createErrorMessage( e );
- return new DroolsParserException( codeAndMessage.get( 1 ),
- codeAndMessage
- .get( 0 ),
- // TODO verify this is correct
- e.getOffendingToken().getLine(),
-
e.getOffendingToken().getCharPositionInLine(),
-
e.getOffendingToken().getStartIndex(),
+ public DroolsParserException createDroolsException(Object offendingSymbol,
int line, int charPositionInLine, String message, RecognitionException e ) {
+ return new DroolsParserException( determineErrorCode( e ),
+ String.format("Line %d:%d %s", line,
charPositionInLine, message),
+ line,
+ charPositionInLine,
+
determineStartingIndex(offendingSymbol),
e );
}
+ private int determineStartingIndex(Object offendingSymbol) {
+ if (offendingSymbol instanceof Token) {
+ return ((Token) offendingSymbol).getStartIndex();
+ }
+ return -1;
+ }
+
/**
- * This will take a RecognitionException, and create a sensible error
- * message out of it
+ * Determines the error code based on a specific subtype of
RecognitionException.
*/
- private List<String> createErrorMessage( RecognitionException e ) {
- List<String> codeAndMessage = new ArrayList<>( 2 );
- String message;
+ private String determineErrorCode( RecognitionException e ) {
+ if (e == null) {
+ return "ERR 109";
+ }
+ if ( e instanceof InputMismatchException) {
+ return "ERR 102";
+ }
if ( e instanceof NoViableAltException ) {
- // NoViableAltException nvae = (NoViableAltException) e;
- message = String.format(
- NO_VIABLE_ALT_MESSAGE,
- // TODO verify this is correct
- e.getOffendingToken().getLine(),
-
e.getOffendingToken().getCharPositionInLine(),
- getBetterToken( e.getOffendingToken() ),
- formatParserLocation() );
- codeAndMessage.add( message );
- codeAndMessage.add( "ERR 101" );
- } else if ( e instanceof FailedPredicateException ) {
- FailedPredicateException fpe = (FailedPredicateException) e;
- String ruleName =
fpe.getRecognizer().getRuleNames()[fpe.getRuleIndex()];
- message = String.format(
- FAILED_PREDICATE_MESSAGE,
- // TODO verify this is correct
- e.getOffendingToken().getLine(),
-
e.getOffendingToken().getCharPositionInLine(),
- ruleName,
- fpe.getPredicate(),
- formatParserLocation() );
- codeAndMessage.add( message );
- codeAndMessage.add( "ERR 103" );
+ return "ERR 101";
}
- if ( codeAndMessage.get( 0 ).length() == 0 ) {
- codeAndMessage.add( "?????" );
+ if ( e instanceof FailedPredicateException ) {
+ return "ERR 103";
}
- return codeAndMessage;
+ throw new IllegalArgumentException("Unexpected exception type: " + e);
}
public DroolsParserException createDroolsException( Exception e,
diff --git
a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/ParserHelper.java
b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/ParserHelper.java
index 1d533e3c51..504233edee 100644
---
a/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/ParserHelper.java
+++
b/drools-drl/drools-drl-parser/src/main/java/org/drools/drl/parser/antlr4/ParserHelper.java
@@ -120,11 +120,9 @@ public class ParserHelper {
private final LanguageLevelOption languageLevel;
public ParserHelper(TokenStream input,
- RecognizerSharedState state,
LanguageLevelOption languageLevel) {
this.errorMessageFactory = new DroolsParserExceptionFactory(
paraphrases, languageLevel );
this.input = input;
- this.state = state;
this.languageLevel = languageLevel;
}
@@ -360,15 +358,8 @@ public class ParserHelper {
DroolsSoftKeywords.DIRECT );
}
- public void reportError( RecognitionException ex ) {
- // if we've already reported an error and have not matched a token
- // yet successfully, don't report any errors.
- if ( state.errorRecovery ) {
- return;
- }
- state.errorRecovery = true;
-
- errors.add( errorMessageFactory.createDroolsException( ex ) );
+ public void reportError(Object offendingSymbol, int line, int
charPositionInLine, String message, RecognitionException ex ) {
+ errors.add( errorMessageFactory.createDroolsException(
offendingSymbol, line, charPositionInLine, message, ex ) );
}
public void reportError( Exception e ) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]