From 2dfbb028d61f249f3335d0b9ef1faccd5dddf1c2 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 15 Oct 2018 17:26:39 +0200 Subject: [PATCH] Attach error listeners to lexers 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 (cherry picked from commit b88d8bcfa64908ccd2b64462dc6b66bb3c69a47c) --- .../impl/leafref/LeafRefPathParserImpl.java | 7 ++--- .../rfc7950/antlr/SourceExceptionParser.java | 26 +++++++++++++++++++ .../repo/YangStatementStreamSource.java | 7 ++--- .../if_feature/IfFeaturePredicateVisitor.java | 8 +++--- .../yang/xpath/impl/XPathParser.java | 22 +++++++++++----- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java index 3c5877839a..d781984325 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java @@ -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(); diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/antlr/SourceExceptionParser.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/antlr/SourceExceptionParser.java index 3867daddc8..2cb3648dbe 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/antlr/SourceExceptionParser.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/antlr/SourceExceptionParser.java @@ -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 parse(final Lexer lexer, final Parser parser, final Supplier 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 diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangStatementStreamSource.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangStatementStreamSource.java index 8f97c9dce6..de3e79eb13 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangStatementStreamSource.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangStatementStreamSource.java @@ -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(); diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/if_feature/IfFeaturePredicateVisitor.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/if_feature/IfFeaturePredicateVisitor.java index bcabd02f7a..eee214d319 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/if_feature/IfFeaturePredicateVisitor.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/if_feature/IfFeaturePredicateVisitor.java @@ -37,10 +37,10 @@ final class IfFeaturePredicateVisitor extends IfFeatureExpressionParserBaseVisit } static Predicate> 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 diff --git a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/XPathParser.java b/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/XPathParser.java index 33c8e7f8bd..b035c696e8 100644 --- a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/XPathParser.java +++ b/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/XPathParser.java @@ -130,11 +130,11 @@ abstract class XPathParser> 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 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> 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> 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 steps = new ArrayList<>(length / 2); -- 2.36.6