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]

Reply via email to