add antlr

This commit is contained in:
2020-09-29 23:16:42 +05:30
parent 34754a7130
commit 2b36e74ff5
181 changed files with 14689 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.
*/
#pragma once
#include "antlr4-common.h"
namespace antlr4 {
namespace tree {
class ANTLR4CPP_PUBLIC ParseTreeWalker {
public:
static ParseTreeWalker &DEFAULT;
virtual ~ParseTreeWalker();
virtual void walk(ParseTreeListener *listener, ParseTree *t) const;
protected:
/// The discovery of a rule node, involves sending two events: the generic
/// <seealso cref="ParseTreeListener#enterEveryRule"/> and a
/// <seealso cref="RuleContext"/>-specific event. First we trigger the generic and then
/// the rule specific. We do them in reverse order upon finishing the node.
virtual void enterRule(ParseTreeListener *listener, ParseTree *r) const;
virtual void exitRule(ParseTreeListener *listener, ParseTree *r) const;
};
} // namespace tree
} // namespace antlr4

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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