From: Robert Varga Date: Mon, 15 Oct 2018 15:26:39 +0000 (+0200) Subject: Attach error listeners to lexers X-Git-Tag: v2.0.12~4 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=2dfbb028d61f249f3335d0b9ef1faccd5dddf1c2;p=yangtools.git 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) --- 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);