Attach error listeners to lexers 03/77003/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 15 Oct 2018 15:26:39 +0000 (17:26 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 15 Oct 2018 15:32:17 +0000 (17:32 +0200)
We currently disconnect parser from standard output, but lexer
may incur errors as well, hence we should do the same dance to
lexers, too.

Change-Id: Ib901cb1fbdba05c721aeba5d60a5e8bda5f48087
JIRA: YANGTOOLS-905
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit b88d8bcfa64908ccd2b64462dc6b66bb3c69a47c)

yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/antlr/SourceExceptionParser.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangStatementStreamSource.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/if_feature/IfFeaturePredicateVisitor.java
yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/XPathParser.java

index 3c5877839a22a598b8b6229c56f0b4e4817c154d..d781984325f67faf48116dcd6278dc95441dd796 100644 (file)
@@ -39,11 +39,12 @@ final class LeafRefPathParserImpl {
 
     private Path_argContext parseLeafRefPathSource(final String path) throws LeafRefYangSyntaxErrorException {
         final LeafRefPathLexer lexer = new LeafRefPathLexer(CharStreams.fromString(path));
-        final CommonTokenStream tokens = new CommonTokenStream(lexer);
-        final LeafRefPathParser parser = new LeafRefPathParser(tokens);
-        parser.removeErrorListeners();
+        final LeafRefPathParser parser = new LeafRefPathParser(new CommonTokenStream(lexer));
 
         final LeafRefPathErrorListener errorListener = new LeafRefPathErrorListener(module);
+        lexer.removeErrorListeners();
+        lexer.addErrorListener(errorListener);
+        parser.removeErrorListeners();
         parser.addErrorListener(errorListener);
 
         final Path_argContext result = parser.path_arg();
index 3867daddc83ea1066803e63f3a00dd6263aacf10..2cb3648dbe87bb38bfe8987c6bd93dc006cbed75 100644 (file)
@@ -12,6 +12,8 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.annotations.Beta;
 import java.util.function.Supplier;
 import javax.annotation.concurrent.NotThreadSafe;
+import org.antlr.v4.runtime.Lexer;
+import org.antlr.v4.runtime.Parser;
 import org.antlr.v4.runtime.RecognitionException;
 import org.antlr.v4.runtime.Recognizer;
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -67,4 +69,28 @@ public final class SourceExceptionParser {
         listener.validate();
         return ret;
     }
+
+    /**
+     * Use a Lexer/Parser pair extracting the parser's root item.
+     *
+     * @param lexer lexer to use
+     * @param parser parser to use
+     * @param parseMethod Root item extractor method
+     * @param ref Source reference
+     * @return Parsed item
+     * @throws NullPointerException if any argument is null
+     * @throws SourceException if a parser error occurs
+     */
+    public static <T> T parse(final Lexer lexer, final Parser parser, final Supplier<T> parseMethod,
+            final StatementSourceReference ref) {
+        final Listener listener = new Listener(ref);
+        lexer.removeErrorListeners();
+        lexer.addErrorListener(listener);
+        parser.removeErrorListeners();
+        parser.addErrorListener(listener);
+
+        final T ret = parseMethod.get();
+        listener.validate();
+        return ret;
+    }
 }
\ No newline at end of file
index 8f97c9dce67aab12d965d0d2128294bb6d966d83..de3e79eb136ecd7ea23afb823d2b348266b4fff3 100644 (file)
@@ -180,12 +180,13 @@ public final class YangStatementStreamSource implements StatementStreamSource {
     private static StatementContext parseYangSource(final SourceIdentifier source, final InputStream stream)
             throws IOException, YangSyntaxErrorException {
         final YangStatementLexer lexer = new YangStatementLexer(CharStreams.fromStream(stream));
-        final CommonTokenStream tokens = new CommonTokenStream(lexer);
-        final YangStatementParser parser = new YangStatementParser(tokens);
-        //disconnect from console error output
+        final YangStatementParser parser = new YangStatementParser(new CommonTokenStream(lexer));
+        // disconnect from console error output
+        lexer.removeErrorListeners();
         parser.removeErrorListeners();
 
         final YangErrorListener errorListener = new YangErrorListener(source);
+        lexer.addErrorListener(errorListener);
         parser.addErrorListener(errorListener);
 
         final StatementContext result = parser.statement();
index bcabd02f7ad3d60bd273b08c602b5d31704fbe20..eee214d319388d46902118ed1a6915ee673c0243 100644 (file)
@@ -37,10 +37,10 @@ final class IfFeaturePredicateVisitor extends IfFeatureExpressionParserBaseVisit
     }
 
     static Predicate<Set<QName>> parseIfFeatureExpression(final StmtContext<?, ?, ?> ctx, final String value) {
-        final IfFeatureExpressionParser parser = new IfFeatureExpressionParser(new CommonTokenStream(
-            new IfFeatureExpressionLexer(CharStreams.fromString(value))));
-        return new IfFeaturePredicateVisitor(ctx).visit(SourceExceptionParser.parse(parser, parser::if_feature_expr,
-            ctx.getStatementSourceReference()));
+        final IfFeatureExpressionLexer lexer = new IfFeatureExpressionLexer(CharStreams.fromString(value));
+        final IfFeatureExpressionParser parser = new IfFeatureExpressionParser(new CommonTokenStream(lexer));
+        return new IfFeaturePredicateVisitor(ctx).visit(SourceExceptionParser.parse(lexer, parser,
+            parser::if_feature_expr, ctx.getStatementSourceReference()));
     }
 
     @Override
index 33c8e7f8bd206c74440351d781f98431a8809f23..b035c696e88c392a84b86b4dae5abe7651c3ecf0 100644 (file)
@@ -130,11 +130,11 @@ abstract class XPathParser<N extends YangNumberExpr<N, ?>> implements YangXPathP
     @Override
     public YangXPathExpression parseExpression(final String xpath) throws XPathExpressionException {
         // Create a parser and disconnect it from console error output
-        final xpathParser parser = new xpathParser(new CommonTokenStream(new xpathLexer(
-            CharStreams.fromString(xpath))));
-        parser.removeErrorListeners();
+        final xpathLexer lexer = new xpathLexer(CharStreams.fromString(xpath));
+        final xpathParser parser = new xpathParser(new CommonTokenStream(lexer));
+
         final List<XPathExpressionException> errors = new ArrayList<>();
-        parser.addErrorListener(new BaseErrorListener() {
+        final BaseErrorListener listener = new BaseErrorListener() {
             @Override
             public void syntaxError(final @Nullable Recognizer<?, ?> recognizer, final @Nullable Object offendingSymbol,
                     final int line, final int charPositionInLine, final @Nullable String msg,
@@ -147,7 +147,12 @@ abstract class XPathParser<N extends YangNumberExpr<N, ?>> implements YangXPathP
                     errors.get(0).addSuppressed(ex);
                 }
             }
-        });
+        };
+
+        lexer.removeErrorListeners();
+        lexer.addErrorListener(listener);
+        parser.removeErrorListeners();
+        parser.addErrorListener(listener);
 
         final YangExpr expr = parseExpr(parser.main().expr());
         if (!errors.isEmpty()) {
@@ -399,10 +404,13 @@ abstract class XPathParser<N extends YangNumberExpr<N, ?>> implements YangXPathP
     }
 
     private YangLiteralExpr parseLocationLiteral(final String text) {
-        final instanceIdentifierParser parser = new instanceIdentifierParser(new CommonTokenStream(new xpathLexer(
-            CharStreams.fromString(text))));
+        final xpathLexer lexer = new xpathLexer(CharStreams.fromString(text));
+        final instanceIdentifierParser parser = new instanceIdentifierParser(new CommonTokenStream(lexer));
+        lexer.removeErrorListeners();
         parser.removeErrorListeners();
 
+        // FIXME: add listeners
+
         final InstanceIdentifierContext id = parser.instanceIdentifier();
         final int length = id.getChildCount();
         final List<Step> steps = new ArrayList<>(length / 2);