All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.org.antlr.v4.kotlinruntime.tree.xpath.XPath.kt Maven / Gradle / Ivy

///*
// * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
// * Use of this file is governed by the BSD 3-clause license that
// * can be found in the LICENSE.txt file in the project root.
// */
//
//package org.antlr.v4.kotlinruntime.tree.xpath
//
//import org.antlr.v4.kotlinruntime.*
//import ParseTree
//
///**
// * Represent a subset of XPath XML path syntax for use in identifying nodes in
// * parse trees.
// *
// *
// *
// * Split path into words and separators `/` and `//` via ANTLR
// * itself then walk path elements from left to right. At each separator-word
// * pair, find set of nodes. Next stage uses those as work list.
// *
// *
// *
// * The basic interface is
// * [ParseTree.findAll][XPath.findAll]`(tree, pathString, parser)`.
// * But that is just shorthand for:
// *
// * 
// * [XPath] p = new [XPath][XPath.XPath](parser, pathString);
// * return p.[evaluate][.evaluate](tree);
//
* // * // * // * // * See `org.antlr.v4.test.TestXPath` for descriptions. In short, this // * allows operators: // * // *
// *
/
root
// *
//
anywhere
// *
!
invert; this must appear directly after root or anywhere // * operator
//
* // * // * // * // * and path elements: // * // *
// *
ID
token name
// *
'string'
any string literal token from the grammar
// *
expr
rule name
// *
*
wildcard matching any node
//
* // * // * // * // * Whitespace is not allowed. // */ //class XPath(protected var parser: Parser, protected var path: String) { // protected var elements: Array // // init { // elements = split(path) // // System.out.println(Arrays.toString(elements)); // } // // // TODO: check for invalid token/rule names, bad syntax // // fun split(path: String): Array { // val `in`: ANTLRInputStream // try { // `in` = ANTLRInputStream(StringReader(path)) // } catch (ioe: IOException) { // throw IllegalArgumentException("Could not read path: " + path, ioe) // } // // val lexer = object : XPathLexer(`in`) { // fun recover(e: LexerNoViableAltException) { // throw e // } // } // lexer.removeErrorListeners() // lexer.addErrorListener(XPathLexerErrorListener()) // val tokenStream = CommonTokenStream(lexer) // try { // tokenStream.fill() // } catch (e: LexerNoViableAltException) { // val pos = lexer.charPositionInLine // val msg = "Invalid tokens or characters at index $pos in path '$path'" // throw IllegalArgumentException(msg, e) // } // // val tokens = tokenStream.getTokens() // // System.out.println("path="+path+"=>"+tokens); // val elements = ArrayList() // val n = tokens.size // var i = 0 // loop@ while (i < n) { // val el = tokens.get(i) // var next: Token? = null // when (el.getType()) { // XPathLexer.ROOT, XPathLexer.ANYWHERE -> { // val anywhere = el.getType() === XPathLexer.ANYWHERE // i++ // next = tokens.get(i) // val invert = next!!.getType() === XPathLexer.BANG // if (invert) { // i++ // next = tokens.get(i) // } // val pathElement = getXPathElement(next, anywhere) // pathElement.invert = invert // elements.add(pathElement) // i++ // } // // XPathLexer.TOKEN_REF, XPathLexer.RULE_REF, XPathLexer.WILDCARD -> { // elements.add(getXPathElement(el, false)) // i++ // } // // Token.EOF -> break@loop // // else -> throw IllegalArgumentException("Unknowth path element " + el) // } // } // return elements.toTypedArray() // } // // /** // * Convert word like `*` or `ID` or `expr` to a path // * element. `anywhere` is `true` if `//` precedes the // * word. // */ // protected fun getXPathElement(wordToken: Token, anywhere: Boolean): XPathElement { // if (wordToken.getType() === Token.EOF) { // throw IllegalArgumentException("Missing path element at end of path") // } // val word = wordToken.getText() // val ttype = parser.getTokenType(word) // val ruleIndex = parser.getRuleIndex(word) // when (wordToken.getType()) { // XPathLexer.WILDCARD -> return if (anywhere) // XPathWildcardAnywhereElement() // else // XPathWildcardElement() // XPathLexer.TOKEN_REF, XPathLexer.STRING -> { // if (ttype == Token.INVALID_TYPE) { // throw IllegalArgumentException(word + // " at index " + // wordToken.getStartIndex() + // " isn't a valid token name") // } // return if (anywhere) // XPathTokenAnywhereElement(word, ttype) // else // XPathTokenElement(word, ttype) // } // else -> { // if (ruleIndex == -1) { // throw IllegalArgumentException(word + // " at index " + // wordToken.getStartIndex() + // " isn't a valid rule name") // } // return if (anywhere) // XPathRuleAnywhereElement(word, ruleIndex) // else // XPathRuleElement(word, ruleIndex) // } // } // } // // /** // * Return a list of all nodes starting at `t` as root that satisfy the // * path. The root `/` is relative to the node passed to // * [.evaluate]. // */ // fun evaluate(t: ParseTree): Collection { // val dummyRoot = ParserRuleContext() // dummyRoot.children = listOf(t) // don't set t's parent. // // var work: Collection = setOf(dummyRoot) // // var i = 0 // while (i < elements.size) { // val next = LinkedHashSet() // for (node in work) { // if (node.getChildCount() > 0) { // // only try to match next element if it has children // // e.g., //func/*/stat might have a token node for which // // we can't go looking for stat nodes. // val matching = elements[i].evaluate(node) // next.addAll(matching) // } // } // i++ // work = next // } // // return work // } // // companion object { // val WILDCARD = "*" // word not operator/separator // val NOT = "!" // word for invert operator // // // fun findAll(tree: ParseTree, xpath: String, parser: Parser): Collection { // val p = XPath(parser, xpath) // return p.evaluate(tree) // } // } //}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy