X-Git-Url: https://gitweb.ps.run/toc/blobdiff_plain/9f94b672a5dc32da5ad01742bd4e976315a30d9c..c6ad2948bb98d42f8e0883ef82cd14cd2d5eda60:/antlr4-cpp-runtime-4.9.2-source/runtime/src/tree/pattern/ParseTreePatternMatcher.h
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