abouttreesummaryrefslogcommitdiff
path: root/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree
diff options
context:
space:
mode:
Diffstat (limited to 'antlr4-cpp-runtime-4.9.2-source/runtime/src/tree')
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/AbstractParseTreeVisitor.h128
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.cpp9
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.h19
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.cpp23
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.h33
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.cpp71
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.h53
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.cpp15
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.h102
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.cpp9
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.h39
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeProperty.h50
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.cpp9
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.h57
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.cpp49
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.h55
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.cpp9
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.h32
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.cpp57
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.h33
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.cpp241
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.h78
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.cpp9
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.h44
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.cpp69
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.h132
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.cpp64
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.h105
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.cpp371
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.h185
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.cpp77
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.h117
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.cpp39
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.h86
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.cpp28
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.h51
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.cpp36
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.h80
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.cpp154
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.h86
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.cpp31
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.h40
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.cpp173
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.g464
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.h56
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.tokens12
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.cpp13
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.h22
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.cpp20
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.h27
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.cpp30
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.h26
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.cpp20
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.h25
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.cpp33
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.h26
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.cpp23
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.h23
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.cpp24
-rw-r--r--antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.h23
60 files changed, 3615 insertions, 0 deletions
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/AbstractParseTreeVisitor.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/AbstractParseTreeVisitor.h
new file mode 100644
index 0000000..d21795b
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/AbstractParseTreeVisitor.h
@@ -0,0 +1,128 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "tree/ParseTreeVisitor.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC AbstractParseTreeVisitor : public ParseTreeVisitor {
+ public:
+ /// The default implementation calls <seealso cref="ParseTree#accept"/> on the
+ /// specified tree.
+ virtual antlrcpp::Any visit(ParseTree *tree) override {
+ return tree->accept(this);
+ }
+
+ /**
+ * <p>The default implementation initializes the aggregate result to
+ * {@link #defaultResult defaultResult()}. Before visiting each child, it
+ * calls {@link #shouldVisitNextChild shouldVisitNextChild}; if the result
+ * is {@code false} no more children are visited and the current aggregate
+ * result is returned. After visiting a child, the aggregate result is
+ * updated by calling {@link #aggregateResult aggregateResult} with the
+ * previous aggregate result and the result of visiting the child.</p>
+ *
+ * <p>The default implementation is not safe for use in visitors that modify
+ * the tree structure. Visitors that modify the tree should override this
+ * method to behave properly in respect to the specific algorithm in use.</p>
+ */
+ virtual antlrcpp::Any visitChildren(ParseTree *node) override {
+ antlrcpp::Any result = defaultResult();
+ size_t n = node->children.size();
+ for (size_t i = 0; i < n; i++) {
+ if (!shouldVisitNextChild(node, result)) {
+ break;
+ }
+
+ antlrcpp::Any childResult = node->children[i]->accept(this);
+ result = aggregateResult(result, childResult);
+ }
+
+ return result;
+ }
+
+ /// The default implementation returns the result of
+ /// <seealso cref="#defaultResult defaultResult"/>.
+ virtual antlrcpp::Any visitTerminal(TerminalNode * /*node*/) override {
+ return defaultResult();
+ }
+
+ /// The default implementation returns the result of
+ /// <seealso cref="#defaultResult defaultResult"/>.
+ virtual antlrcpp::Any visitErrorNode(ErrorNode * /*node*/) override {
+ return defaultResult();
+ }
+
+ protected:
+ /// <summary>
+ /// Gets the default value returned by visitor methods. This value is
+ /// returned by the default implementations of
+ /// <seealso cref="#visitTerminal visitTerminal"/>, <seealso cref="#visitErrorNode visitErrorNode"/>.
+ /// The default implementation of <seealso cref="#visitChildren visitChildren"/>
+ /// initializes its aggregate result to this value.
+ /// <p/>
+ /// The base implementation returns {@code null}.
+ /// </summary>
+ /// <returns> The default value returned by visitor methods. </returns>
+ virtual antlrcpp::Any defaultResult() {
+ return nullptr; // support isNotNull
+ }
+
+ /// <summary>
+ /// Aggregates the results of visiting multiple children of a node. After
+ /// either all children are visited or <seealso cref="#shouldVisitNextChild"/> returns
+ /// {@code false}, the aggregate value is returned as the result of
+ /// <seealso cref="#visitChildren"/>.
+ /// <p/>
+ /// The default implementation returns {@code nextResult}, meaning
+ /// <seealso cref="#visitChildren"/> will return the result of the last child visited
+ /// (or return the initial value if the node has no children).
+ /// </summary>
+ /// <param name="aggregate"> The previous aggregate value. In the default
+ /// implementation, the aggregate value is initialized to
+ /// <seealso cref="#defaultResult"/>, which is passed as the {@code aggregate} argument
+ /// to this method after the first child node is visited. </param>
+ /// <param name="nextResult"> The result of the immediately preceeding call to visit
+ /// a child node.
+ /// </param>
+ /// <returns> The updated aggregate result. </returns>
+ virtual antlrcpp::Any aggregateResult(antlrcpp::Any /*aggregate*/, const antlrcpp::Any &nextResult) {
+ return nextResult;
+ }
+
+ /// <summary>
+ /// This method is called after visiting each child in
+ /// <seealso cref="#visitChildren"/>. This method is first called before the first
+ /// child is visited; at that point {@code currentResult} will be the initial
+ /// value (in the default implementation, the initial value is returned by a
+ /// call to <seealso cref="#defaultResult"/>. This method is not called after the last
+ /// child is visited.
+ /// <p/>
+ /// The default implementation always returns {@code true}, indicating that
+ /// {@code visitChildren} should only return after all children are visited.
+ /// One reason to override this method is to provide a "short circuit"
+ /// evaluation option for situations where the result of visiting a single
+ /// child has the potential to determine the result of the visit operation as
+ /// a whole.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="ParseTree"/> whose children are currently being
+ /// visited. </param>
+ /// <param name="currentResult"> The current aggregate result of the children visited
+ /// to the current point.
+ /// </param>
+ /// <returns> {@code true} to continue visiting children. Otherwise return
+ /// {@code false} to stop visiting children and immediately return the
+ /// current aggregate result from <seealso cref="#visitChildren"/>. </returns>
+ virtual bool shouldVisitNextChild(ParseTree * /*node*/, const antlrcpp::Any &/*currentResult*/) {
+ return true;
+ }
+
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.cpp
new file mode 100644
index 0000000..ade2539
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.cpp
@@ -0,0 +1,9 @@
+/* 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.
+ */
+
+#include "tree/ErrorNode.h"
+
+antlr4::tree::ErrorNode::~ErrorNode() {
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.h
new file mode 100644
index 0000000..619f44d
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNode.h
@@ -0,0 +1,19 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "tree/TerminalNode.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC ErrorNode : public virtual TerminalNode {
+ public:
+ ~ErrorNode() override;
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.cpp
new file mode 100644
index 0000000..fde942d
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.cpp
@@ -0,0 +1,23 @@
+/* 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.
+ */
+
+#include "Exceptions.h"
+#include "tree/ParseTreeVisitor.h"
+
+#include "tree/ErrorNodeImpl.h"
+
+using namespace antlr4;
+using namespace antlr4::misc;
+using namespace antlr4::tree;
+
+ErrorNodeImpl::ErrorNodeImpl(Token *token) : TerminalNodeImpl(token) {
+}
+
+ErrorNodeImpl::~ErrorNodeImpl() {
+}
+
+antlrcpp::Any ErrorNodeImpl::accept(ParseTreeVisitor *visitor) {
+ return visitor->visitErrorNode(this);
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.h
new file mode 100644
index 0000000..b64b6f9
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ErrorNodeImpl.h
@@ -0,0 +1,33 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "tree/ErrorNode.h"
+#include "tree/TerminalNodeImpl.h"
+#include "misc/Interval.h"
+
+#include "support/Any.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// <summary>
+ /// Represents a token that was consumed during resynchronization
+ /// rather than during a valid match operation. For example,
+ /// we will create this kind of a node during single token insertion
+ /// and deletion as well as during "consume until error recovery set"
+ /// upon no viable alternative exceptions.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ErrorNodeImpl : public virtual TerminalNodeImpl, public virtual ErrorNode {
+ public:
+ ErrorNodeImpl(Token *token);
+ ~ErrorNodeImpl() override;
+
+ virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.cpp
new file mode 100644
index 0000000..a4b3efd
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.cpp
@@ -0,0 +1,71 @@
+/* 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.
+ */
+
+#include "support/CPPUtils.h"
+
+#include "tree/ParseTreeListener.h"
+#include "tree/ParseTree.h"
+#include "tree/ErrorNode.h"
+
+#include "IterativeParseTreeWalker.h"
+
+using namespace antlr4::tree;
+
+void IterativeParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) const {
+
+ std::vector<ParseTree *> nodeStack;
+ std::vector<size_t> indexStack;
+
+ ParseTree *currentNode = t;
+ size_t currentIndex = 0;
+
+ while (currentNode != nullptr) {
+ // pre-order visit
+ if (antlrcpp::is<ErrorNode *>(currentNode)) {
+ listener->visitErrorNode(dynamic_cast<ErrorNode *>(currentNode));
+ } else if (antlrcpp::is<TerminalNode *>(currentNode)) {
+ listener->visitTerminal((TerminalNode *)currentNode);
+ } else {
+ enterRule(listener, currentNode);
+ }
+
+ // Move down to first child, if it exists.
+ if (!currentNode->children.empty()) {
+ nodeStack.push_back(currentNode);
+ indexStack.push_back(currentIndex);
+ currentIndex = 0;
+ currentNode = currentNode->children[0];
+ continue;
+ }
+
+ // No child nodes, so walk tree.
+ do {
+ // post-order visit
+ if (!antlrcpp::is<TerminalNode *>(currentNode)) {
+ exitRule(listener, currentNode);
+ }
+
+ // No parent, so no siblings.
+ if (nodeStack.empty()) {
+ currentNode = nullptr;
+ currentIndex = 0;
+ break;
+ }
+
+ // Move to next sibling if possible.
+ if (nodeStack.back()->children.size() > ++currentIndex) {
+ currentNode = nodeStack.back()->children[currentIndex];
+ break;
+ }
+
+ // No next sibling, so move up.
+ currentNode = nodeStack.back();
+ nodeStack.pop_back();
+ currentIndex = indexStack.back();
+ indexStack.pop_back();
+
+ } while (currentNode != nullptr);
+ }
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.h
new file mode 100644
index 0000000..8957d87
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/IterativeParseTreeWalker.h
@@ -0,0 +1,53 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2012 Terence Parr
+ * Copyright (c) 2012 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+#include "tree/ParseTreeWalker.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ParseTreeListener;
+
+ /**
+ * An iterative (read: non-recursive) pre-order and post-order tree walker that
+ * doesn't use the thread stack but heap-based stacks. Makes it possible to
+ * process deeply nested parse trees.
+ */
+ class ANTLR4CPP_PUBLIC IterativeParseTreeWalker : public ParseTreeWalker {
+ public:
+ virtual void walk(ParseTreeListener *listener, ParseTree *t) const override;
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.cpp
new file mode 100644
index 0000000..b975a40
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.cpp
@@ -0,0 +1,15 @@
+/* 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.
+ */
+
+#include "tree/ParseTree.h"
+
+using namespace antlr4::tree;
+
+ParseTree::ParseTree() : parent(nullptr) {
+}
+
+bool ParseTree::operator == (const ParseTree &other) const {
+ return &other == this;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.h
new file mode 100644
index 0000000..3b91be8
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTree.h
@@ -0,0 +1,102 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "support/Any.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// An interface to access the tree of <seealso cref="RuleContext"/> objects created
+ /// during a parse that makes the data structure look like a simple parse tree.
+ /// This node represents both internal nodes, rule invocations,
+ /// and leaf nodes, token matches.
+ ///
+ /// The payload is either a <seealso cref="Token"/> or a <seealso cref="RuleContext"/> object.
+ // ml: This class unites 4 Java classes: RuleNode, ParseTree, SyntaxTree and Tree.
+ class ANTLR4CPP_PUBLIC ParseTree {
+ public:
+ ParseTree();
+ ParseTree(ParseTree const&) = delete;
+ virtual ~ParseTree() {}
+
+ ParseTree& operator=(ParseTree const&) = delete;
+
+ /// The parent of this node. If the return value is null, then this
+ /// node is the root of the tree.
+ ParseTree *parent;
+
+ /// If we are debugging or building a parse tree for a visitor,
+ /// we need to track all of the tokens and rule invocations associated
+ /// with this rule's context. This is empty for parsing w/o tree constr.
+ /// operation because we don't the need to track the details about
+ /// how we parse this rule.
+ // ml: memory is not managed here, but by the owning class. This is just for the structure.
+ std::vector<ParseTree *> children;
+
+ /// Print out a whole tree, not just a node, in LISP format
+ /// {@code (root child1 .. childN)}. Print just a node if this is a leaf.
+ virtual std::string toStringTree(bool pretty = false) = 0;
+ virtual std::string toString() = 0;
+
+ /// Specialize toStringTree so that it can print out more information
+ /// based upon the parser.
+ virtual std::string toStringTree(Parser *parser, bool pretty = false) = 0;
+
+ virtual bool operator == (const ParseTree &other) const;
+
+ /// The <seealso cref="ParseTreeVisitor"/> needs a double dispatch method.
+ // ml: This has been changed to use Any instead of a template parameter, to avoid the need of a virtual template function.
+ virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) = 0;
+
+ /// Return the combined text of all leaf nodes. Does not get any
+ /// off-channel tokens (if any) so won't return whitespace and
+ /// comments if they are sent to parser on hidden channel.
+ virtual std::string getText() = 0;
+
+ /**
+ * Return an {@link Interval} indicating the index in the
+ * {@link TokenStream} of the first and last token associated with this
+ * subtree. If this node is a leaf, then the interval represents a single
+ * token and has interval i..i for token index i.
+ *
+ * <p>An interval of i..i-1 indicates an empty interval at position
+ * i in the input stream, where 0 &lt;= i &lt;= the size of the input
+ * token stream. Currently, the code base can only have i=0..n-1 but
+ * in concept one could have an empty interval after EOF. </p>
+ *
+ * <p>If source interval is unknown, this returns {@link Interval#INVALID}.</p>
+ *
+ * <p>As a weird special case, the source interval for rules matched after
+ * EOF is unspecified.</p>
+ */
+ virtual misc::Interval getSourceInterval() = 0;
+ };
+
+ // A class to help managing ParseTree instances without the need of a shared_ptr.
+ class ANTLR4CPP_PUBLIC ParseTreeTracker {
+ public:
+ template<typename T, typename ... Args>
+ T* createInstance(Args&& ... args) {
+ static_assert(std::is_base_of<ParseTree, T>::value, "Argument must be a parse tree type");
+ T* result = new T(args...);
+ _allocated.push_back(result);
+ return result;
+ }
+
+ void reset() {
+ for (auto * entry : _allocated)
+ delete entry;
+ _allocated.clear();
+ }
+
+ private:
+ std::vector<ParseTree *> _allocated;
+ };
+
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.cpp
new file mode 100644
index 0000000..ce12297
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.cpp
@@ -0,0 +1,9 @@
+/* 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.
+ */
+
+#include "ParseTreeListener.h"
+
+antlr4::tree::ParseTreeListener::~ParseTreeListener() {
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.h
new file mode 100644
index 0000000..6a7f96a
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeListener.h
@@ -0,0 +1,39 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /** This interface describes the minimal core of methods triggered
+ * by {@link ParseTreeWalker}. E.g.,
+ *
+ * ParseTreeWalker walker = new ParseTreeWalker();
+ * walker.walk(myParseTreeListener, myParseTree); <-- triggers events in your listener
+ *
+ * If you want to trigger events in multiple listeners during a single
+ * tree walk, you can use the ParseTreeDispatcher object available at
+ *
+ * https://github.com/antlr/antlr4/issues/841
+ */
+ class ANTLR4CPP_PUBLIC ParseTreeListener {
+ public:
+ virtual ~ParseTreeListener();
+
+ virtual void visitTerminal(TerminalNode *node) = 0;
+ virtual void visitErrorNode(ErrorNode *node) = 0;
+ virtual void enterEveryRule(ParserRuleContext *ctx) = 0;
+ virtual void exitEveryRule(ParserRuleContext *ctx) = 0;
+
+ bool operator == (const ParseTreeListener &other) {
+ return this == &other;
+ }
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeProperty.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeProperty.h
new file mode 100644
index 0000000..8669a10
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeProperty.h
@@ -0,0 +1,50 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// <summary>
+ /// Associate a property with a parse tree node. Useful with parse tree listeners
+ /// that need to associate values with particular tree nodes, kind of like
+ /// specifying a return value for the listener event method that visited a
+ /// particular node. Example:
+ ///
+ /// <pre>
+ /// ParseTreeProperty&lt;Integer&gt; values = new ParseTreeProperty&lt;Integer&gt;();
+ /// values.put(tree, 36);
+ /// int x = values.get(tree);
+ /// values.removeFrom(tree);
+ /// </pre>
+ ///
+ /// You would make one decl (values here) in the listener and use lots of times
+ /// in your event methods.
+ /// </summary>
+ template<typename V>
+ class ANTLR4CPP_PUBLIC ParseTreeProperty {
+ public:
+ virtual ~ParseTreeProperty() {}
+ virtual V get(ParseTree *node) {
+ return _annotations[node];
+ }
+ virtual void put(ParseTree *node, V value) {
+ _annotations[node] = value;
+ }
+ virtual V removeFrom(ParseTree *node) {
+ auto value = _annotations[node];
+ _annotations.erase(node);
+ return value;
+ }
+
+ protected:
+ std::map<ParseTree*, V> _annotations;
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.cpp
new file mode 100644
index 0000000..a329919
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.cpp
@@ -0,0 +1,9 @@
+/* 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.
+ */
+
+#include "ParseTreeVisitor.h"
+
+antlr4::tree::ParseTreeVisitor::~ParseTreeVisitor() {
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.h
new file mode 100644
index 0000000..5a08599
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeVisitor.h
@@ -0,0 +1,57 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "support/Any.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// <summary>
+ /// This interface defines the basic notion of a parse tree visitor. Generated
+ /// visitors implement this interface and the {@code XVisitor} interface for
+ /// grammar {@code X}.
+ /// </summary>
+ /// @param <T> The return type of the visit operation. Use <seealso cref="Void"/> for
+ /// operations with no return type. </param>
+ // ml: no template parameter here, to avoid the need for virtual template functions. Instead we have our Any class.
+ class ANTLR4CPP_PUBLIC ParseTreeVisitor {
+ public:
+ virtual ~ParseTreeVisitor();
+
+ /// <summary>
+ /// Visit a parse tree, and return a user-defined result of the operation.
+ /// </summary>
+ /// <param name="tree"> The <seealso cref="ParseTree"/> to visit. </param>
+ /// <returns> The result of visiting the parse tree. </returns>
+ virtual antlrcpp::Any visit(ParseTree *tree) = 0;
+
+ /// <summary>
+ /// Visit the children of a node, and return a user-defined result of the
+ /// operation.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="ParseTree"/> whose children should be visited. </param>
+ /// <returns> The result of visiting the children of the node. </returns>
+ virtual antlrcpp::Any visitChildren(ParseTree *node) = 0;
+
+ /// <summary>
+ /// Visit a terminal node, and return a user-defined result of the operation.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="TerminalNode"/> to visit. </param>
+ /// <returns> The result of visiting the node. </returns>
+ virtual antlrcpp::Any visitTerminal(TerminalNode *node) = 0;
+
+ /// <summary>
+ /// Visit an error node, and return a user-defined result of the operation.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="ErrorNode"/> to visit. </param>
+ /// <returns> The result of visiting the node. </returns>
+ virtual antlrcpp::Any visitErrorNode(ErrorNode *node) = 0;
+
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.cpp
new file mode 100644
index 0000000..998c9ed
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.cpp
@@ -0,0 +1,49 @@
+/* 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.
+ */
+
+#include "tree/ErrorNode.h"
+#include "ParserRuleContext.h"
+#include "tree/ParseTreeListener.h"
+#include "support/CPPUtils.h"
+
+#include "tree/IterativeParseTreeWalker.h"
+#include "tree/ParseTreeWalker.h"
+
+using namespace antlr4::tree;
+using namespace antlrcpp;
+
+static IterativeParseTreeWalker defaultWalker;
+ParseTreeWalker &ParseTreeWalker::DEFAULT = defaultWalker;
+
+ParseTreeWalker::~ParseTreeWalker() {
+}
+
+void ParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) const {
+ if (is<ErrorNode *>(t)) {
+ listener->visitErrorNode(dynamic_cast<ErrorNode *>(t));
+ return;
+ } else if (is<TerminalNode *>(t)) {
+ listener->visitTerminal(dynamic_cast<TerminalNode *>(t));
+ return;
+ }
+
+ enterRule(listener, t);
+ for (auto &child : t->children) {
+ walk(listener, child);
+ }
+ exitRule(listener, t);
+}
+
+void ParseTreeWalker::enterRule(ParseTreeListener *listener, ParseTree *r) const {
+ ParserRuleContext *ctx = dynamic_cast<ParserRuleContext *>(r);
+ listener->enterEveryRule(ctx);
+ ctx->enterRule(listener);
+}
+
+void ParseTreeWalker::exitRule(ParseTreeListener *listener, ParseTree *r) const {
+ ParserRuleContext *ctx = dynamic_cast<ParserRuleContext *>(r);
+ ctx->exitRule(listener);
+ listener->exitEveryRule(ctx);
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.h
new file mode 100644
index 0000000..166ad80
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/ParseTreeWalker.h
@@ -0,0 +1,55 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC ParseTreeWalker {
+ public:
+ static ParseTreeWalker &DEFAULT;
+
+ virtual ~ParseTreeWalker();
+
+ /**
+ * <summary>
+ * Performs a walk on the given parse tree starting at the root and going down recursively
+ * with depth-first search. On each node, <seealso cref="ParseTreeWalker#enterRule"/> is called before
+ * recursively walking down into child nodes, then
+ * <seealso cref="ParseTreeWalker#exitRule"/> is called after the recursive call to wind up.
+ * </summary>
+ * <param name='listener'> The listener used by the walker to process grammar rules </param>
+ * <param name='t'> The parse tree to be walked on </param>
+ */
+ virtual void walk(ParseTreeListener *listener, ParseTree *t) const;
+
+ protected:
+
+ /**
+ * <summary>
+ * Enters a grammar rule by first triggering the generic event <seealso cref="ParseTreeListener#enterEveryRule"/>
+ * then by triggering the event specific to the given parse tree node
+ * </summary>
+ * <param name='listener'> The listener responding to the trigger events </param>
+ * <param name='r'> The grammar rule containing the rule context </param>
+ */
+ virtual void enterRule(ParseTreeListener *listener, ParseTree *r) const;
+
+ /**
+ * <summary>
+ * Exits a grammar rule by first triggering the event specific to the given parse tree node
+ * then by triggering the generic event <seealso cref="ParseTreeListener#exitEveryRule"/>
+ * </summary>
+ * <param name='listener'> The listener responding to the trigger events </param>
+ * <param name='r'> The grammar rule containing the rule context </param>
+ */
+ virtual void exitRule(ParseTreeListener *listener, ParseTree *r) const;
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.cpp
new file mode 100644
index 0000000..d630469
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.cpp
@@ -0,0 +1,9 @@
+/* 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.
+ */
+
+#include "tree/TerminalNode.h"
+
+antlr4::tree::TerminalNode::~TerminalNode() {
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.h
new file mode 100644
index 0000000..7108f70
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNode.h
@@ -0,0 +1,32 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "tree/ParseTree.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC TerminalNode : public ParseTree {
+ public:
+ ~TerminalNode() override;
+
+ virtual Token* getSymbol() = 0;
+
+ /** Set the parent for this leaf node.
+ *
+ * Technically, this is not backward compatible as it changes
+ * the interface but no one was able to create custom
+ * TerminalNodes anyway so I'm adding as it improves internal
+ * code quality.
+ *
+ * @since 4.7
+ */
+ virtual void setParent(RuleContext *parent) = 0;
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.cpp
new file mode 100644
index 0000000..7ab121b
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.cpp
@@ -0,0 +1,57 @@
+/* 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.
+ */
+
+#include "misc/Interval.h"
+#include "Token.h"
+#include "RuleContext.h"
+#include "tree/ParseTreeVisitor.h"
+
+#include "tree/TerminalNodeImpl.h"
+
+using namespace antlr4;
+using namespace antlr4::tree;
+
+TerminalNodeImpl::TerminalNodeImpl(Token *symbol_) : symbol(symbol_) {
+}
+
+Token* TerminalNodeImpl::getSymbol() {
+ return symbol;
+}
+
+void TerminalNodeImpl::setParent(RuleContext *parent_) {
+ this->parent = parent_;
+}
+
+misc::Interval TerminalNodeImpl::getSourceInterval() {
+ if (symbol == nullptr) {
+ return misc::Interval::INVALID;
+ }
+
+ size_t tokenIndex = symbol->getTokenIndex();
+ return misc::Interval(tokenIndex, tokenIndex);
+}
+
+antlrcpp::Any TerminalNodeImpl::accept(ParseTreeVisitor *visitor) {
+ return visitor->visitTerminal(this);
+}
+
+std::string TerminalNodeImpl::getText() {
+ return symbol->getText();
+}
+
+std::string TerminalNodeImpl::toStringTree(Parser * /*parser*/, bool /*pretty*/) {
+ return toString();
+}
+
+std::string TerminalNodeImpl::toString() {
+ if (symbol->getType() == Token::EOF) {
+ return "<EOF>";
+ }
+ return symbol->getText();
+}
+
+std::string TerminalNodeImpl::toStringTree(bool /*pretty*/) {
+ return toString();
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.h
new file mode 100644
index 0000000..6f65d82
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/TerminalNodeImpl.h
@@ -0,0 +1,33 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "tree/TerminalNode.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC TerminalNodeImpl : public virtual TerminalNode {
+ public:
+ Token *symbol;
+
+ TerminalNodeImpl(Token *symbol);
+
+ virtual Token* getSymbol() override;
+ virtual void setParent(RuleContext *parent) override;
+ virtual misc::Interval getSourceInterval() override;
+
+ virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
+
+ virtual std::string getText() override;
+ virtual std::string toStringTree(Parser *parser, bool pretty = false) override;
+ virtual std::string toString() override;
+ virtual std::string toStringTree(bool pretty = false) override;
+
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.cpp
new file mode 100644
index 0000000..34cfb74
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.cpp
@@ -0,0 +1,241 @@
+/* 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.
+ */
+
+#include "tree/ErrorNode.h"
+#include "Parser.h"
+#include "ParserRuleContext.h"
+#include "support/CPPUtils.h"
+#include "tree/TerminalNodeImpl.h"
+#include "atn/ATN.h"
+#include "misc/Interval.h"
+#include "Token.h"
+#include "CommonToken.h"
+#include "misc/Predicate.h"
+
+#include "tree/Trees.h"
+
+using namespace antlr4;
+using namespace antlr4::misc;
+using namespace antlr4::tree;
+
+using namespace antlrcpp;
+
+Trees::Trees() {
+}
+
+std::string Trees::toStringTree(ParseTree *t, bool pretty) {
+ return toStringTree(t, nullptr, pretty);
+}
+
+std::string Trees::toStringTree(ParseTree *t, Parser *recog, bool pretty) {
+ if (recog == nullptr)
+ return toStringTree(t, std::vector<std::string>(), pretty);
+ return toStringTree(t, recog->getRuleNames(), pretty);
+}
+
+std::string Trees::toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames, bool pretty) {
+ std::string temp = antlrcpp::escapeWhitespace(Trees::getNodeText(t, ruleNames), false);
+ if (t->children.empty()) {
+ return temp;
+ }
+
+ std::stringstream ss;
+ ss << "(" << temp << ' ';
+
+ // Implement the recursive walk as iteration to avoid trouble with deep nesting.
+ std::stack<size_t> stack;
+ size_t childIndex = 0;
+ ParseTree *run = t;
+ size_t indentationLevel = 1;
+ while (childIndex < run->children.size()) {
+ if (childIndex > 0) {
+ ss << ' ';
+ }
+ ParseTree *child = run->children[childIndex];
+ temp = antlrcpp::escapeWhitespace(Trees::getNodeText(child, ruleNames), false);
+ if (!child->children.empty()) {
+ // Go deeper one level.
+ stack.push(childIndex);
+ run = child;
+ childIndex = 0;
+ if (pretty) {
+ ++indentationLevel;
+ ss << std::endl;
+ for (size_t i = 0; i < indentationLevel; ++i) {
+ ss << " ";
+ }
+ }
+ ss << "(" << temp << " ";
+ } else {
+ ss << temp;
+ while (++childIndex == run->children.size()) {
+ if (stack.size() > 0) {
+ // Reached the end of the current level. See if we can step up from here.
+ childIndex = stack.top();
+ stack.pop();
+ run = run->parent;
+ if (pretty) {
+ --indentationLevel;
+ }
+ ss << ")";
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ ss << ")";
+ return ss.str();
+}
+
+std::string Trees::getNodeText(ParseTree *t, Parser *recog) {
+ return getNodeText(t, recog->getRuleNames());
+}
+
+std::string Trees::getNodeText(ParseTree *t, const std::vector<std::string> &ruleNames) {
+ if (ruleNames.size() > 0) {
+ if (is<RuleContext *>(t)) {
+ size_t ruleIndex = dynamic_cast<RuleContext *>(t)->getRuleIndex();
+ std::string ruleName = ruleNames[ruleIndex];
+ size_t altNumber = dynamic_cast<RuleContext *>(t)->getAltNumber();
+ if (altNumber != atn::ATN::INVALID_ALT_NUMBER) {
+ return ruleName + ":" + std::to_string(altNumber);
+ }
+ return ruleName;
+ } else if (is<ErrorNode *>(t)) {
+ return t->toString();
+ } else if (is<TerminalNode *>(t)) {
+ Token *symbol = dynamic_cast<TerminalNode *>(t)->getSymbol();
+ if (symbol != nullptr) {
+ std::string s = symbol->getText();
+ return s;
+ }
+ }
+ }
+ // no recog for rule names
+ if (is<RuleContext *>(t)) {
+ return dynamic_cast<RuleContext *>(t)->getText();
+ }
+
+ if (is<TerminalNodeImpl *>(t)) {
+ return dynamic_cast<TerminalNodeImpl *>(t)->getSymbol()->getText();
+ }
+
+ return "";
+}
+
+std::vector<ParseTree *> Trees::getAncestors(ParseTree *t) {
+ std::vector<ParseTree *> ancestors;
+ ParseTree *parent = t->parent;
+ while (parent != nullptr) {
+ ancestors.insert(ancestors.begin(), parent); // insert at start
+ parent = parent->parent;
+ }
+ return ancestors;
+}
+
+template<typename T>
+static void _findAllNodes(ParseTree *t, size_t index, bool findTokens, std::vector<T> &nodes) {
+ // check this node (the root) first
+ if (findTokens && is<TerminalNode *>(t)) {
+ TerminalNode *tnode = dynamic_cast<TerminalNode *>(t);
+ if (tnode->getSymbol()->getType() == index) {
+ nodes.push_back(t);
+ }
+ } else if (!findTokens && is<ParserRuleContext *>(t)) {
+ ParserRuleContext *ctx = dynamic_cast<ParserRuleContext *>(t);
+ if (ctx->getRuleIndex() == index) {
+ nodes.push_back(t);
+ }
+ }
+ // check children
+ for (size_t i = 0; i < t->children.size(); i++) {
+ _findAllNodes(t->children[i], index, findTokens, nodes);
+ }
+}
+
+bool Trees::isAncestorOf(ParseTree *t, ParseTree *u) {
+ if (t == nullptr || u == nullptr || t->parent == nullptr) {
+ return false;
+ }
+
+ ParseTree *p = u->parent;
+ while (p != nullptr) {
+ if (t == p) {
+ return true;
+ }
+ p = p->parent;
+ }
+ return false;
+}
+
+std::vector<ParseTree *> Trees::findAllTokenNodes(ParseTree *t, size_t ttype) {
+ return findAllNodes(t, ttype, true);
+}
+
+std::vector<ParseTree *> Trees::findAllRuleNodes(ParseTree *t, size_t ruleIndex) {
+ return findAllNodes(t, ruleIndex, false);
+}
+
+std::vector<ParseTree *> Trees::findAllNodes(ParseTree *t, size_t index, bool findTokens) {
+ std::vector<ParseTree *> nodes;
+ _findAllNodes<ParseTree *>(t, index, findTokens, nodes);
+ return nodes;
+}
+
+std::vector<ParseTree *> Trees::getDescendants(ParseTree *t) {
+ std::vector<ParseTree *> nodes;
+ nodes.push_back(t);
+ std::size_t n = t->children.size();
+ for (size_t i = 0 ; i < n ; i++) {
+ auto descentants = getDescendants(t->children[i]);
+ for (auto *entry: descentants) {
+ nodes.push_back(entry);
+ }
+ }
+ return nodes;
+}
+
+std::vector<ParseTree *> Trees::descendants(ParseTree *t) {
+ return getDescendants(t);
+}
+
+ParserRuleContext* Trees::getRootOfSubtreeEnclosingRegion(ParseTree *t, size_t startTokenIndex, size_t stopTokenIndex) {
+ size_t n = t->children.size();
+ for (size_t i = 0; i < n; i++) {
+ ParserRuleContext *r = getRootOfSubtreeEnclosingRegion(t->children[i], startTokenIndex, stopTokenIndex);
+ if (r != nullptr) {
+ return r;
+ }
+ }
+
+ if (is<ParserRuleContext *>(t)) {
+ ParserRuleContext *r = dynamic_cast<ParserRuleContext *>(t);
+ if (startTokenIndex >= r->getStart()->getTokenIndex() && // is range fully contained in t?
+ (r->getStop() == nullptr || stopTokenIndex <= r->getStop()->getTokenIndex())) {
+ // note: r.getStop()==null likely implies that we bailed out of parser and there's nothing to the right
+ return r;
+ }
+ }
+ return nullptr;
+}
+
+ParseTree * Trees::findNodeSuchThat(ParseTree *t, Ref<Predicate> const& pred) {
+ if (pred->test(t)) {
+ return t;
+ }
+
+ size_t n = t->children.size();
+ for (size_t i = 0 ; i < n ; ++i) {
+ ParseTree *u = findNodeSuchThat(t->children[i], pred);
+ if (u != nullptr) {
+ return u;
+ }
+ }
+
+ return nullptr;
+}
+
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.h
new file mode 100644
index 0000000..d9d0462
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/Trees.h
@@ -0,0 +1,78 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "tree/TerminalNode.h"
+#include "ParserRuleContext.h"
+#include "Recognizer.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// A set of utility routines useful for all kinds of ANTLR trees.
+ class ANTLR4CPP_PUBLIC Trees {
+ public:
+ /// Print out a whole tree in LISP form. getNodeText is used on the
+ /// node payloads to get the text for the nodes. Detect
+ /// parse trees and extract data appropriately.
+ static std::string toStringTree(ParseTree *t, bool pretty = false);
+
+ /// Print out a whole tree in LISP form. getNodeText is used on the
+ /// node payloads to get the text for the nodes. Detect
+ /// parse trees and extract data appropriately.
+ static std::string toStringTree(ParseTree *t, Parser *recog, bool pretty = false);
+
+ /// Print out a whole tree in LISP form. getNodeText is used on the
+ /// node payloads to get the text for the nodes. Detect
+ /// parse trees and extract data appropriately.
+ static std::string toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames, bool pretty = false);
+ static std::string getNodeText(ParseTree *t, Parser *recog);
+ static std::string getNodeText(ParseTree *t, const std::vector<std::string> &ruleNames);
+
+ /// Return a list of all ancestors of this node. The first node of
+ /// list is the root and the last is the parent of this node.
+ static std::vector<ParseTree *> getAncestors(ParseTree *t);
+
+ /** Return true if t is u's parent or a node on path to root from u.
+ * Use == not equals().
+ *
+ * @since 4.5.1
+ */
+ static bool isAncestorOf(ParseTree *t, ParseTree *u);
+ static std::vector<ParseTree *> findAllTokenNodes(ParseTree *t, size_t ttype);
+ static std::vector<ParseTree *> findAllRuleNodes(ParseTree *t, size_t ruleIndex);
+ static std::vector<ParseTree *> findAllNodes(ParseTree *t, size_t index, bool findTokens);
+
+ /** Get all descendents; includes t itself.
+ *
+ * @since 4.5.1
+ */
+ static std::vector<ParseTree *> getDescendants(ParseTree *t);
+
+ /** @deprecated */
+ static std::vector<ParseTree *> descendants(ParseTree *t);
+
+ /** Find smallest subtree of t enclosing range startTokenIndex..stopTokenIndex
+ * inclusively using postorder traversal. Recursive depth-first-search.
+ *
+ * @since 4.5.1
+ */
+ static ParserRuleContext* getRootOfSubtreeEnclosingRegion(ParseTree *t,
+ size_t startTokenIndex, // inclusive
+ size_t stopTokenIndex); // inclusive
+
+ /** Return first node satisfying the pred
+ *
+ * @since 4.5.1
+ */
+ static ParseTree* findNodeSuchThat(ParseTree *t, Ref<misc::Predicate> const& pred);
+
+ private:
+ Trees();
+ };
+
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.cpp
new file mode 100644
index 0000000..5320f91
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.cpp
@@ -0,0 +1,9 @@
+/* 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.
+ */
+
+#include "tree/pattern/Chunk.h"
+
+antlr4::tree::pattern::Chunk::~Chunk() {
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.h
new file mode 100644
index 0000000..42e7838
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.h
@@ -0,0 +1,44 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A chunk is either a token tag, a rule tag, or a span of literal text within a
+ /// tree pattern.
+ /// <p/>
+ /// The method <seealso cref="ParseTreePatternMatcher#split(String)"/> returns a list of
+ /// chunks in preparation for creating a token stream by
+ /// <seealso cref="ParseTreePatternMatcher#tokenize(String)"/>. From there, we get a parse
+ /// tree from with <seealso cref="ParseTreePatternMatcher#compile(String, int)"/>. These
+ /// chunks are converted to <seealso cref="RuleTagToken"/>, <seealso cref="TokenTagToken"/>, or the
+ /// regular tokens of the text surrounding the tags.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC Chunk {
+ public:
+ Chunk() = default;
+ Chunk(Chunk const&) = default;
+ virtual ~Chunk();
+
+ Chunk& operator=(Chunk const&) = default;
+
+ /// This method returns a text representation of the tag chunk. Labeled tags
+ /// are returned in the form {@code label:tag}, and unlabeled tags are
+ /// returned as just the tag name.
+ virtual std::string toString() {
+ std::string str;
+ return str;
+ }
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.cpp
new file mode 100644
index 0000000..ce34b3f
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.cpp
@@ -0,0 +1,69 @@
+/* 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.
+ */
+
+#include "Exceptions.h"
+
+#include "tree/pattern/ParseTreeMatch.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::pattern;
+
+ParseTreeMatch::ParseTreeMatch(ParseTree *tree, const ParseTreePattern &pattern,
+ const std::map<std::string, std::vector<ParseTree *>> &labels,
+ ParseTree *mismatchedNode)
+ : _tree(tree), _pattern(pattern), _labels(labels), _mismatchedNode(mismatchedNode) {
+ if (tree == nullptr) {
+ throw IllegalArgumentException("tree cannot be nul");
+ }
+}
+
+ParseTreeMatch::~ParseTreeMatch() {
+}
+
+ParseTree* ParseTreeMatch::get(const std::string &label) {
+ auto iterator = _labels.find(label);
+ if (iterator == _labels.end() || iterator->second.empty()) {
+ return nullptr;
+ }
+
+ return iterator->second.back(); // return last if multiple
+}
+
+std::vector<ParseTree *> ParseTreeMatch::getAll(const std::string &label) {
+ auto iterator = _labels.find(label);
+ if (iterator == _labels.end()) {
+ return {};
+ }
+
+ return iterator->second;
+}
+
+std::map<std::string, std::vector<ParseTree *>>& ParseTreeMatch::getLabels() {
+ return _labels;
+}
+
+ParseTree *ParseTreeMatch::getMismatchedNode() {
+ return _mismatchedNode;
+}
+
+bool ParseTreeMatch::succeeded() {
+ return _mismatchedNode == nullptr;
+}
+
+const ParseTreePattern& ParseTreeMatch::getPattern() {
+ return _pattern;
+}
+
+ParseTree * ParseTreeMatch::getTree() {
+ return _tree;
+}
+
+std::string ParseTreeMatch::toString() {
+ if (succeeded()) {
+ return "Match succeeded; found " + std::to_string(_labels.size()) + " labels";
+ } else {
+ return "Match failed; found " + std::to_string(_labels.size()) + " labels";
+ }
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.h
new file mode 100644
index 0000000..eefde46
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.h
@@ -0,0 +1,132 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// Represents the result of matching a ParseTree against a tree pattern.
+ class ANTLR4CPP_PUBLIC ParseTreeMatch {
+ private:
+ /// This is the backing field for getTree().
+ ParseTree *_tree;
+
+ /// This is the backing field for getPattern().
+ const ParseTreePattern &_pattern;
+
+ /// This is the backing field for getLabels().
+ std::map<std::string, std::vector<ParseTree *>> _labels;
+
+ /// This is the backing field for getMismatchedNode().
+ ParseTree *_mismatchedNode;
+
+ public:
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="ParseTreeMatch"/> from the specified
+ /// parse tree and pattern.
+ /// </summary>
+ /// <param name="tree"> The parse tree to match against the pattern. </param>
+ /// <param name="pattern"> The parse tree pattern. </param>
+ /// <param name="labels"> A mapping from label names to collections of
+ /// <seealso cref="ParseTree"/> objects located by the tree pattern matching process. </param>
+ /// <param name="mismatchedNode"> The first node which failed to match the tree
+ /// pattern during the matching process.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code tree} is {@code null} </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code pattern} is {@code null} </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code labels} is {@code null} </exception>
+ ParseTreeMatch(ParseTree *tree, ParseTreePattern const& pattern,
+ const std::map<std::string, std::vector<ParseTree *>> &labels, ParseTree *mismatchedNode);
+ ParseTreeMatch(ParseTreeMatch const&) = default;
+ virtual ~ParseTreeMatch();
+
+ /// <summary>
+ /// Get the last node associated with a specific {@code label}.
+ /// <p/>
+ /// For example, for pattern {@code <id:ID>}, {@code get("id")} returns the
+ /// node matched for that {@code ID}. If more than one node
+ /// matched the specified label, only the last is returned. If there is
+ /// no node associated with the label, this returns {@code null}.
+ /// <p/>
+ /// Pattern tags like {@code <ID>} and {@code <expr>} without labels are
+ /// considered to be labeled with {@code ID} and {@code expr}, respectively.
+ /// </summary>
+ /// <param name="labe"> The label to check.
+ /// </param>
+ /// <returns> The last <seealso cref="ParseTree"/> to match a tag with the specified
+ /// label, or {@code null} if no parse tree matched a tag with the label. </returns>
+ virtual ParseTree* get(const std::string &label);
+
+ /// <summary>
+ /// Return all nodes matching a rule or token tag with the specified label.
+ /// <p/>
+ /// If the {@code label} is the name of a parser rule or token in the
+ /// grammar, the resulting list will contain both the parse trees matching
+ /// rule or tags explicitly labeled with the label and the complete set of
+ /// parse trees matching the labeled and unlabeled tags in the pattern for
+ /// the parser rule or token. For example, if {@code label} is {@code "foo"},
+ /// the result will contain <em>all</em> of the following.
+ ///
+ /// <ul>
+ /// <li>Parse tree nodes matching tags of the form {@code <foo:anyRuleName>} and
+ /// {@code <foo:AnyTokenName>}.</li>
+ /// <li>Parse tree nodes matching tags of the form {@code <anyLabel:foo>}.</li>
+ /// <li>Parse tree nodes matching tags of the form {@code <foo>}.</li>
+ /// </ul>
+ /// </summary>
+ /// <param name="labe"> The label.
+ /// </param>
+ /// <returns> A collection of all <seealso cref="ParseTree"/> nodes matching tags with
+ /// the specified {@code label}. If no nodes matched the label, an empty list
+ /// is returned. </returns>
+ virtual std::vector<ParseTree *> getAll(const std::string &label);
+
+ /// <summary>
+ /// Return a mapping from label &rarr; [list of nodes].
+ /// <p/>
+ /// The map includes special entries corresponding to the names of rules and
+ /// tokens referenced in tags in the original pattern. For additional
+ /// information, see the description of <seealso cref="#getAll(String)"/>.
+ /// </summary>
+ /// <returns> A mapping from labels to parse tree nodes. If the parse tree
+ /// pattern did not contain any rule or token tags, this map will be empty. </returns>
+ virtual std::map<std::string, std::vector<ParseTree *>>& getLabels();
+
+ /// <summary>
+ /// Get the node at which we first detected a mismatch.
+ /// </summary>
+ /// <returns> the node at which we first detected a mismatch, or {@code null}
+ /// if the match was successful. </returns>
+ virtual ParseTree* getMismatchedNode();
+
+ /// <summary>
+ /// Gets a value indicating whether the match operation succeeded.
+ /// </summary>
+ /// <returns> {@code true} if the match operation succeeded; otherwise,
+ /// {@code false}. </returns>
+ virtual bool succeeded();
+
+ /// <summary>
+ /// Get the tree pattern we are matching against.
+ /// </summary>
+ /// <returns> The tree pattern we are matching against. </returns>
+ virtual const ParseTreePattern& getPattern();
+
+ /// <summary>
+ /// Get the parse tree we are trying to match to a pattern.
+ /// </summary>
+ /// <returns> The <seealso cref="ParseTree"/> we are trying to match to a pattern. </returns>
+ virtual ParseTree* getTree();
+
+ virtual std::string toString();
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.cpp
new file mode 100644
index 0000000..50f44c8
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.cpp
@@ -0,0 +1,64 @@
+/* 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.
+ */
+
+#include "tree/ParseTree.h"
+#include "tree/pattern/ParseTreePatternMatcher.h"
+#include "tree/pattern/ParseTreeMatch.h"
+
+#include "tree/xpath/XPath.h"
+#include "tree/xpath/XPathElement.h"
+
+#include "tree/pattern/ParseTreePattern.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::pattern;
+
+using namespace antlrcpp;
+
+ParseTreePattern::ParseTreePattern(ParseTreePatternMatcher *matcher, const std::string &pattern, int patternRuleIndex_,
+ ParseTree *patternTree)
+ : patternRuleIndex(patternRuleIndex_), _pattern(pattern), _patternTree(patternTree), _matcher(matcher) {
+}
+
+ParseTreePattern::~ParseTreePattern() {
+}
+
+ParseTreeMatch ParseTreePattern::match(ParseTree *tree) {
+ return _matcher->match(tree, *this);
+}
+
+bool ParseTreePattern::matches(ParseTree *tree) {
+ return _matcher->match(tree, *this).succeeded();
+}
+
+std::vector<ParseTreeMatch> ParseTreePattern::findAll(ParseTree *tree, const std::string &xpath) {
+ xpath::XPath finder(_matcher->getParser(), xpath);
+ std::vector<ParseTree *> subtrees = finder.evaluate(tree);
+ std::vector<ParseTreeMatch> matches;
+ for (auto *t : subtrees) {
+ ParseTreeMatch aMatch = match(t);
+ if (aMatch.succeeded()) {
+ matches.push_back(aMatch);
+ }
+ }
+ return matches;
+}
+
+
+ParseTreePatternMatcher *ParseTreePattern::getMatcher() const {
+ return _matcher;
+}
+
+std::string ParseTreePattern::getPattern() const {
+ return _pattern;
+}
+
+int ParseTreePattern::getPatternRuleIndex() const {
+ return patternRuleIndex;
+}
+
+ParseTree* ParseTreePattern::getPatternTree() const {
+ return _patternTree;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.h
new file mode 100644
index 0000000..d5b86ff
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.h
@@ -0,0 +1,105 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A pattern like {@code <ID> = <expr>;} converted to a <seealso cref="ParseTree"/> by
+ /// <seealso cref="ParseTreePatternMatcher#compile(String, int)"/>.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ParseTreePattern {
+ public:
+ /// <summary>
+ /// Construct a new instance of the <seealso cref="ParseTreePattern"/> class.
+ /// </summary>
+ /// <param name="matcher"> The <seealso cref="ParseTreePatternMatcher"/> which created this
+ /// tree pattern. </param>
+ /// <param name="pattern"> The tree pattern in concrete syntax form. </param>
+ /// <param name="patternRuleIndex"> The parser rule which serves as the root of the
+ /// tree pattern. </param>
+ /// <param name="patternTree"> The tree pattern in <seealso cref="ParseTree"/> form. </param>
+ ParseTreePattern(ParseTreePatternMatcher *matcher, const std::string &pattern, int patternRuleIndex,
+ ParseTree *patternTree);
+ ParseTreePattern(ParseTreePattern const&) = default;
+ virtual ~ParseTreePattern();
+
+ /// <summary>
+ /// Match a specific parse tree against this tree pattern.
+ /// </summary>
+ /// <param name="tree"> The parse tree to match against this tree pattern. </param>
+ /// <returns> A <seealso cref="ParseTreeMatch"/> object describing the result of the
+ /// match operation. The <seealso cref="ParseTreeMatch#succeeded()"/> method can be
+ /// used to determine whether or not the match was successful. </returns>
+ virtual ParseTreeMatch match(ParseTree *tree);
+
+ /// <summary>
+ /// Determine whether or not a parse tree matches this tree pattern.
+ /// </summary>
+ /// <param name="tree"> The parse tree to match against this tree pattern. </param>
+ /// <returns> {@code true} if {@code tree} is a match for the current tree
+ /// pattern; otherwise, {@code false}. </returns>
+ virtual bool matches(ParseTree *tree);
+
+ /// Find all nodes using XPath and then try to match those subtrees against
+ /// this tree pattern.
+ /// @param tree The ParseTree to match against this pattern.
+ /// @param xpath An expression matching the nodes
+ ///
+ /// @returns A collection of ParseTreeMatch objects describing the
+ /// successful matches. Unsuccessful matches are omitted from the result,
+ /// regardless of the reason for the failure.
+ virtual std::vector<ParseTreeMatch> findAll(ParseTree *tree, const std::string &xpath);
+
+ /// <summary>
+ /// Get the <seealso cref="ParseTreePatternMatcher"/> which created this tree pattern.
+ /// </summary>
+ /// <returns> The <seealso cref="ParseTreePatternMatcher"/> which created this tree
+ /// pattern. </returns>
+ virtual ParseTreePatternMatcher *getMatcher() const;
+
+ /// <summary>
+ /// Get the tree pattern in concrete syntax form.
+ /// </summary>
+ /// <returns> The tree pattern in concrete syntax form. </returns>
+ virtual std::string getPattern() const;
+
+ /// <summary>
+ /// Get the parser rule which serves as the outermost rule for the tree
+ /// pattern.
+ /// </summary>
+ /// <returns> The parser rule which serves as the outermost rule for the tree
+ /// pattern. </returns>
+ virtual int getPatternRuleIndex() const;
+
+ /// <summary>
+ /// Get the tree pattern as a <seealso cref="ParseTree"/>. The rule and token tags from
+ /// the pattern are present in the parse tree as terminal nodes with a symbol
+ /// of type <seealso cref="RuleTagToken"/> or <seealso cref="TokenTagToken"/>.
+ /// </summary>
+ /// <returns> The tree pattern as a <seealso cref="ParseTree"/>. </returns>
+ virtual ParseTree* getPatternTree() const;
+
+ private:
+ const int patternRuleIndex;
+
+ /// This is the backing field for <seealso cref="#getPattern()"/>.
+ const std::string _pattern;
+
+ /// This is the backing field for <seealso cref="#getPatternTree()"/>.
+ ParseTree *_patternTree;
+
+ /// This is the backing field for <seealso cref="#getMatcher()"/>.
+ ParseTreePatternMatcher *const _matcher;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.cpp
new file mode 100644
index 0000000..2e58a96
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.cpp
@@ -0,0 +1,371 @@
+/* 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.
+ */
+
+#include "tree/pattern/ParseTreePattern.h"
+#include "tree/pattern/ParseTreeMatch.h"
+#include "tree/TerminalNode.h"
+#include "CommonTokenStream.h"
+#include "ParserInterpreter.h"
+#include "tree/pattern/TokenTagToken.h"
+#include "ParserRuleContext.h"
+#include "tree/pattern/RuleTagToken.h"
+#include "tree/pattern/TagChunk.h"
+#include "atn/ATN.h"
+#include "Lexer.h"
+#include "BailErrorStrategy.h"
+
+#include "ListTokenSource.h"
+#include "tree/pattern/TextChunk.h"
+#include "ANTLRInputStream.h"
+#include "support/Arrays.h"
+#include "Exceptions.h"
+#include "support/StringUtils.h"
+#include "support/CPPUtils.h"
+
+#include "tree/pattern/ParseTreePatternMatcher.h"
+
+using namespace antlr4;
+using namespace antlr4::tree;
+using namespace antlr4::tree::pattern;
+using namespace antlrcpp;
+
+ParseTreePatternMatcher::CannotInvokeStartRule::CannotInvokeStartRule(const RuntimeException &e) : RuntimeException(e.what()) {
+}
+
+ParseTreePatternMatcher::CannotInvokeStartRule::~CannotInvokeStartRule() {
+}
+
+ParseTreePatternMatcher::StartRuleDoesNotConsumeFullPattern::~StartRuleDoesNotConsumeFullPattern() {
+}
+
+ParseTreePatternMatcher::ParseTreePatternMatcher(Lexer *lexer, Parser *parser) : _lexer(lexer), _parser(parser) {
+ InitializeInstanceFields();
+}
+
+ParseTreePatternMatcher::~ParseTreePatternMatcher() {
+}
+
+void ParseTreePatternMatcher::setDelimiters(const std::string &start, const std::string &stop, const std::string &escapeLeft) {
+ if (start.empty()) {
+ throw IllegalArgumentException("start cannot be null or empty");
+ }
+
+ if (stop.empty()) {
+ throw IllegalArgumentException("stop cannot be null or empty");
+ }
+
+ _start = start;
+ _stop = stop;
+ _escape = escapeLeft;
+}
+
+bool ParseTreePatternMatcher::matches(ParseTree *tree, const std::string &pattern, int patternRuleIndex) {
+ ParseTreePattern p = compile(pattern, patternRuleIndex);
+ return matches(tree, p);
+}
+
+bool ParseTreePatternMatcher::matches(ParseTree *tree, const ParseTreePattern &pattern) {
+ std::map<std::string, std::vector<ParseTree *>> labels;
+ ParseTree *mismatchedNode = matchImpl(tree, pattern.getPatternTree(), labels);
+ return mismatchedNode == nullptr;
+}
+
+ParseTreeMatch ParseTreePatternMatcher::match(ParseTree *tree, const std::string &pattern, int patternRuleIndex) {
+ ParseTreePattern p = compile(pattern, patternRuleIndex);
+ return match(tree, p);
+}
+
+ParseTreeMatch ParseTreePatternMatcher::match(ParseTree *tree, const ParseTreePattern &pattern) {
+ std::map<std::string, std::vector<ParseTree *>> labels;
+ tree::ParseTree *mismatchedNode = matchImpl(tree, pattern.getPatternTree(), labels);
+ return ParseTreeMatch(tree, pattern, labels, mismatchedNode);
+}
+
+ParseTreePattern ParseTreePatternMatcher::compile(const std::string &pattern, int patternRuleIndex) {
+ ListTokenSource tokenSrc(tokenize(pattern));
+ CommonTokenStream tokens(&tokenSrc);
+
+ ParserInterpreter parserInterp(_parser->getGrammarFileName(), _parser->getVocabulary(),
+ _parser->getRuleNames(), _parser->getATNWithBypassAlts(), &tokens);
+
+ ParserRuleContext *tree = nullptr;
+ try {
+ parserInterp.setErrorHandler(std::make_shared<BailErrorStrategy>());
+ tree = parserInterp.parse(patternRuleIndex);
+ } catch (ParseCancellationException &e) {
+#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026
+ // rethrow_if_nested is not available before VS 2015.
+ throw e;
+#else
+ std::rethrow_if_nested(e); // Unwrap the nested exception.
+#endif
+ } catch (RecognitionException &re) {
+ throw re;
+#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026
+ } catch (std::exception &e) {
+ // throw_with_nested is not available before VS 2015.
+ throw e;
+#else
+ } catch (std::exception & /*e*/) {
+ std::throw_with_nested((const char*)"Cannot invoke start rule"); // Wrap any other exception. We should however probably use one of the ANTLR exceptions here.
+#endif
+ }
+
+ // Make sure tree pattern compilation checks for a complete parse
+ if (tokens.LA(1) != Token::EOF) {
+ throw StartRuleDoesNotConsumeFullPattern();
+ }
+
+ return ParseTreePattern(this, pattern, patternRuleIndex, tree);
+}
+
+Lexer* ParseTreePatternMatcher::getLexer() {
+ return _lexer;
+}
+
+Parser* ParseTreePatternMatcher::getParser() {
+ return _parser;
+}
+
+ParseTree* ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *patternTree,
+ std::map<std::string, std::vector<ParseTree *>> &labels) {
+ if (tree == nullptr) {
+ throw IllegalArgumentException("tree cannot be nul");
+ }
+
+ if (patternTree == nullptr) {
+ throw IllegalArgumentException("patternTree cannot be nul");
+ }
+
+ // x and <ID>, x and y, or x and x; or could be mismatched types
+ if (is<TerminalNode *>(tree) && is<TerminalNode *>(patternTree)) {
+ TerminalNode *t1 = dynamic_cast<TerminalNode *>(tree);
+ TerminalNode *t2 = dynamic_cast<TerminalNode *>(patternTree);
+
+ ParseTree *mismatchedNode = nullptr;
+ // both are tokens and they have same type
+ if (t1->getSymbol()->getType() == t2->getSymbol()->getType()) {
+ if (is<TokenTagToken *>(t2->getSymbol())) { // x and <ID>
+ TokenTagToken *tokenTagToken = dynamic_cast<TokenTagToken *>(t2->getSymbol());
+
+ // track label->list-of-nodes for both token name and label (if any)
+ labels[tokenTagToken->getTokenName()].push_back(tree);
+ if (tokenTagToken->getLabel() != "") {
+ labels[tokenTagToken->getLabel()].push_back(tree);
+ }
+ } else if (t1->getText() == t2->getText()) {
+ // x and x
+ } else {
+ // x and y
+ if (mismatchedNode == nullptr) {
+ mismatchedNode = t1;
+ }
+ }
+ } else {
+ if (mismatchedNode == nullptr) {
+ mismatchedNode = t1;
+ }
+ }
+
+ return mismatchedNode;
+ }
+
+ if (is<ParserRuleContext *>(tree) && is<ParserRuleContext *>(patternTree)) {
+ ParserRuleContext *r1 = dynamic_cast<ParserRuleContext *>(tree);
+ ParserRuleContext *r2 = dynamic_cast<ParserRuleContext *>(patternTree);
+ ParseTree *mismatchedNode = nullptr;
+
+ // (expr ...) and <expr>
+ RuleTagToken *ruleTagToken = getRuleTagToken(r2);
+ if (ruleTagToken != nullptr) {
+ //ParseTreeMatch *m = nullptr; // unused?
+ if (r1->getRuleIndex() == r2->getRuleIndex()) {
+ // track label->list-of-nodes for both rule name and label (if any)
+ labels[ruleTagToken->getRuleName()].push_back(tree);
+ if (ruleTagToken->getLabel() != "") {
+ labels[ruleTagToken->getLabel()].push_back(tree);
+ }
+ } else {
+ if (!mismatchedNode) {
+ mismatchedNode = r1;
+ }
+ }
+
+ return mismatchedNode;
+ }
+
+ // (expr ...) and (expr ...)
+ if (r1->children.size() != r2->children.size()) {
+ if (mismatchedNode == nullptr) {
+ mismatchedNode = r1;
+ }
+
+ return mismatchedNode;
+ }
+
+ std::size_t n = r1->children.size();
+ for (size_t i = 0; i < n; i++) {
+ ParseTree *childMatch = matchImpl(r1->children[i], patternTree->children[i], labels);
+ if (childMatch) {
+ return childMatch;
+ }
+ }
+
+ return mismatchedNode;
+ }
+
+ // if nodes aren't both tokens or both rule nodes, can't match
+ return tree;
+}
+
+RuleTagToken* ParseTreePatternMatcher::getRuleTagToken(ParseTree *t) {
+ if (t->children.size() == 1 && is<TerminalNode *>(t->children[0])) {
+ TerminalNode *c = dynamic_cast<TerminalNode *>(t->children[0]);
+ if (is<RuleTagToken *>(c->getSymbol())) {
+ return dynamic_cast<RuleTagToken *>(c->getSymbol());
+ }
+ }
+ return nullptr;
+}
+
+std::vector<std::unique_ptr<Token>> ParseTreePatternMatcher::tokenize(const std::string &pattern) {
+ // split pattern into chunks: sea (raw input) and islands (<ID>, <expr>)
+ std::vector<Chunk> chunks = split(pattern);
+
+ // create token stream from text and tags
+ std::vector<std::unique_ptr<Token>> tokens;
+ for (auto chunk : chunks) {
+ if (is<TagChunk *>(&chunk)) {
+ TagChunk &tagChunk = (TagChunk&)chunk;
+ // add special rule token or conjure up new token from name
+ if (isupper(tagChunk.getTag()[0])) {
+ size_t ttype = _parser->getTokenType(tagChunk.getTag());
+ if (ttype == Token::INVALID_TYPE) {
+ throw IllegalArgumentException("Unknown token " + tagChunk.getTag() + " in pattern: " + pattern);
+ }
+ tokens.emplace_back(new TokenTagToken(tagChunk.getTag(), (int)ttype, tagChunk.getLabel()));
+ } else if (islower(tagChunk.getTag()[0])) {
+ size_t ruleIndex = _parser->getRuleIndex(tagChunk.getTag());
+ if (ruleIndex == INVALID_INDEX) {
+ throw IllegalArgumentException("Unknown rule " + tagChunk.getTag() + " in pattern: " + pattern);
+ }
+ size_t ruleImaginaryTokenType = _parser->getATNWithBypassAlts().ruleToTokenType[ruleIndex];
+ tokens.emplace_back(new RuleTagToken(tagChunk.getTag(), ruleImaginaryTokenType, tagChunk.getLabel()));
+ } else {
+ throw IllegalArgumentException("invalid tag: " + tagChunk.getTag() + " in pattern: " + pattern);
+ }
+ } else {
+ TextChunk &textChunk = (TextChunk&)chunk;
+ ANTLRInputStream input(textChunk.getText());
+ _lexer->setInputStream(&input);
+ std::unique_ptr<Token> t(_lexer->nextToken());
+ while (t->getType() != Token::EOF) {
+ tokens.push_back(std::move(t));
+ t = _lexer->nextToken();
+ }
+ _lexer->setInputStream(nullptr);
+ }
+ }
+
+ return tokens;
+}
+
+std::vector<Chunk> ParseTreePatternMatcher::split(const std::string &pattern) {
+ size_t p = 0;
+ size_t n = pattern.length();
+ std::vector<Chunk> chunks;
+
+ // find all start and stop indexes first, then collect
+ std::vector<size_t> starts;
+ std::vector<size_t> stops;
+ while (p < n) {
+ if (p == pattern.find(_escape + _start,p)) {
+ p += _escape.length() + _start.length();
+ } else if (p == pattern.find(_escape + _stop,p)) {
+ p += _escape.length() + _stop.length();
+ } else if (p == pattern.find(_start,p)) {
+ starts.push_back(p);
+ p += _start.length();
+ } else if (p == pattern.find(_stop,p)) {
+ stops.push_back(p);
+ p += _stop.length();
+ } else {
+ p++;
+ }
+ }
+
+ if (starts.size() > stops.size()) {
+ throw IllegalArgumentException("unterminated tag in pattern: " + pattern);
+ }
+
+ if (starts.size() < stops.size()) {
+ throw IllegalArgumentException("missing start tag in pattern: " + pattern);
+ }
+
+ size_t ntags = starts.size();
+ for (size_t i = 0; i < ntags; i++) {
+ if (starts[i] >= stops[i]) {
+ throw IllegalArgumentException("tag delimiters out of order in pattern: " + pattern);
+ }
+ }
+
+ // collect into chunks now
+ if (ntags == 0) {
+ std::string text = pattern.substr(0, n);
+ chunks.push_back(TextChunk(text));
+ }
+
+ if (ntags > 0 && starts[0] > 0) { // copy text up to first tag into chunks
+ std::string text = pattern.substr(0, starts[0]);
+ chunks.push_back(TextChunk(text));
+ }
+
+ for (size_t i = 0; i < ntags; i++) {
+ // copy inside of <tag>
+ std::string tag = pattern.substr(starts[i] + _start.length(), stops[i] - (starts[i] + _start.length()));
+ std::string ruleOrToken = tag;
+ std::string label = "";
+ size_t colon = tag.find(':');
+ if (colon != std::string::npos) {
+ label = tag.substr(0,colon);
+ ruleOrToken = tag.substr(colon + 1, tag.length() - (colon + 1));
+ }
+ chunks.push_back(TagChunk(label, ruleOrToken));
+ if (i + 1 < ntags) {
+ // copy from end of <tag> to start of next
+ std::string text = pattern.substr(stops[i] + _stop.length(), starts[i + 1] - (stops[i] + _stop.length()));
+ chunks.push_back(TextChunk(text));
+ }
+ }
+
+ if (ntags > 0) {
+ size_t afterLastTag = stops[ntags - 1] + _stop.length();
+ if (afterLastTag < n) { // copy text from end of last tag to end
+ std::string text = pattern.substr(afterLastTag, n - afterLastTag);
+ chunks.push_back(TextChunk(text));
+ }
+ }
+
+ // strip out all backslashes from text chunks but not tags
+ for (size_t i = 0; i < chunks.size(); i++) {
+ Chunk &c = chunks[i];
+ if (is<TextChunk *>(&c)) {
+ TextChunk &tc = (TextChunk&)c;
+ std::string unescaped = tc.getText();
+ unescaped.erase(std::remove(unescaped.begin(), unescaped.end(), '\\'), unescaped.end());
+ if (unescaped.length() < tc.getText().length()) {
+ chunks[i] = TextChunk(unescaped);
+ }
+ }
+ }
+
+ return chunks;
+}
+
+void ParseTreePatternMatcher::InitializeInstanceFields() {
+ _start = "<";
+ _stop = ">";
+ _escape = "\\";
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.h
new file mode 100644
index 0000000..e77c7bc
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.h
@@ -0,0 +1,185 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "Exceptions.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A tree pattern matching mechanism for ANTLR <seealso cref="ParseTree"/>s.
+ /// <p/>
+ /// Patterns are strings of source input text with special tags representing
+ /// token or rule references such as:
+ /// <p/>
+ /// {@code <ID> = <expr>;}
+ /// <p/>
+ /// Given a pattern start rule such as {@code statement}, this object constructs
+ /// a <seealso cref="ParseTree"/> with placeholders for the {@code ID} and {@code expr}
+ /// subtree. Then the <seealso cref="#match"/> routines can compare an actual
+ /// <seealso cref="ParseTree"/> from a parse with this pattern. Tag {@code <ID>} matches
+ /// any {@code ID} token and tag {@code <expr>} references the result of the
+ /// {@code expr} rule (generally an instance of {@code ExprContext}.
+ /// <p/>
+ /// Pattern {@code x = 0;} is a similar pattern that matches the same pattern
+ /// except that it requires the identifier to be {@code x} and the expression to
+ /// be {@code 0}.
+ /// <p/>
+ /// The <seealso cref="#matches"/> routines return {@code true} or {@code false} based
+ /// upon a match for the tree rooted at the parameter sent in. The
+ /// <seealso cref="#match"/> routines return a <seealso cref="ParseTreeMatch"/> object that
+ /// contains the parse tree, the parse tree pattern, and a map from tag name to
+ /// matched nodes (more below). A subtree that fails to match, returns with
+ /// <seealso cref="ParseTreeMatch#mismatchedNode"/> set to the first tree node that did not
+ /// match.
+ /// <p/>
+ /// For efficiency, you can compile a tree pattern in string form to a
+ /// <seealso cref="ParseTreePattern"/> object.
+ /// <p/>
+ /// See {@code TestParseTreeMatcher} for lots of examples.
+ /// <seealso cref="ParseTreePattern"/> has two static helper methods:
+ /// <seealso cref="ParseTreePattern#findAll"/> and <seealso cref="ParseTreePattern#match"/> that
+ /// are easy to use but not super efficient because they create new
+ /// <seealso cref="ParseTreePatternMatcher"/> objects each time and have to compile the
+ /// pattern in string form before using it.
+ /// <p/>
+ /// The lexer and parser that you pass into the <seealso cref="ParseTreePatternMatcher"/>
+ /// constructor are used to parse the pattern in string form. The lexer converts
+ /// the {@code <ID> = <expr>;} into a sequence of four tokens (assuming lexer
+ /// throws out whitespace or puts it on a hidden channel). Be aware that the
+ /// input stream is reset for the lexer (but not the parser; a
+ /// <seealso cref="ParserInterpreter"/> is created to parse the input.). Any user-defined
+ /// fields you have put into the lexer might get changed when this mechanism asks
+ /// it to scan the pattern string.
+ /// <p/>
+ /// Normally a parser does not accept token {@code <expr>} as a valid
+ /// {@code expr} but, from the parser passed in, we create a special version of
+ /// the underlying grammar representation (an <seealso cref="ATN"/>) that allows imaginary
+ /// tokens representing rules ({@code <expr>}) to match entire rules. We call
+ /// these <em>bypass alternatives</em>.
+ /// <p/>
+ /// Delimiters are {@code <} and {@code >}, with {@code \} as the escape string
+ /// by default, but you can set them to whatever you want using
+ /// <seealso cref="#setDelimiters"/>. You must escape both start and stop strings
+ /// {@code \<} and {@code \>}.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ParseTreePatternMatcher {
+ public:
+ class CannotInvokeStartRule : public RuntimeException {
+ public:
+ CannotInvokeStartRule(const RuntimeException &e);
+ ~CannotInvokeStartRule();
+ };
+
+ // Fixes https://github.com/antlr/antlr4/issues/413
+ // "Tree pattern compilation doesn't check for a complete parse"
+ class StartRuleDoesNotConsumeFullPattern : public RuntimeException {
+ public:
+ StartRuleDoesNotConsumeFullPattern() = default;
+ StartRuleDoesNotConsumeFullPattern(StartRuleDoesNotConsumeFullPattern const&) = default;
+ ~StartRuleDoesNotConsumeFullPattern();
+
+ StartRuleDoesNotConsumeFullPattern& operator=(StartRuleDoesNotConsumeFullPattern const&) = default;
+ };
+
+ /// Constructs a <seealso cref="ParseTreePatternMatcher"/> or from a <seealso cref="Lexer"/> and
+ /// <seealso cref="Parser"/> object. The lexer input stream is altered for tokenizing
+ /// the tree patterns. The parser is used as a convenient mechanism to get
+ /// the grammar name, plus token, rule names.
+ ParseTreePatternMatcher(Lexer *lexer, Parser *parser);
+ virtual ~ParseTreePatternMatcher();
+
+ /// <summary>
+ /// Set the delimiters used for marking rule and token tags within concrete
+ /// syntax used by the tree pattern parser.
+ /// </summary>
+ /// <param name="start"> The start delimiter. </param>
+ /// <param name="stop"> The stop delimiter. </param>
+ /// <param name="escapeLeft"> The escape sequence to use for escaping a start or stop delimiter.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code start} is {@code null} or empty. </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code stop} is {@code null} or empty. </exception>
+ virtual void setDelimiters(const std::string &start, const std::string &stop, const std::string &escapeLeft);
+
+ /// <summary>
+ /// Does {@code pattern} matched as rule {@code patternRuleIndex} match {@code tree}? </summary>
+ virtual bool matches(ParseTree *tree, const std::string &pattern, int patternRuleIndex);
+
+ /// <summary>
+ /// Does {@code pattern} matched as rule patternRuleIndex match tree? Pass in a
+ /// compiled pattern instead of a string representation of a tree pattern.
+ /// </summary>
+ virtual bool matches(ParseTree *tree, const ParseTreePattern &pattern);
+
+ /// <summary>
+ /// Compare {@code pattern} matched as rule {@code patternRuleIndex} against
+ /// {@code tree} and return a <seealso cref="ParseTreeMatch"/> object that contains the
+ /// matched elements, or the node at which the match failed.
+ /// </summary>
+ virtual ParseTreeMatch match(ParseTree *tree, const std::string &pattern, int patternRuleIndex);
+
+ /// <summary>
+ /// Compare {@code pattern} matched against {@code tree} and return a
+ /// <seealso cref="ParseTreeMatch"/> object that contains the matched elements, or the
+ /// node at which the match failed. Pass in a compiled pattern instead of a
+ /// string representation of a tree pattern.
+ /// </summary>
+ virtual ParseTreeMatch match(ParseTree *tree, const ParseTreePattern &pattern);
+
+ /// <summary>
+ /// For repeated use of a tree pattern, compile it to a
+ /// <seealso cref="ParseTreePattern"/> using this method.
+ /// </summary>
+ virtual ParseTreePattern compile(const std::string &pattern, int patternRuleIndex);
+
+ /// <summary>
+ /// Used to convert the tree pattern string into a series of tokens. The
+ /// input stream is reset.
+ /// </summary>
+ virtual Lexer* getLexer();
+
+ /// <summary>
+ /// Used to collect to the grammar file name, token names, rule names for
+ /// used to parse the pattern into a parse tree.
+ /// </summary>
+ virtual Parser* getParser();
+
+ // ---- SUPPORT CODE ----
+
+ virtual std::vector<std::unique_ptr<Token>> tokenize(const std::string &pattern);
+
+ /// Split "<ID> = <e:expr>;" into 4 chunks for tokenizing by tokenize().
+ virtual std::vector<Chunk> split(const std::string &pattern);
+
+ protected:
+ std::string _start;
+ std::string _stop;
+ std::string _escape; // e.g., \< and \> must escape BOTH!
+
+ /// Recursively walk {@code tree} against {@code patternTree}, filling
+ /// {@code match.}<seealso cref="ParseTreeMatch#labels labels"/>.
+ ///
+ /// <returns> the first node encountered in {@code tree} which does not match
+ /// a corresponding node in {@code patternTree}, or {@code null} if the match
+ /// was successful. The specific node returned depends on the matching
+ /// algorithm used by the implementation, and may be overridden. </returns>
+ virtual ParseTree* matchImpl(ParseTree *tree, ParseTree *patternTree, std::map<std::string, std::vector<ParseTree *>> &labels);
+
+ /// Is t <expr> subtree?
+ virtual RuleTagToken* getRuleTagToken(ParseTree *t);
+
+ private:
+ Lexer *_lexer;
+ Parser *_parser;
+
+ void InitializeInstanceFields();
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.cpp
new file mode 100644
index 0000000..4e33f98
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.cpp
@@ -0,0 +1,77 @@
+/* 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.
+ */
+
+#include "Exceptions.h"
+
+#include "tree/pattern/RuleTagToken.h"
+
+using namespace antlr4::tree::pattern;
+
+RuleTagToken::RuleTagToken(const std::string &/*ruleName*/, int _bypassTokenType) : bypassTokenType(_bypassTokenType) {
+}
+
+RuleTagToken::RuleTagToken(const std::string &ruleName, size_t bypassTokenType, const std::string &label)
+ : ruleName(ruleName), bypassTokenType(bypassTokenType), label(label) {
+ if (ruleName.empty()) {
+ throw IllegalArgumentException("ruleName cannot be null or empty.");
+ }
+
+}
+
+std::string RuleTagToken::getRuleName() const {
+ return ruleName;
+}
+
+std::string RuleTagToken::getLabel() const {
+ return label;
+}
+
+size_t RuleTagToken::getChannel() const {
+ return DEFAULT_CHANNEL;
+}
+
+std::string RuleTagToken::getText() const {
+ if (label != "") {
+ return std::string("<") + label + std::string(":") + ruleName + std::string(">");
+ }
+
+ return std::string("<") + ruleName + std::string(">");
+}
+
+size_t RuleTagToken::getType() const {
+ return bypassTokenType;
+}
+
+size_t RuleTagToken::getLine() const {
+ return 0;
+}
+
+size_t RuleTagToken::getCharPositionInLine() const {
+ return INVALID_INDEX;
+}
+
+size_t RuleTagToken::getTokenIndex() const {
+ return INVALID_INDEX;
+}
+
+size_t RuleTagToken::getStartIndex() const {
+ return INVALID_INDEX;
+}
+
+size_t RuleTagToken::getStopIndex() const {
+ return INVALID_INDEX;
+}
+
+antlr4::TokenSource *RuleTagToken::getTokenSource() const {
+ return nullptr;
+}
+
+antlr4::CharStream *RuleTagToken::getInputStream() const {
+ return nullptr;
+}
+
+std::string RuleTagToken::toString() const {
+ return ruleName + ":" + std::to_string(bypassTokenType);
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.h
new file mode 100644
index 0000000..368ae41
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.h
@@ -0,0 +1,117 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "Token.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A <seealso cref="Token"/> object representing an entire subtree matched by a parser
+ /// rule; e.g., {@code <expr>}. These tokens are created for <seealso cref="TagChunk"/>
+ /// chunks where the tag corresponds to a parser rule.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC RuleTagToken : public Token {
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getRuleName"/>.
+ /// </summary>
+ private:
+ const std::string ruleName;
+
+ /// The token type for the current token. This is the token type assigned to
+ /// the bypass alternative for the rule during ATN deserialization.
+ const size_t bypassTokenType;
+
+ /// This is the backing field for <seealso cref="#getLabe"/>.
+ const std::string label;
+
+ public:
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="RuleTagToken"/> with the specified rule
+ /// name and bypass token type and no label.
+ /// </summary>
+ /// <param name="ruleName"> The name of the parser rule this rule tag matches. </param>
+ /// <param name="bypassTokenType"> The bypass token type assigned to the parser rule.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code ruleName} is {@code null}
+ /// or empty. </exception>
+ RuleTagToken(const std::string &ruleName, int bypassTokenType); //this(ruleName, bypassTokenType, nullptr);
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="RuleTagToken"/> with the specified rule
+ /// name, bypass token type, and label.
+ /// </summary>
+ /// <param name="ruleName"> The name of the parser rule this rule tag matches. </param>
+ /// <param name="bypassTokenType"> The bypass token type assigned to the parser rule. </param>
+ /// <param name="label"> The label associated with the rule tag, or {@code null} if
+ /// the rule tag is unlabeled.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code ruleName} is {@code null}
+ /// or empty. </exception>
+ RuleTagToken(const std::string &ruleName, size_t bypassTokenType, const std::string &label);
+
+ /// <summary>
+ /// Gets the name of the rule associated with this rule tag.
+ /// </summary>
+ /// <returns> The name of the parser rule associated with this rule tag. </returns>
+ std::string getRuleName() const;
+
+ /// <summary>
+ /// Gets the label associated with the rule tag.
+ /// </summary>
+ /// <returns> The name of the label associated with the rule tag, or
+ /// {@code null} if this is an unlabeled rule tag. </returns>
+ std::string getLabel() const;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// Rule tag tokens are always placed on the <seealso cref="#DEFAULT_CHANNE"/>.
+ /// </summary>
+ virtual size_t getChannel() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// This method returns the rule tag formatted with {@code <} and {@code >}
+ /// delimiters.
+ /// </summary>
+ virtual std::string getText() const override;
+
+ /// Rule tag tokens have types assigned according to the rule bypass
+ /// transitions created during ATN deserialization.
+ virtual size_t getType() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns 0.
+ virtual size_t getLine() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getCharPositionInLine() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getTokenIndex() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getStartIndex() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getStopIndex() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns {@code null}.
+ virtual TokenSource *getTokenSource() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns {@code null}.
+ virtual CharStream *getInputStream() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> returns a string of the form {@code ruleName:bypassTokenType}.
+ virtual std::string toString() const override;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.cpp
new file mode 100644
index 0000000..77f2b4c
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.cpp
@@ -0,0 +1,39 @@
+/* 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.
+ */
+
+#include "Exceptions.h"
+
+#include "tree/pattern/TagChunk.h"
+
+using namespace antlr4::tree::pattern;
+
+TagChunk::TagChunk(const std::string &tag) : TagChunk("", tag) {
+}
+
+TagChunk::TagChunk(const std::string &label, const std::string &tag) : _tag(tag), _label(label) {
+ if (tag.empty()) {
+ throw IllegalArgumentException("tag cannot be null or empty");
+ }
+
+}
+
+TagChunk::~TagChunk() {
+}
+
+std::string TagChunk::getTag() {
+ return _tag;
+}
+
+std::string TagChunk::getLabel() {
+ return _label;
+}
+
+std::string TagChunk::toString() {
+ if (!_label.empty()) {
+ return _label + ":" + _tag;
+ }
+
+ return _tag;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.h
new file mode 100644
index 0000000..3d0c9f8
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.h
@@ -0,0 +1,86 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "Chunk.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// Represents a placeholder tag in a tree pattern. A tag can have any of the
+ /// following forms.
+ ///
+ /// <ul>
+ /// <li>{@code expr}: An unlabeled placeholder for a parser rule {@code expr}.</li>
+ /// <li>{@code ID}: An unlabeled placeholder for a token of type {@code ID}.</li>
+ /// <li>{@code e:expr}: A labeled placeholder for a parser rule {@code expr}.</li>
+ /// <li>{@code id:ID}: A labeled placeholder for a token of type {@code ID}.</li>
+ /// </ul>
+ ///
+ /// This class does not perform any validation on the tag or label names aside
+ /// from ensuring that the tag is a non-null, non-empty string.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TagChunk : public Chunk {
+ public:
+ /// <summary>
+ /// Construct a new instance of <seealso cref="TagChunk"/> using the specified tag and
+ /// no label.
+ /// </summary>
+ /// <param name="tag"> The tag, which should be the name of a parser rule or token
+ /// type.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code tag} is {@code null} or
+ /// empty. </exception>
+ TagChunk(const std::string &tag);
+ virtual ~TagChunk();
+
+ /// <summary>
+ /// Construct a new instance of <seealso cref="TagChunk"/> using the specified label
+ /// and tag.
+ /// </summary>
+ /// <param name="label"> The label for the tag. If this is {@code null}, the
+ /// <seealso cref="TagChunk"/> represents an unlabeled tag. </param>
+ /// <param name="tag"> The tag, which should be the name of a parser rule or token
+ /// type.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code tag} is {@code null} or
+ /// empty. </exception>
+ TagChunk(const std::string &label, const std::string &tag);
+
+ /// <summary>
+ /// Get the tag for this chunk.
+ /// </summary>
+ /// <returns> The tag for the chunk. </returns>
+ std::string getTag();
+
+ /// <summary>
+ /// Get the label, if any, assigned to this chunk.
+ /// </summary>
+ /// <returns> The label assigned to this chunk, or {@code null} if no label is
+ /// assigned to the chunk. </returns>
+ std::string getLabel();
+
+ /// <summary>
+ /// This method returns a text representation of the tag chunk. Labeled tags
+ /// are returned in the form {@code label:tag}, and unlabeled tags are
+ /// returned as just the tag name.
+ /// </summary>
+ virtual std::string toString() override;
+
+ private:
+ /// This is the backing field for <seealso cref="#getTag"/>.
+ const std::string _tag;
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getLabe"/>.
+ /// </summary>
+ const std::string _label;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.cpp
new file mode 100644
index 0000000..f8dcfb0
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.cpp
@@ -0,0 +1,28 @@
+/* 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.
+ */
+
+#include "Exceptions.h"
+
+#include "tree/pattern/TextChunk.h"
+
+using namespace antlr4::tree::pattern;
+
+TextChunk::TextChunk(const std::string &text) : text(text) {
+ if (text == "") {
+ throw IllegalArgumentException("text cannot be nul");
+ }
+
+}
+
+TextChunk::~TextChunk() {
+}
+
+std::string TextChunk::getText() {
+ return text;
+}
+
+std::string TextChunk::toString() {
+ return std::string("'") + text + std::string("'");
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.h
new file mode 100644
index 0000000..1cbc0dd
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.h
@@ -0,0 +1,51 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "Chunk.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// Represents a span of raw text (concrete syntax) between tags in a tree
+ /// pattern string.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TextChunk : public Chunk {
+ private:
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getText"/>.
+ /// </summary>
+ const std::string text;
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="TextChunk"/> with the specified text.
+ /// </summary>
+ /// <param name="text"> The text of this chunk. </param>
+ /// <exception cref="IllegalArgumentException"> if {@code text} is {@code null}. </exception>
+ public:
+ TextChunk(const std::string &text);
+ virtual ~TextChunk();
+
+ /// <summary>
+ /// Gets the raw text of this chunk.
+ /// </summary>
+ /// <returns> The text of the chunk. </returns>
+ std::string getText();
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The implementation for <seealso cref="TextChunk"/> returns the result of
+ /// <seealso cref="#getText()"/> in single quotes.
+ /// </summary>
+ virtual std::string toString() override;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.cpp
new file mode 100644
index 0000000..7d6cc9a
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.cpp
@@ -0,0 +1,36 @@
+/* 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.
+ */
+
+#include "tree/pattern/TokenTagToken.h"
+
+using namespace antlr4::tree::pattern;
+
+TokenTagToken::TokenTagToken(const std::string &/*tokenName*/, int type)
+ : CommonToken(type), tokenName(""), label("") {
+}
+
+TokenTagToken::TokenTagToken(const std::string &tokenName, int type, const std::string &label)
+ : CommonToken(type), tokenName(tokenName), label(label) {
+}
+
+std::string TokenTagToken::getTokenName() const {
+ return tokenName;
+}
+
+std::string TokenTagToken::getLabel() const {
+ return label;
+}
+
+std::string TokenTagToken::getText() const {
+ if (!label.empty()) {
+ return "<" + label + ":" + tokenName + ">";
+ }
+
+ return "<" + tokenName + ">";
+}
+
+std::string TokenTagToken::toString() const {
+ return tokenName + ":" + std::to_string(_type);
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.h
new file mode 100644
index 0000000..9013fb8
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.h
@@ -0,0 +1,80 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "CommonToken.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A <seealso cref="Token"/> object representing a token of a particular type; e.g.,
+ /// {@code <ID>}. These tokens are created for <seealso cref="TagChunk"/> chunks where the
+ /// tag corresponds to a lexer rule or token type.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TokenTagToken : public CommonToken {
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getTokenName"/>.
+ /// </summary>
+ private:
+ const std::string tokenName;
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getLabe"/>.
+ /// </summary>
+ const std::string label;
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="TokenTagToken"/> for an unlabeled tag
+ /// with the specified token name and type.
+ /// </summary>
+ /// <param name="tokenName"> The token name. </param>
+ /// <param name="type"> The token type. </param>
+ public:
+ TokenTagToken(const std::string &tokenName, int type); //this(tokenName, type, nullptr);
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="TokenTagToken"/> with the specified
+ /// token name, type, and label.
+ /// </summary>
+ /// <param name="tokenName"> The token name. </param>
+ /// <param name="type"> The token type. </param>
+ /// <param name="label"> The label associated with the token tag, or {@code null} if
+ /// the token tag is unlabeled. </param>
+ TokenTagToken(const std::string &tokenName, int type, const std::string &label);
+
+ /// <summary>
+ /// Gets the token name. </summary>
+ /// <returns> The token name. </returns>
+ std::string getTokenName() const;
+
+ /// <summary>
+ /// Gets the label associated with the rule tag.
+ /// </summary>
+ /// <returns> The name of the label associated with the rule tag, or
+ /// {@code null} if this is an unlabeled rule tag. </returns>
+ std::string getLabel() const;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The implementation for <seealso cref="TokenTagToken"/> returns the token tag
+ /// formatted with {@code <} and {@code >} delimiters.
+ /// </summary>
+ virtual std::string getText() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The implementation for <seealso cref="TokenTagToken"/> returns a string of the form
+ /// {@code tokenName:type}.
+ /// </summary>
+ virtual std::string toString() const override;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.cpp
new file mode 100644
index 0000000..c039896
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.cpp
@@ -0,0 +1,154 @@
+/* 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.
+ */
+
+#include "XPathLexer.h"
+#include "XPathLexerErrorListener.h"
+#include "XPathElement.h"
+#include "XPathWildcardAnywhereElement.h"
+#include "XPathWildcardElement.h"
+#include "XPathTokenAnywhereElement.h"
+#include "XPathTokenElement.h"
+#include "XPathRuleAnywhereElement.h"
+#include "XPathRuleElement.h"
+
+#include "XPath.h"
+
+using namespace antlr4;
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+const std::string XPath::WILDCARD = "*";
+const std::string XPath::NOT = "!";
+
+XPath::XPath(Parser *parser, const std::string &path) {
+ _parser = parser;
+ _path = path;
+}
+
+std::vector<std::unique_ptr<XPathElement>> XPath::split(const std::string &path) {
+ ANTLRInputStream in(path);
+ XPathLexer lexer(&in);
+ lexer.removeErrorListeners();
+ XPathLexerErrorListener listener;
+ lexer.addErrorListener(&listener);
+ CommonTokenStream tokenStream(&lexer);
+ try {
+ tokenStream.fill();
+ } catch (LexerNoViableAltException &) {
+ size_t pos = lexer.getCharPositionInLine();
+ std::string msg = "Invalid tokens or characters at index " + std::to_string(pos) + " in path '" + path + "'";
+ throw IllegalArgumentException(msg);
+ }
+
+ std::vector<Token *> tokens = tokenStream.getTokens();
+ std::vector<std::unique_ptr<XPathElement>> elements;
+ size_t n = tokens.size();
+ size_t i = 0;
+ bool done = false;
+ while (!done && i < n) {
+ Token *el = tokens[i];
+ Token *next = nullptr;
+ switch (el->getType()) {
+ case XPathLexer::ROOT:
+ case XPathLexer::ANYWHERE: {
+ bool anywhere = el->getType() == XPathLexer::ANYWHERE;
+ i++;
+ next = tokens[i];
+ bool invert = next->getType() == XPathLexer::BANG;
+ if (invert) {
+ i++;
+ next = tokens[i];
+ }
+ std::unique_ptr<XPathElement> pathElement = getXPathElement(next, anywhere);
+ pathElement->setInvert(invert);
+ elements.push_back(std::move(pathElement));
+ i++;
+ break;
+
+ }
+ case XPathLexer::TOKEN_REF:
+ case XPathLexer::RULE_REF:
+ case XPathLexer::WILDCARD:
+ elements.push_back(getXPathElement(el, false));
+ i++;
+ break;
+
+ case Token::EOF:
+ done = true;
+ break;
+
+ default :
+ throw IllegalArgumentException("Unknown path element " + el->toString());
+ }
+ }
+
+ return elements;
+}
+
+std::unique_ptr<XPathElement> XPath::getXPathElement(Token *wordToken, bool anywhere) {
+ if (wordToken->getType() == Token::EOF) {
+ throw IllegalArgumentException("Missing path element at end of path");
+ }
+
+ std::string word = wordToken->getText();
+ size_t ttype = _parser->getTokenType(word);
+ ssize_t ruleIndex = _parser->getRuleIndex(word);
+ switch (wordToken->getType()) {
+ case XPathLexer::WILDCARD :
+ if (anywhere)
+ return std::unique_ptr<XPathWildcardAnywhereElement>(new XPathWildcardAnywhereElement());
+ return std::unique_ptr<XPathWildcardElement>(new XPathWildcardElement());
+
+ case XPathLexer::TOKEN_REF:
+ case XPathLexer::STRING :
+ if (ttype == Token::INVALID_TYPE) {
+ throw IllegalArgumentException(word + " at index " + std::to_string(wordToken->getStartIndex()) + " isn't a valid token name");
+ }
+ if (anywhere)
+ return std::unique_ptr<XPathTokenAnywhereElement>(new XPathTokenAnywhereElement(word, (int)ttype));
+ return std::unique_ptr<XPathTokenElement>(new XPathTokenElement(word, (int)ttype));
+
+ default :
+ if (ruleIndex == -1) {
+ throw IllegalArgumentException(word + " at index " + std::to_string(wordToken->getStartIndex()) + " isn't a valid rule name");
+ }
+ if (anywhere)
+ return std::unique_ptr<XPathRuleAnywhereElement>(new XPathRuleAnywhereElement(word, (int)ruleIndex));
+ return std::unique_ptr<XPathRuleElement>(new XPathRuleElement(word, (int)ruleIndex));
+ }
+}
+
+static ParserRuleContext dummyRoot;
+
+std::vector<ParseTree *> XPath::findAll(ParseTree *tree, std::string const& xpath, Parser *parser) {
+ XPath p(parser, xpath);
+ return p.evaluate(tree);
+}
+
+std::vector<ParseTree *> XPath::evaluate(ParseTree *t) {
+ dummyRoot.children = { t }; // don't set t's parent.
+
+ std::vector<ParseTree *> work = { &dummyRoot };
+
+ size_t i = 0;
+ std::vector<std::unique_ptr<XPathElement>> elements = split(_path);
+
+ while (i < elements.size()) {
+ std::vector<ParseTree *> next;
+ for (auto *node : work) {
+ if (!node->children.empty()) {
+ // 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.
+ auto matching = elements[i]->evaluate(node);
+ next.insert(next.end(), matching.begin(), matching.end());
+ }
+ }
+ i++;
+ work = next;
+ }
+
+ return work;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.h
new file mode 100644
index 0000000..e38d482
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPath.h
@@ -0,0 +1,86 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ /// Represent a subset of XPath XML path syntax for use in identifying nodes in
+ /// parse trees.
+ ///
+ /// <para>
+ /// Split path into words and separators {@code /} and {@code //} 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.</para>
+ ///
+ /// <para>
+ /// The basic interface is
+ /// <seealso cref="XPath#findAll ParseTree.findAll"/>{@code (tree, pathString, parser)}.
+ /// But that is just shorthand for:</para>
+ ///
+ /// <pre>
+ /// <seealso cref="XPath"/> p = new <seealso cref="XPath#XPath XPath"/>(parser, pathString);
+ /// return p.<seealso cref="#evaluate evaluate"/>(tree);
+ /// </pre>
+ ///
+ /// <para>
+ /// See {@code org.antlr.v4.test.TestXPath} for descriptions. In short, this
+ /// allows operators:</para>
+ ///
+ /// <dl>
+ /// <dt>/</dt> <dd>root</dd>
+ /// <dt>//</dt> <dd>anywhere</dd>
+ /// <dt>!</dt> <dd>invert; this must appear directly after root or anywhere
+ /// operator</dd>
+ /// </dl>
+ ///
+ /// <para>
+ /// and path elements:</para>
+ ///
+ /// <dl>
+ /// <dt>ID</dt> <dd>token name</dd>
+ /// <dt>'string'</dt> <dd>any string literal token from the grammar</dd>
+ /// <dt>expr</dt> <dd>rule name</dd>
+ /// <dt>*</dt> <dd>wildcard matching any node</dd>
+ /// </dl>
+ ///
+ /// <para>
+ /// Whitespace is not allowed.</para>
+
+ class ANTLR4CPP_PUBLIC XPath {
+ public:
+ static const std::string WILDCARD; // word not operator/separator
+ static const std::string NOT; // word for invert operator
+
+ XPath(Parser *parser, const std::string &path);
+ virtual ~XPath() {}
+
+ // TODO: check for invalid token/rule names, bad syntax
+ virtual std::vector<std::unique_ptr<XPathElement>> split(const std::string &path);
+
+ static std::vector<ParseTree *> findAll(ParseTree *tree, std::string const& xpath, Parser *parser);
+
+ /// Return a list of all nodes starting at {@code t} as root that satisfy the
+ /// path. The root {@code /} is relative to the node passed to
+ /// <seealso cref="#evaluate"/>.
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t);
+
+ protected:
+ std::string _path;
+ Parser *_parser;
+
+ /// Convert word like {@code *} or {@code ID} or {@code expr} to a path
+ /// element. {@code anywhere} is {@code true} if {@code //} precedes the
+ /// word.
+ virtual std::unique_ptr<XPathElement> getXPathElement(Token *wordToken, bool anywhere);
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.cpp
new file mode 100644
index 0000000..64b122d
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.cpp
@@ -0,0 +1,31 @@
+/* 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.
+ */
+
+#include "support/CPPUtils.h"
+
+#include "XPathElement.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+XPathElement::XPathElement(const std::string &nodeName) {
+ _nodeName = nodeName;
+}
+
+XPathElement::~XPathElement() {
+}
+
+std::vector<ParseTree *> XPathElement::evaluate(ParseTree * /*t*/) {
+ return {};
+}
+
+std::string XPathElement::toString() const {
+ std::string inv = _invert ? "!" : "";
+ return antlrcpp::toString(*this) + "[" + inv + _nodeName + "]";
+}
+
+void XPathElement::setInvert(bool value) {
+ _invert = value;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.h
new file mode 100644
index 0000000..f339117
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathElement.h
@@ -0,0 +1,40 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+ class ParseTree;
+
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathElement {
+ public:
+ /// Construct element like {@code /ID} or {@code ID} or {@code /*} etc...
+ /// op is null if just node
+ XPathElement(const std::string &nodeName);
+ XPathElement(XPathElement const&) = default;
+ virtual ~XPathElement();
+
+ XPathElement& operator=(XPathElement const&) = default;
+
+ /// Given tree rooted at {@code t} return all nodes matched by this path
+ /// element.
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t);
+ virtual std::string toString() const;
+
+ void setInvert(bool value);
+
+ protected:
+ std::string _nodeName;
+ bool _invert = false;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.cpp
new file mode 100644
index 0000000..fb18788
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.cpp
@@ -0,0 +1,173 @@
+#include "XPathLexer.h"
+
+
+using namespace antlr4;
+
+
+XPathLexer::XPathLexer(CharStream *input) : Lexer(input) {
+ _interpreter = new atn::LexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);
+}
+
+XPathLexer::~XPathLexer() {
+ delete _interpreter;
+}
+
+std::string XPathLexer::getGrammarFileName() const {
+ return "XPathLexer.g4";
+}
+
+const std::vector<std::string>& XPathLexer::getRuleNames() const {
+ return _ruleNames;
+}
+
+const std::vector<std::string>& XPathLexer::getChannelNames() const {
+ return _channelNames;
+}
+
+const std::vector<std::string>& XPathLexer::getModeNames() const {
+ return _modeNames;
+}
+
+const std::vector<std::string>& XPathLexer::getTokenNames() const {
+ return _tokenNames;
+}
+
+dfa::Vocabulary& XPathLexer::getVocabulary() const {
+ return _vocabulary;
+}
+
+const std::vector<uint16_t> XPathLexer::getSerializedATN() const {
+ return _serializedATN;
+}
+
+const atn::ATN& XPathLexer::getATN() const {
+ return _atn;
+}
+
+
+void XPathLexer::action(RuleContext *context, size_t ruleIndex, size_t actionIndex) {
+ switch (ruleIndex) {
+ case 4: IDAction(dynamic_cast<antlr4::RuleContext *>(context), actionIndex); break;
+
+ default:
+ break;
+ }
+}
+
+void XPathLexer::IDAction(antlr4::RuleContext * /*context*/, size_t actionIndex) {
+ switch (actionIndex) {
+ case 0:
+ if (isupper(getText()[0]))
+ setType(TOKEN_REF);
+ else
+ setType(RULE_REF);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+// Static vars and initialization.
+std::vector<dfa::DFA> XPathLexer::_decisionToDFA;
+atn::PredictionContextCache XPathLexer::_sharedContextCache;
+
+// We own the ATN which in turn owns the ATN states.
+atn::ATN XPathLexer::_atn;
+std::vector<uint16_t> XPathLexer::_serializedATN;
+
+std::vector<std::string> XPathLexer::_ruleNames = {
+ "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID", "NameChar", "NameStartChar",
+ "STRING"
+};
+
+std::vector<std::string> XPathLexer::_channelNames = {
+ "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
+};
+
+std::vector<std::string> XPathLexer::_modeNames = {
+ "DEFAULT_MODE"
+};
+
+std::vector<std::string> XPathLexer::_literalNames = {
+ "", "", "", "'//'", "'/'", "'*'", "'!'"
+};
+
+std::vector<std::string> XPathLexer::_symbolicNames = {
+ "", "TOKEN_REF", "RULE_REF", "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID",
+ "STRING"
+};
+
+dfa::Vocabulary XPathLexer::_vocabulary(_literalNames, _symbolicNames);
+
+std::vector<std::string> XPathLexer::_tokenNames;
+
+XPathLexer::Initializer::Initializer() {
+ // This code could be in a static initializer lambda, but VS doesn't allow access to private class members from there.
+ for (size_t i = 0; i < _symbolicNames.size(); ++i) {
+ std::string name = _vocabulary.getLiteralName(i);
+ if (name.empty()) {
+ name = _vocabulary.getSymbolicName(i);
+ }
+
+ if (name.empty()) {
+ _tokenNames.push_back("<INVALID>");
+ } else {
+ _tokenNames.push_back(name);
+ }
+ }
+
+ _serializedATN = {
+ 0x3, 0x430, 0xd6d1, 0x8206, 0xad2d, 0x4417, 0xaef1, 0x8d80, 0xaadd,
+ 0x2, 0xa, 0x34, 0x8, 0x1, 0x4, 0x2, 0x9, 0x2, 0x4, 0x3, 0x9, 0x3, 0x4,
+ 0x4, 0x9, 0x4, 0x4, 0x5, 0x9, 0x5, 0x4, 0x6, 0x9, 0x6, 0x4, 0x7, 0x9,
+ 0x7, 0x4, 0x8, 0x9, 0x8, 0x4, 0x9, 0x9, 0x9, 0x3, 0x2, 0x3, 0x2, 0x3,
+ 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x4, 0x3, 0x5, 0x3, 0x5, 0x3,
+ 0x6, 0x3, 0x6, 0x7, 0x6, 0x1f, 0xa, 0x6, 0xc, 0x6, 0xe, 0x6, 0x22, 0xb,
+ 0x6, 0x3, 0x6, 0x3, 0x6, 0x3, 0x7, 0x3, 0x7, 0x5, 0x7, 0x28, 0xa, 0x7,
+ 0x3, 0x8, 0x3, 0x8, 0x3, 0x9, 0x3, 0x9, 0x7, 0x9, 0x2e, 0xa, 0x9, 0xc,
+ 0x9, 0xe, 0x9, 0x31, 0xb, 0x9, 0x3, 0x9, 0x3, 0x9, 0x3, 0x2f, 0x2, 0xa,
+ 0x3, 0x5, 0x5, 0x6, 0x7, 0x7, 0x9, 0x8, 0xb, 0x9, 0xd, 0x2, 0xf, 0x2,
+ 0x11, 0xa, 0x3, 0x2, 0x4, 0x7, 0x2, 0x32, 0x3b, 0x61, 0x61, 0xb9, 0xb9,
+ 0x302, 0x371, 0x2041, 0x2042, 0xf, 0x2, 0x43, 0x5c, 0x63, 0x7c, 0xc2,
+ 0xd8, 0xda, 0xf8, 0xfa, 0x301, 0x372, 0x37f, 0x381, 0x2001, 0x200e,
+ 0x200f, 0x2072, 0x2191, 0x2c02, 0x2ff1, 0x3003, 0xd801, 0xf902, 0xfdd1,
+ 0xfdf2, 0x1, 0x34, 0x2, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x5, 0x3, 0x2,
+ 0x2, 0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x9, 0x3, 0x2, 0x2, 0x2,
+ 0x2, 0xb, 0x3, 0x2, 0x2, 0x2, 0x2, 0x11, 0x3, 0x2, 0x2, 0x2, 0x3, 0x13,
+ 0x3, 0x2, 0x2, 0x2, 0x5, 0x16, 0x3, 0x2, 0x2, 0x2, 0x7, 0x18, 0x3, 0x2,
+ 0x2, 0x2, 0x9, 0x1a, 0x3, 0x2, 0x2, 0x2, 0xb, 0x1c, 0x3, 0x2, 0x2, 0x2,
+ 0xd, 0x27, 0x3, 0x2, 0x2, 0x2, 0xf, 0x29, 0x3, 0x2, 0x2, 0x2, 0x11,
+ 0x2b, 0x3, 0x2, 0x2, 0x2, 0x13, 0x14, 0x7, 0x31, 0x2, 0x2, 0x14, 0x15,
+ 0x7, 0x31, 0x2, 0x2, 0x15, 0x4, 0x3, 0x2, 0x2, 0x2, 0x16, 0x17, 0x7,
+ 0x31, 0x2, 0x2, 0x17, 0x6, 0x3, 0x2, 0x2, 0x2, 0x18, 0x19, 0x7, 0x2c,
+ 0x2, 0x2, 0x19, 0x8, 0x3, 0x2, 0x2, 0x2, 0x1a, 0x1b, 0x7, 0x23, 0x2,
+ 0x2, 0x1b, 0xa, 0x3, 0x2, 0x2, 0x2, 0x1c, 0x20, 0x5, 0xf, 0x8, 0x2,
+ 0x1d, 0x1f, 0x5, 0xd, 0x7, 0x2, 0x1e, 0x1d, 0x3, 0x2, 0x2, 0x2, 0x1f,
+ 0x22, 0x3, 0x2, 0x2, 0x2, 0x20, 0x1e, 0x3, 0x2, 0x2, 0x2, 0x20, 0x21,
+ 0x3, 0x2, 0x2, 0x2, 0x21, 0x23, 0x3, 0x2, 0x2, 0x2, 0x22, 0x20, 0x3,
+ 0x2, 0x2, 0x2, 0x23, 0x24, 0x8, 0x6, 0x2, 0x2, 0x24, 0xc, 0x3, 0x2,
+ 0x2, 0x2, 0x25, 0x28, 0x5, 0xf, 0x8, 0x2, 0x26, 0x28, 0x9, 0x2, 0x2,
+ 0x2, 0x27, 0x25, 0x3, 0x2, 0x2, 0x2, 0x27, 0x26, 0x3, 0x2, 0x2, 0x2,
+ 0x28, 0xe, 0x3, 0x2, 0x2, 0x2, 0x29, 0x2a, 0x9, 0x3, 0x2, 0x2, 0x2a,
+ 0x10, 0x3, 0x2, 0x2, 0x2, 0x2b, 0x2f, 0x7, 0x29, 0x2, 0x2, 0x2c, 0x2e,
+ 0xb, 0x2, 0x2, 0x2, 0x2d, 0x2c, 0x3, 0x2, 0x2, 0x2, 0x2e, 0x31, 0x3,
+ 0x2, 0x2, 0x2, 0x2f, 0x30, 0x3, 0x2, 0x2, 0x2, 0x2f, 0x2d, 0x3, 0x2,
+ 0x2, 0x2, 0x30, 0x32, 0x3, 0x2, 0x2, 0x2, 0x31, 0x2f, 0x3, 0x2, 0x2,
+ 0x2, 0x32, 0x33, 0x7, 0x29, 0x2, 0x2, 0x33, 0x12, 0x3, 0x2, 0x2, 0x2,
+ 0x6, 0x2, 0x20, 0x27, 0x2f, 0x3, 0x3, 0x6, 0x2,
+ };
+
+ atn::ATNDeserializer deserializer;
+ _atn = deserializer.deserialize(_serializedATN);
+
+ size_t count = _atn.getNumberOfDecisions();
+ _decisionToDFA.reserve(count);
+ for (size_t i = 0; i < count; i++) {
+ _decisionToDFA.emplace_back(_atn.getDecisionState(i), i);
+ }
+}
+
+XPathLexer::Initializer XPathLexer::_init;
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.g4 b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.g4
new file mode 100644
index 0000000..14bcf5a
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.g4
@@ -0,0 +1,64 @@
+lexer grammar XPathLexer;
+
+tokens { TOKEN_REF, RULE_REF }
+
+/*
+path : separator? word (separator word)* EOF ;
+
+separator
+ : '/' '!'
+ | '//' '!'
+ | '/'
+ | '//'
+ ;
+
+word: TOKEN_REF
+ | RULE_REF
+ | STRING
+ | '*'
+ ;
+*/
+
+ANYWHERE : '//' ;
+ROOT : '/' ;
+WILDCARD : '*' ;
+BANG : '!' ;
+
+ID : NameStartChar NameChar*
+ {
+ if (isupper(getText()[0]))
+ setType(TOKEN_REF);
+ else
+ setType(RULE_REF);
+ }
+ ;
+
+fragment
+NameChar : NameStartChar
+ | '0'..'9'
+ | '_'
+ | '\u00B7'
+ | '\u0300'..'\u036F'
+ | '\u203F'..'\u2040'
+ ;
+
+fragment
+NameStartChar
+ : 'A'..'Z' | 'a'..'z'
+ | '\u00C0'..'\u00D6'
+ | '\u00D8'..'\u00F6'
+ | '\u00F8'..'\u02FF'
+ | '\u0370'..'\u037D'
+ | '\u037F'..'\u1FFF'
+ | '\u200C'..'\u200D'
+ | '\u2070'..'\u218F'
+ | '\u2C00'..'\u2FEF'
+ | '\u3001'..'\uD7FF'
+ | '\uF900'..'\uFDCF'
+ | '\uFDF0'..'\uFFFF' // implicitly includes ['\u10000-'\uEFFFF]
+ ;
+
+STRING : '\'' .*? '\'';
+
+//WS : [ \t\r\n]+ -> skip ;
+
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.h
new file mode 100644
index 0000000..ca471c9
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.h
@@ -0,0 +1,56 @@
+#pragma once
+
+
+#include "antlr4-runtime.h"
+
+
+
+
+class XPathLexer : public antlr4::Lexer {
+public:
+ enum {
+ TOKEN_REF = 1, RULE_REF = 2, ANYWHERE = 3, ROOT = 4, WILDCARD = 5, BANG = 6,
+ ID = 7, STRING = 8
+ };
+
+ XPathLexer(antlr4::CharStream *input);
+ ~XPathLexer();
+
+ virtual std::string getGrammarFileName() const override;
+ virtual const std::vector<std::string>& getRuleNames() const override;
+
+ virtual const std::vector<std::string>& getChannelNames() const override;
+ virtual const std::vector<std::string>& getModeNames() const override;
+ virtual const std::vector<std::string>& getTokenNames() const override; // deprecated, use vocabulary instead
+ virtual antlr4::dfa::Vocabulary& getVocabulary() const override;
+
+ virtual const std::vector<uint16_t> getSerializedATN() const override;
+ virtual const antlr4::atn::ATN& getATN() const override;
+
+ virtual void action(antlr4::RuleContext *context, size_t ruleIndex, size_t actionIndex) override;
+private:
+ static std::vector<antlr4::dfa::DFA> _decisionToDFA;
+ static antlr4::atn::PredictionContextCache _sharedContextCache;
+ static std::vector<std::string> _ruleNames;
+ static std::vector<std::string> _tokenNames;
+ static std::vector<std::string> _channelNames;
+ static std::vector<std::string> _modeNames;
+
+ static std::vector<std::string> _literalNames;
+ static std::vector<std::string> _symbolicNames;
+ static antlr4::dfa::Vocabulary _vocabulary;
+ static antlr4::atn::ATN _atn;
+ static std::vector<uint16_t> _serializedATN;
+
+
+ // Individual action functions triggered by action() above.
+ void IDAction(antlr4::RuleContext *context, size_t actionIndex);
+
+ // Individual semantic predicate functions triggered by sempred() above.
+
+ struct Initializer {
+ Initializer();
+ };
+ static Initializer _init;
+};
+
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.tokens b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.tokens
new file mode 100644
index 0000000..5bf699e
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexer.tokens
@@ -0,0 +1,12 @@
+TOKEN_REF=1
+RULE_REF=2
+ANYWHERE=3
+ROOT=4
+WILDCARD=5
+BANG=6
+ID=7
+STRING=8
+'//'=3
+'/'=4
+'*'=5
+'!'=6
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.cpp
new file mode 100644
index 0000000..2804c8e
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.cpp
@@ -0,0 +1,13 @@
+/* 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.
+ */
+
+#include "XPathLexerErrorListener.h"
+
+using namespace antlr4;
+using namespace antlr4::tree::xpath;
+
+void XPathLexerErrorListener::syntaxError(Recognizer * /*recognizer*/, Token * /*offendingSymbol*/,
+ size_t /*line*/, size_t /*charPositionInLine*/, const std::string &/*msg*/, std::exception_ptr /*e*/) {
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.h
new file mode 100644
index 0000000..c0c3eaa
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathLexerErrorListener.h
@@ -0,0 +1,22 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "BaseErrorListener.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathLexerErrorListener : public BaseErrorListener {
+ public:
+ virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line,
+ size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.cpp
new file mode 100644
index 0000000..9ca910d
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.cpp
@@ -0,0 +1,20 @@
+/* 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.
+ */
+
+#include "tree/ParseTree.h"
+#include "tree/Trees.h"
+
+#include "tree/xpath/XPathRuleAnywhereElement.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+XPathRuleAnywhereElement::XPathRuleAnywhereElement(const std::string &ruleName, int ruleIndex) : XPathElement(ruleName) {
+ _ruleIndex = ruleIndex;
+}
+
+std::vector<ParseTree *> XPathRuleAnywhereElement::evaluate(ParseTree *t) {
+ return Trees::findAllRuleNodes(t, _ruleIndex);
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.h
new file mode 100644
index 0000000..2ceb75c
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleAnywhereElement.h
@@ -0,0 +1,27 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ /// Either {@code ID} at start of path or {@code ...//ID} in middle of path.
+ class ANTLR4CPP_PUBLIC XPathRuleAnywhereElement : public XPathElement {
+ public:
+ XPathRuleAnywhereElement(const std::string &ruleName, int ruleIndex);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+
+ protected:
+ int _ruleIndex = 0;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.cpp
new file mode 100644
index 0000000..1d145fb
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.cpp
@@ -0,0 +1,30 @@
+/* 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.
+ */
+
+#include "tree/ParseTree.h"
+#include "tree/Trees.h"
+
+#include "XPathRuleElement.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+XPathRuleElement::XPathRuleElement(const std::string &ruleName, size_t ruleIndex) : XPathElement(ruleName) {
+ _ruleIndex = ruleIndex;
+}
+
+std::vector<ParseTree *> XPathRuleElement::evaluate(ParseTree *t) {
+ // return all children of t that match nodeName
+ std::vector<ParseTree *> nodes;
+ for (auto *c : t->children) {
+ if (antlrcpp::is<ParserRuleContext *>(c)) {
+ ParserRuleContext *ctx = dynamic_cast<ParserRuleContext *>(c);
+ if ((ctx->getRuleIndex() == _ruleIndex && !_invert) || (ctx->getRuleIndex() != _ruleIndex && _invert)) {
+ nodes.push_back(ctx);
+ }
+ }
+ }
+ return nodes;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.h
new file mode 100644
index 0000000..b57276f
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathRuleElement.h
@@ -0,0 +1,26 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathRuleElement : public XPathElement {
+ public:
+ XPathRuleElement(const std::string &ruleName, size_t ruleIndex);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+
+ protected:
+ size_t _ruleIndex = 0;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.cpp
new file mode 100644
index 0000000..c557c9d
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.cpp
@@ -0,0 +1,20 @@
+/* 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.
+ */
+
+#include "tree/ParseTree.h"
+#include "tree/Trees.h"
+
+#include "XPathTokenAnywhereElement.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+XPathTokenAnywhereElement::XPathTokenAnywhereElement(const std::string &tokenName, int tokenType) : XPathElement(tokenName) {
+ this->tokenType = tokenType;
+}
+
+std::vector<ParseTree *> XPathTokenAnywhereElement::evaluate(ParseTree *t) {
+ return Trees::findAllTokenNodes(t, tokenType);
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.h
new file mode 100644
index 0000000..2045d91
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenAnywhereElement.h
@@ -0,0 +1,25 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathTokenAnywhereElement : public XPathElement {
+ protected:
+ int tokenType = 0;
+ public:
+ XPathTokenAnywhereElement(const std::string &tokenName, int tokenType);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.cpp
new file mode 100644
index 0000000..d52fc26
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.cpp
@@ -0,0 +1,33 @@
+/* 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.
+ */
+
+#include "tree/ParseTree.h"
+#include "tree/Trees.h"
+#include "support/CPPUtils.h"
+#include "Token.h"
+
+#include "XPathTokenElement.h"
+
+using namespace antlr4;
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+XPathTokenElement::XPathTokenElement(const std::string &tokenName, size_t tokenType) : XPathElement(tokenName) {
+ _tokenType = tokenType;
+}
+
+std::vector<ParseTree *> XPathTokenElement::evaluate(ParseTree *t) {
+ // return all children of t that match nodeName
+ std::vector<ParseTree *> nodes;
+ for (auto *c : t->children) {
+ if (antlrcpp::is<TerminalNode *>(c)) {
+ TerminalNode *tnode = dynamic_cast<TerminalNode *>(c);
+ if ((tnode->getSymbol()->getType() == _tokenType && !_invert) || (tnode->getSymbol()->getType() != _tokenType && _invert)) {
+ nodes.push_back(tnode);
+ }
+ }
+ }
+ return nodes;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.h
new file mode 100644
index 0000000..7221530
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathTokenElement.h
@@ -0,0 +1,26 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathTokenElement : public XPathElement {
+ public:
+ XPathTokenElement(const std::string &tokenName, size_t tokenType);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+
+ protected:
+ size_t _tokenType = 0;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.cpp
new file mode 100644
index 0000000..4ff424f
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.cpp
@@ -0,0 +1,23 @@
+/* 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.
+ */
+
+#include "XPath.h"
+#include "tree/ParseTree.h"
+#include "tree/Trees.h"
+
+#include "XPathWildcardAnywhereElement.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+XPathWildcardAnywhereElement::XPathWildcardAnywhereElement() : XPathElement(XPath::WILDCARD) {
+}
+
+std::vector<ParseTree *> XPathWildcardAnywhereElement::evaluate(ParseTree *t) {
+ if (_invert) {
+ return {}; // !* is weird but valid (empty)
+ }
+ return Trees::getDescendants(t);
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.h
new file mode 100644
index 0000000..dc5d1e5
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardAnywhereElement.h
@@ -0,0 +1,23 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathWildcardAnywhereElement : public XPathElement {
+ public:
+ XPathWildcardAnywhereElement();
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.cpp b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.cpp
new file mode 100644
index 0000000..aabda5a
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.cpp
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+#include "XPath.h"
+#include "tree/ParseTree.h"
+#include "tree/Trees.h"
+
+#include "XPathWildcardElement.h"
+
+using namespace antlr4::tree;
+using namespace antlr4::tree::xpath;
+
+XPathWildcardElement::XPathWildcardElement() : XPathElement(XPath::WILDCARD) {
+}
+
+std::vector<ParseTree *> XPathWildcardElement::evaluate(ParseTree *t) {
+ if (_invert) {
+ return {}; // !* is weird but valid (empty)
+ }
+
+ return t->children;
+}
diff --git a/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.h b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.h
new file mode 100644
index 0000000..accb461
--- /dev/null
+++ b/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/xpath/XPathWildcardElement.h
@@ -0,0 +1,23 @@
+/* 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.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathWildcardElement : public XPathElement {
+ public:
+ XPathWildcardElement();
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4