X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-xpath-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fxpath%2Fimpl%2FAntlrXPathParser.java;h=17be3ca2cf515f224b16bfae3d7cfa8764c489bb;hb=refs%2Fchanges%2F77%2F86577%2F4;hp=cc24c1d9e71e93adb37862c56984c5561ae7c071;hpb=5054f913d032f85fa5ac7fca8a40de35f82a4e10;p=yangtools.git diff --git a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParser.java b/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParser.java index cc24c1d9e7..17be3ca2cf 100644 --- a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParser.java +++ b/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParser.java @@ -21,8 +21,8 @@ import static org.opendaylight.yangtools.yang.xpath.impl.ParseTreeUtils.verifyTr import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import java.util.AbstractMap.SimpleImmutableEntry; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -31,6 +31,7 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import javax.xml.xpath.XPathExpressionException; @@ -45,6 +46,35 @@ import org.opendaylight.yangtools.yang.common.QualifiedQName; import org.opendaylight.yangtools.yang.common.UnqualifiedQName; import org.opendaylight.yangtools.yang.common.YangConstants; import org.opendaylight.yangtools.yang.common.YangNamespaceContext; +import org.opendaylight.yangtools.yang.common.YangVersion; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathLexer; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.AbbreviatedStepContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.AbsoluteLocationPathNorootContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.AdditiveExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.AndExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.AxisSpecifierContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.EqualityExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.ExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.FilterExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.FunctionCallContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.FunctionNameContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.LocationPathContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.MultiplicativeExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.NCNameContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.NameTestContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.NodeTestContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.OrExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.PathExprNoRootContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.PredicateContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.PrimaryExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.QNameContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.RelationalExprContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.RelativeLocationPathContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.StepContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.UnaryExprNoRootContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.UnionExprNoRootContext; +import org.opendaylight.yangtools.yang.xpath.antlr.xpathParser.VariableReferenceContext; import org.opendaylight.yangtools.yang.xpath.api.YangBinaryOperator; import org.opendaylight.yangtools.yang.xpath.api.YangBooleanConstantExpr; import org.opendaylight.yangtools.yang.xpath.api.YangExpr; @@ -69,32 +99,6 @@ import org.opendaylight.yangtools.yang.xpath.api.YangXPathMathMode; import org.opendaylight.yangtools.yang.xpath.api.YangXPathMathSupport; import org.opendaylight.yangtools.yang.xpath.api.YangXPathNodeType; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParser; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.AbbreviatedStepContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.AbsoluteLocationPathNorootContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.AdditiveExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.AndExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.AxisSpecifierContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.EqualityExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.ExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.FilterExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.FunctionCallContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.FunctionNameContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.LocationPathContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.MultiplicativeExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.NCNameContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.NameTestContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.NodeTestContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.OrExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.PathExprNoRootContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.PredicateContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.PrimaryExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.QNameContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.RelationalExprContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.RelativeLocationPathContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.StepContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.UnaryExprNoRootContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.UnionExprNoRootContext; -import org.opendaylight.yangtools.yang.xpath.impl.xpathParser.VariableReferenceContext; /** * ANTLR-based XPath parser. Uses {@code xpath.g4} ANTLR grammar. @@ -109,7 +113,8 @@ abstract class AntlrXPathParser implements YangXPathParser { @Override public YangXPathExpression parseExpression(final String xpath) throws XPathExpressionException { - return new AntlrYangXPathExpression.Base(mathMode, parseExpr(xpath), xpath); + final Entry result = parseExpr(xpath); + return new AntlrYangXPathExpression.Base(mathMode, result.getKey(), result.getValue(), xpath); } @Override @@ -145,7 +150,9 @@ abstract class AntlrXPathParser implements YangXPathParser { @Override public YangXPathExpression.QualifiedBound parseExpression(final String xpath) throws XPathExpressionException { - return new AntlrYangXPathExpression.Qualified(mathMode, parseExpr(xpath), xpath, namespaceContext); + final Entry result = parseExpr(xpath); + return new AntlrYangXPathExpression.Qualified(mathMode, result.getKey(), result.getValue(), xpath, + namespaceContext); } @Override @@ -172,8 +179,10 @@ abstract class AntlrXPathParser implements YangXPathParser { @Override public YangXPathExpression.UnqualifiedBound parseExpression(final String xpath) throws XPathExpressionException { - return new AntlrYangXPathExpression.Unqualified(mathMode, parseExpr(xpath), xpath, namespaceContext, - defaultNamespace); + final Entry result = parseExpr(xpath); + + return new AntlrYangXPathExpression.Unqualified(mathMode, result.getKey(), result.getValue(), xpath, + namespaceContext, defaultNamespace); } @Override @@ -204,6 +213,8 @@ abstract class AntlrXPathParser implements YangXPathParser { private final YangXPathMathSupport mathSupport; private final FunctionSupport functionSupport; + private YangVersion minimumYangVersion = YangVersion.VERSION_1; + AntlrXPathParser(final YangXPathMathMode mathMode) { this.mathMode = requireNonNull(mathMode); this.mathSupport = mathMode.getSupport(); @@ -230,7 +241,8 @@ abstract class AntlrXPathParser implements YangXPathParser { } } - final YangExpr parseExpr(final String xpath) throws XPathExpressionException { + @SuppressWarnings("checkstyle:illegalCatch") + final Entry parseExpr(final String xpath) throws XPathExpressionException { // Create a parser and disconnect it from console error output final xpathLexer lexer = new xpathLexer(CharStreams.fromString(xpath)); final xpathParser parser = new xpathParser(new CommonTokenStream(lexer)); @@ -240,15 +252,25 @@ abstract class AntlrXPathParser implements YangXPathParser { lexer.addErrorListener(listener); parser.removeErrorListeners(); parser.addErrorListener(listener); - - final YangExpr expr = parseExpr(parser.main().expr()); + final ExprContext antlr = parser.main().expr(); listener.reportError(); - return expr; + + // Reset our internal context + minimumYangVersion = YangVersion.VERSION_1; + + final YangExpr expr; + try { + expr = parseExpr(antlr); + } catch (RuntimeException e) { + throw new XPathExpressionException(e); + } + return new SimpleImmutableEntry<>(minimumYangVersion, expr); } /** * Parse and simplify an XPath expression in {@link ExprContext} representation. * + * @param ctx Current parsing context * @param expr ANTLR ExprContext * @return A {@link YangExpr} * @throws NullPointerException if {@code expr} is null @@ -315,9 +337,12 @@ abstract class AntlrXPathParser implements YangXPathParser { throw illegalShape(name); } - final List args = ImmutableList.copyOf(Lists.transform(expr.expr(), this::parseExpr)); + final List args = expr.expr().stream().map(this::parseExpr).collect(ImmutableList.toImmutableList()); final YangFunction func = YANG_FUNCTIONS.get(parsed); if (func != null) { + if (minimumYangVersion.compareTo(func.getYangVersion()) < 0) { + minimumYangVersion = func.getYangVersion(); + } return functionSupport.functionToExpr(func, args); } @@ -411,21 +436,24 @@ abstract class AntlrXPathParser implements YangXPathParser { private Deque parseLocationPathSteps(final RelativeLocationPathContext expr) { final Deque steps = new ArrayDeque<>(expr.getChildCount()); final Iterator it = expr.children.iterator(); - steps.add(parseStep(nextContext(it, StepContext.class))); + addNotSelfStep(steps, parseStep(nextContext(it, StepContext.class))); while (it.hasNext()) { parseStepShorthand(it.next()).ifPresent(steps::add); // Parse step and add it if it's not SELF_STEP - final Step step = parseStep(nextContext(it, StepContext.class)); - if (!SELF_STEP.equals(step)) { - steps.add(step); - } + addNotSelfStep(steps, parseStep(nextContext(it, StepContext.class))); } return steps; } + private static void addNotSelfStep(final Deque steps, final Step step) { + if (!SELF_STEP.equals(step)) { + steps.add(step); + } + } + private YangExpr parseTerminal(final TerminalNode term) { final String text = term.getText(); switch (term.getSymbol().getType()) { @@ -535,7 +563,7 @@ abstract class AntlrXPathParser implements YangXPathParser { final YangBinaryOperator operator = nextOperator(it); final YangExpr right = parseAdditive(nextContext(it, AdditiveExprContext.class)); final Optional simple = simplifyNumbers(operator, ret, right); - ret = simple.isPresent() ? simple.get() : nextOperator(it).exprWith(ret, right); + ret = simple.isPresent() ? simple.get() : operator.exprWith(ret, right); } while (it.hasNext()); return ret;