From c6ad2948bb98d42f8e0883ef82cd14cd2d5eda60 Mon Sep 17 00:00:00 2001
From: Patrick Schönberger
Date: Sat, 14 Aug 2021 14:56:12 +0200
Subject: add antlr source code and ReadMe
---
.../runtime/src/tree/pattern/Chunk.cpp | 9 +
.../runtime/src/tree/pattern/Chunk.h | 44 +++
.../runtime/src/tree/pattern/ParseTreeMatch.cpp | 69 ++++
.../runtime/src/tree/pattern/ParseTreeMatch.h | 132 ++++++++
.../runtime/src/tree/pattern/ParseTreePattern.cpp | 64 ++++
.../runtime/src/tree/pattern/ParseTreePattern.h | 105 ++++++
.../src/tree/pattern/ParseTreePatternMatcher.cpp | 371 +++++++++++++++++++++
.../src/tree/pattern/ParseTreePatternMatcher.h | 185 ++++++++++
.../runtime/src/tree/pattern/RuleTagToken.cpp | 77 +++++
.../runtime/src/tree/pattern/RuleTagToken.h | 117 +++++++
.../runtime/src/tree/pattern/TagChunk.cpp | 39 +++
.../runtime/src/tree/pattern/TagChunk.h | 86 +++++
.../runtime/src/tree/pattern/TextChunk.cpp | 28 ++
.../runtime/src/tree/pattern/TextChunk.h | 51 +++
.../runtime/src/tree/pattern/TokenTagToken.cpp | 36 ++
.../runtime/src/tree/pattern/TokenTagToken.h | 80 +++++
16 files changed, 1493 insertions(+)
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/Chunk.h
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreeMatch.h
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePattern.h
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.h
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/RuleTagToken.h
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TagChunk.h
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TextChunk.h
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.cpp
create mode 100644 antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/TokenTagToken.h
(limited to 'antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern')
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 {
+
+ ///
+ /// A chunk is either a token tag, a rule tag, or a span of literal text within a
+ /// tree pattern.
+ ///
+ /// The method returns a list of
+ /// chunks in preparation for creating a token stream by
+ /// . From there, we get a parse
+ /// tree from with . These
+ /// chunks are converted to , , or the
+ /// regular tokens of the text surrounding the tags.
+ ///
+ 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> &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 ParseTreeMatch::getAll(const std::string &label) {
+ auto iterator = _labels.find(label);
+ if (iterator == _labels.end()) {
+ return {};
+ }
+
+ return iterator->second;
+}
+
+std::map>& 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> _labels;
+
+ /// This is the backing field for getMismatchedNode().
+ ParseTree *_mismatchedNode;
+
+ public:
+ ///
+ /// Constructs a new instance of from the specified
+ /// parse tree and pattern.
+ ///
+ /// The parse tree to match against the pattern.
+ /// The parse tree pattern.
+ /// A mapping from label names to collections of
+ /// objects located by the tree pattern matching process.
+ /// The first node which failed to match the tree
+ /// pattern during the matching process.
+ ///
+ /// if {@code tree} is {@code null}
+ /// if {@code pattern} is {@code null}
+ /// if {@code labels} is {@code null}
+ ParseTreeMatch(ParseTree *tree, ParseTreePattern const& pattern,
+ const std::map> &labels, ParseTree *mismatchedNode);
+ ParseTreeMatch(ParseTreeMatch const&) = default;
+ virtual ~ParseTreeMatch();
+
+ ///
+ /// Get the last node associated with a specific {@code label}.
+ ///
+ /// For example, for pattern {@code }, {@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}.
+ ///
+ /// Pattern tags like {@code } and {@code } without labels are
+ /// considered to be labeled with {@code ID} and {@code expr}, respectively.
+ ///
+ /// The label to check.
+ ///
+ /// The last to match a tag with the specified
+ /// label, or {@code null} if no parse tree matched a tag with the label.
+ virtual ParseTree* get(const std::string &label);
+
+ ///
+ /// Return all nodes matching a rule or token tag with the specified label.
+ ///
+ /// 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 all of the following.
+ ///
+ ///
+ /// - Parse tree nodes matching tags of the form {@code } and
+ /// {@code }.
+ /// - Parse tree nodes matching tags of the form {@code }.
+ /// - Parse tree nodes matching tags of the form {@code }.
+ ///
+ ///
+ /// The label.
+ ///
+ /// A collection of all nodes matching tags with
+ /// the specified {@code label}. If no nodes matched the label, an empty list
+ /// is returned.
+ virtual std::vector getAll(const std::string &label);
+
+ ///
+ /// Return a mapping from label → [list of nodes].
+ ///
+ /// 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 .
+ ///
+ /// 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.
+ virtual std::map>& getLabels();
+
+ ///
+ /// Get the node at which we first detected a mismatch.
+ ///
+ /// the node at which we first detected a mismatch, or {@code null}
+ /// if the match was successful.
+ virtual ParseTree* getMismatchedNode();
+
+ ///
+ /// Gets a value indicating whether the match operation succeeded.
+ ///
+ /// {@code true} if the match operation succeeded; otherwise,
+ /// {@code false}.
+ virtual bool succeeded();
+
+ ///
+ /// Get the tree pattern we are matching against.
+ ///
+ /// The tree pattern we are matching against.
+ virtual const ParseTreePattern& getPattern();
+
+ ///
+ /// Get the parse tree we are trying to match to a pattern.
+ ///
+ /// The we are trying to match to a pattern.
+ 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 ParseTreePattern::findAll(ParseTree *tree, const std::string &xpath) {
+ xpath::XPath finder(_matcher->getParser(), xpath);
+ std::vector subtrees = finder.evaluate(tree);
+ std::vector 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 {
+
+ ///
+ /// A pattern like {@code = ;} converted to a by
+ /// .
+ ///
+ class ANTLR4CPP_PUBLIC ParseTreePattern {
+ public:
+ ///
+ /// Construct a new instance of the class.
+ ///
+ /// The which created this
+ /// tree pattern.
+ /// The tree pattern in concrete syntax form.
+ /// The parser rule which serves as the root of the
+ /// tree pattern.
+ /// The tree pattern in form.
+ ParseTreePattern(ParseTreePatternMatcher *matcher, const std::string &pattern, int patternRuleIndex,
+ ParseTree *patternTree);
+ ParseTreePattern(ParseTreePattern const&) = default;
+ virtual ~ParseTreePattern();
+
+ ///
+ /// Match a specific parse tree against this tree pattern.
+ ///
+ /// The parse tree to match against this tree pattern.
+ /// A object describing the result of the
+ /// match operation. The method can be
+ /// used to determine whether or not the match was successful.
+ virtual ParseTreeMatch match(ParseTree *tree);
+
+ ///
+ /// Determine whether or not a parse tree matches this tree pattern.
+ ///
+ /// The parse tree to match against this tree pattern.
+ /// {@code true} if {@code tree} is a match for the current tree
+ /// pattern; otherwise, {@code false}.
+ 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 findAll(ParseTree *tree, const std::string &xpath);
+
+ ///
+ /// Get the which created this tree pattern.
+ ///
+ /// The which created this tree
+ /// pattern.
+ virtual ParseTreePatternMatcher *getMatcher() const;
+
+ ///
+ /// Get the tree pattern in concrete syntax form.
+ ///
+ /// The tree pattern in concrete syntax form.
+ virtual std::string getPattern() const;
+
+ ///
+ /// Get the parser rule which serves as the outermost rule for the tree
+ /// pattern.
+ ///
+ /// The parser rule which serves as the outermost rule for the tree
+ /// pattern.
+ virtual int getPatternRuleIndex() const;
+
+ ///
+ /// Get the tree pattern as a . The rule and token tags from
+ /// the pattern are present in the parse tree as terminal nodes with a symbol
+ /// of type or .
+ ///
+ /// The tree pattern as a .
+ virtual ParseTree* getPatternTree() const;
+
+ private:
+ const int patternRuleIndex;
+
+ /// This is the backing field for .
+ const std::string _pattern;
+
+ /// This is the backing field for .
+ ParseTree *_patternTree;
+
+ /// This is the backing field for .
+ 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> 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> 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());
+ 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> &labels) {
+ if (tree == nullptr) {
+ throw IllegalArgumentException("tree cannot be nul");
+ }
+
+ if (patternTree == nullptr) {
+ throw IllegalArgumentException("patternTree cannot be nul");
+ }
+
+ // x and , x and y, or x and x; or could be mismatched types
+ if (is(tree) && is(patternTree)) {
+ TerminalNode *t1 = dynamic_cast(tree);
+ TerminalNode *t2 = dynamic_cast(patternTree);
+
+ ParseTree *mismatchedNode = nullptr;
+ // both are tokens and they have same type
+ if (t1->getSymbol()->getType() == t2->getSymbol()->getType()) {
+ if (is(t2->getSymbol())) { // x and
+ TokenTagToken *tokenTagToken = dynamic_cast(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(tree) && is(patternTree)) {
+ ParserRuleContext *r1 = dynamic_cast(tree);
+ ParserRuleContext *r2 = dynamic_cast(patternTree);
+ ParseTree *mismatchedNode = nullptr;
+
+ // (expr ...) and
+ 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(t->children[0])) {
+ TerminalNode *c = dynamic_cast(t->children[0]);
+ if (is(c->getSymbol())) {
+ return dynamic_cast(c->getSymbol());
+ }
+ }
+ return nullptr;
+}
+
+std::vector> ParseTreePatternMatcher::tokenize(const std::string &pattern) {
+ // split pattern into chunks: sea (raw input) and islands (, )
+ std::vector chunks = split(pattern);
+
+ // create token stream from text and tags
+ std::vector> tokens;
+ for (auto chunk : chunks) {
+ if (is(&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 t(_lexer->nextToken());
+ while (t->getType() != Token::EOF) {
+ tokens.push_back(std::move(t));
+ t = _lexer->nextToken();
+ }
+ _lexer->setInputStream(nullptr);
+ }
+ }
+
+ return tokens;
+}
+
+std::vector ParseTreePatternMatcher::split(const std::string &pattern) {
+ size_t p = 0;
+ size_t n = pattern.length();
+ std::vector chunks;
+
+ // find all start and stop indexes first, then collect
+ std::vector starts;
+ std::vector 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
+ 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 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(&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 {
+
+ ///
+ /// A tree pattern matching mechanism for ANTLR s.
+ ///
+ /// Patterns are strings of source input text with special tags representing
+ /// token or rule references such as:
+ ///
+ /// {@code = ;}
+ ///
+ /// Given a pattern start rule such as {@code statement}, this object constructs
+ /// a with placeholders for the {@code ID} and {@code expr}
+ /// subtree. Then the routines can compare an actual
+ /// from a parse with this pattern. Tag {@code } matches
+ /// any {@code ID} token and tag {@code } references the result of the
+ /// {@code expr} rule (generally an instance of {@code ExprContext}.
+ ///
+ /// 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}.
+ ///
+ /// The routines return {@code true} or {@code false} based
+ /// upon a match for the tree rooted at the parameter sent in. The
+ /// routines return a 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
+ /// set to the first tree node that did not
+ /// match.
+ ///
+ /// For efficiency, you can compile a tree pattern in string form to a
+ /// object.
+ ///
+ /// See {@code TestParseTreeMatcher} for lots of examples.
+ /// has two static helper methods:
+ /// and that
+ /// are easy to use but not super efficient because they create new
+ /// objects each time and have to compile the
+ /// pattern in string form before using it.
+ ///
+ /// The lexer and parser that you pass into the
+ /// constructor are used to parse the pattern in string form. The lexer converts
+ /// the {@code = ;} 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
+ /// 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.
+ ///
+ /// Normally a parser does not accept token {@code } as a valid
+ /// {@code expr} but, from the parser passed in, we create a special version of
+ /// the underlying grammar representation (an ) that allows imaginary
+ /// tokens representing rules ({@code }) to match entire rules. We call
+ /// these bypass alternatives.
+ ///
+ /// Delimiters are {@code <} and {@code >}, with {@code \} as the escape string
+ /// by default, but you can set them to whatever you want using
+ /// . You must escape both start and stop strings
+ /// {@code \<} and {@code \>}.
+ ///
+ 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 or from a and
+ /// 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();
+
+ ///
+ /// Set the delimiters used for marking rule and token tags within concrete
+ /// syntax used by the tree pattern parser.
+ ///
+ /// The start delimiter.
+ /// The stop delimiter.
+ /// The escape sequence to use for escaping a start or stop delimiter.
+ ///
+ /// if {@code start} is {@code null} or empty.
+ /// if {@code stop} is {@code null} or empty.
+ virtual void setDelimiters(const std::string &start, const std::string &stop, const std::string &escapeLeft);
+
+ ///
+ /// Does {@code pattern} matched as rule {@code patternRuleIndex} match {@code tree}?
+ virtual bool matches(ParseTree *tree, const std::string &pattern, int patternRuleIndex);
+
+ ///
+ /// Does {@code pattern} matched as rule patternRuleIndex match tree? Pass in a
+ /// compiled pattern instead of a string representation of a tree pattern.
+ ///
+ virtual bool matches(ParseTree *tree, const ParseTreePattern &pattern);
+
+ ///
+ /// Compare {@code pattern} matched as rule {@code patternRuleIndex} against
+ /// {@code tree} and return a object that contains the
+ /// matched elements, or the node at which the match failed.
+ ///
+ virtual ParseTreeMatch match(ParseTree *tree, const std::string &pattern, int patternRuleIndex);
+
+ ///
+ /// Compare {@code pattern} matched against {@code tree} and return a
+ /// 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.
+ ///
+ virtual ParseTreeMatch match(ParseTree *tree, const ParseTreePattern &pattern);
+
+ ///
+ /// For repeated use of a tree pattern, compile it to a
+ /// using this method.
+ ///
+ virtual ParseTreePattern compile(const std::string &pattern, int patternRuleIndex);
+
+ ///
+ /// Used to convert the tree pattern string into a series of tokens. The
+ /// input stream is reset.
+ ///
+ virtual Lexer* getLexer();
+
+ ///
+ /// Used to collect to the grammar file name, token names, rule names for
+ /// used to parse the pattern into a parse tree.
+ ///
+ virtual Parser* getParser();
+
+ // ---- SUPPORT CODE ----
+
+ virtual std::vector> tokenize(const std::string &pattern);
+
+ /// Split " = ;" into 4 chunks for tokenizing by tokenize().
+ virtual std::vector 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.}.
+ ///
+ /// 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.
+ virtual ParseTree* matchImpl(ParseTree *tree, ParseTree *patternTree, std::map> &labels);
+
+ /// Is t 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 {
+
+ ///
+ /// A object representing an entire subtree matched by a parser
+ /// rule; e.g., {@code }. These tokens are created for
+ /// chunks where the tag corresponds to a parser rule.
+ ///
+ class ANTLR4CPP_PUBLIC RuleTagToken : public Token {
+ ///
+ /// This is the backing field for .
+ ///
+ 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 .
+ const std::string label;
+
+ public:
+ ///
+ /// Constructs a new instance of with the specified rule
+ /// name and bypass token type and no label.
+ ///
+ /// The name of the parser rule this rule tag matches.
+ /// The bypass token type assigned to the parser rule.
+ ///
+ /// if {@code ruleName} is {@code null}
+ /// or empty.
+ RuleTagToken(const std::string &ruleName, int bypassTokenType); //this(ruleName, bypassTokenType, nullptr);
+
+ ///
+ /// Constructs a new instance of with the specified rule
+ /// name, bypass token type, and label.
+ ///
+ /// The name of the parser rule this rule tag matches.
+ /// The bypass token type assigned to the parser rule.
+ /// The label associated with the rule tag, or {@code null} if
+ /// the rule tag is unlabeled.
+ ///
+ /// if {@code ruleName} is {@code null}
+ /// or empty.
+ RuleTagToken(const std::string &ruleName, size_t bypassTokenType, const std::string &label);
+
+ ///
+ /// Gets the name of the rule associated with this rule tag.
+ ///
+ /// The name of the parser rule associated with this rule tag.
+ std::string getRuleName() const;
+
+ ///
+ /// Gets the label associated with the rule tag.
+ ///
+ /// The name of the label associated with the rule tag, or
+ /// {@code null} if this is an unlabeled rule tag.
+ std::string getLabel() const;
+
+ ///
+ /// {@inheritDoc}
+ ///
+ /// Rule tag tokens are always placed on the .
+ ///
+ virtual size_t getChannel() const override;
+
+ ///
+ /// {@inheritDoc}
+ ///
+ /// This method returns the rule tag formatted with {@code <} and {@code >}
+ /// delimiters.
+ ///
+ 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 always returns 0.
+ virtual size_t getLine() const override;
+
+ /// The implementation for always returns INVALID_INDEX.
+ virtual size_t getCharPositionInLine() const override;
+
+ /// The implementation for always returns INVALID_INDEX.
+ virtual size_t getTokenIndex() const override;
+
+ /// The implementation for always returns INVALID_INDEX.
+ virtual size_t getStartIndex() const override;
+
+ /// The implementation for always returns INVALID_INDEX.
+ virtual size_t getStopIndex() const override;
+
+ /// The implementation for always returns {@code null}.
+ virtual TokenSource *getTokenSource() const override;
+
+ /// The implementation for always returns {@code null}.
+ virtual CharStream *getInputStream() const override;
+
+ /// The implementation for 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 {
+
+ ///
+ /// Represents a placeholder tag in a tree pattern. A tag can have any of the
+ /// following forms.
+ ///
+ ///
+ /// - {@code expr}: An unlabeled placeholder for a parser rule {@code expr}.
+ /// - {@code ID}: An unlabeled placeholder for a token of type {@code ID}.
+ /// - {@code e:expr}: A labeled placeholder for a parser rule {@code expr}.
+ /// - {@code id:ID}: A labeled placeholder for a token of type {@code ID}.
+ ///
+ ///
+ /// 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.
+ ///
+ class ANTLR4CPP_PUBLIC TagChunk : public Chunk {
+ public:
+ ///
+ /// Construct a new instance of using the specified tag and
+ /// no label.
+ ///
+ /// The tag, which should be the name of a parser rule or token
+ /// type.
+ ///
+ /// if {@code tag} is {@code null} or
+ /// empty.
+ TagChunk(const std::string &tag);
+ virtual ~TagChunk();
+
+ ///
+ /// Construct a new instance of using the specified label
+ /// and tag.
+ ///
+ /// The label for the tag. If this is {@code null}, the
+ /// represents an unlabeled tag.
+ /// The tag, which should be the name of a parser rule or token
+ /// type.
+ ///
+ /// if {@code tag} is {@code null} or
+ /// empty.
+ TagChunk(const std::string &label, const std::string &tag);
+
+ ///
+ /// Get the tag for this chunk.
+ ///
+ /// The tag for the chunk.
+ std::string getTag();
+
+ ///
+ /// Get the label, if any, assigned to this chunk.
+ ///
+ /// The label assigned to this chunk, or {@code null} if no label is
+ /// assigned to the chunk.
+ std::string getLabel();
+
+ ///
+ /// 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() override;
+
+ private:
+ /// This is the backing field for .
+ const std::string _tag;
+ ///
+ /// This is the backing field for .
+ ///
+ 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 {
+
+ ///
+ /// Represents a span of raw text (concrete syntax) between tags in a tree
+ /// pattern string.
+ ///
+ class ANTLR4CPP_PUBLIC TextChunk : public Chunk {
+ private:
+ ///
+ /// This is the backing field for .
+ ///
+ const std::string text;
+
+ ///
+ /// Constructs a new instance of with the specified text.
+ ///
+ /// The text of this chunk.
+ /// if {@code text} is {@code null}.
+ public:
+ TextChunk(const std::string &text);
+ virtual ~TextChunk();
+
+ ///
+ /// Gets the raw text of this chunk.
+ ///
+ /// The text of the chunk.
+ std::string getText();
+
+ ///
+ /// {@inheritDoc}
+ ///
+ /// The implementation for returns the result of
+ /// in single quotes.
+ ///
+ 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 {
+
+ ///
+ /// A object representing a token of a particular type; e.g.,
+ /// {@code }. These tokens are created for chunks where the
+ /// tag corresponds to a lexer rule or token type.
+ ///
+ class ANTLR4CPP_PUBLIC TokenTagToken : public CommonToken {
+ ///
+ /// This is the backing field for .
+ ///
+ private:
+ const std::string tokenName;
+ ///
+ /// This is the backing field for .
+ ///
+ const std::string label;
+
+ ///
+ /// Constructs a new instance of for an unlabeled tag
+ /// with the specified token name and type.
+ ///
+ /// The token name.
+ /// The token type.
+ public:
+ TokenTagToken(const std::string &tokenName, int type); //this(tokenName, type, nullptr);
+
+ ///
+ /// Constructs a new instance of with the specified
+ /// token name, type, and label.
+ ///
+ /// The token name.
+ /// The token type.
+ /// The label associated with the token tag, or {@code null} if
+ /// the token tag is unlabeled.
+ TokenTagToken(const std::string &tokenName, int type, const std::string &label);
+
+ ///
+ /// Gets the token name.
+ /// The token name.
+ std::string getTokenName() const;
+
+ ///
+ /// Gets the label associated with the rule tag.
+ ///
+ /// The name of the label associated with the rule tag, or
+ /// {@code null} if this is an unlabeled rule tag.
+ std::string getLabel() const;
+
+ ///
+ /// {@inheritDoc}
+ ///
+ /// The implementation for returns the token tag
+ /// formatted with {@code <} and {@code >} delimiters.
+ ///
+ virtual std::string getText() const override;
+
+ ///
+ /// {@inheritDoc}
+ ///
+ /// The implementation for returns a string of the form
+ /// {@code tokenName:type}.
+ ///
+ virtual std::string toString() const override;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--
cgit v1.2.3