A tree pattern matching mechanism for ANTLR Antlr4.Runtime.Tree.IParseTree s.

Patterns are strings of source input text with special tags representing token or rule references such as:

<ID> = <expr>;

Given a pattern start rule such as statement , this object constructs a Antlr4.Runtime.Tree.IParseTree with placeholders for the ID and expr subtree. Then the Match(Antlr4.Runtime.Tree.IParseTree, ParseTreePattern) routines can compare an actual Antlr4.Runtime.Tree.IParseTree from a parse with this pattern. Tag <ID> matches any ID token and tag <expr> references the result of the expr rule (generally an instance of ExprContext .

Pattern x = 0; is a similar pattern that matches the same pattern except that it requires the identifier to be x and the expression to be 0 .

The Matches(Antlr4.Runtime.Tree.IParseTree, ParseTreePattern) routines return or based upon a match for the tree rooted at the parameter sent in. The Match(Antlr4.Runtime.Tree.IParseTree, ParseTreePattern) routines return a 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 ParseTreeMatch.MismatchedNode set to the first tree node that did not match.

For efficiency, you can compile a tree pattern in string form to a ParseTreePattern object.

See TestParseTreeMatcher for lots of examples. ParseTreePattern has two static helper methods: ParseTreePattern.FindAll(Antlr4.Runtime.Tree.IParseTree, string) and ParseTreePattern.Match(Antlr4.Runtime.Tree.IParseTree) that are easy to use but not super efficient because they create new ParseTreePatternMatcher objects each time and have to compile the pattern in string form before using it.

The lexer and parser that you pass into the ParseTreePatternMatcher constructor are used to parse the pattern in string form. The lexer converts the <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 Antlr4.Runtime.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.

Normally a parser does not accept token <expr> as a valid expr but, from the parser passed in, we create a special version of the underlying grammar representation (an Antlr4.Runtime.Atn.ATN ) that allows imaginary tokens representing rules ( <expr> ) to match entire rules. We call these bypass alternatives.

Delimiters are < and > , with \ as the escape string by default, but you can set them to whatever you want using SetDelimiters(string, string, string) . You must escape both start and stop strings \< and \> .

 /// <summary>
 /// Construct a new instance of the
 /// <see cref="ParseTreePattern"/>
 /// class.
 /// </summary>
 /// <param name="matcher">
 /// The
 /// <see 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
 /// <see cref="Antlr4.Runtime.Tree.IParseTree"/>
 /// form.
 /// </param>
 public ParseTreePattern([NotNull] ParseTreePatternMatcher matcher, [NotNull] string pattern, int patternRuleIndex, [NotNull] IParseTree patternTree)
 {
     this.matcher          = matcher;
     this.patternRuleIndex = patternRuleIndex;
     this.pattern          = pattern;
     this.patternTree      = patternTree;
 }
Exemple #2
0
 /// <summary>
 /// Construct a new instance of the
 /// <see cref="ParseTreePattern"/>
 /// class.
 /// </summary>
 /// <param name="matcher">
 /// The
 /// <see 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
 /// <see cref="Antlr4.Runtime.Tree.IParseTree"/>
 /// form.
 /// </param>
 public ParseTreePattern(ParseTreePatternMatcher matcher, string pattern, int patternRuleIndex, IParseTree patternTree)
 {
     this.matcher          = matcher;
     this.patternRuleIndex = patternRuleIndex;
     this.pattern          = pattern;
     this.patternTree      = patternTree;
 }
 /// <summary>
 /// Construct a new instance of the
 /// <see cref="ParseTreePattern"/>
 /// class.
 /// </summary>
 /// <param name="matcher">
 /// The
 /// <see 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
 /// <see cref="Antlr4.Runtime.Tree.IParseTree"/>
 /// form.
 /// </param>
 public ParseTreePattern(ParseTreePatternMatcher matcher, string pattern, int patternRuleIndex, IParseTree patternTree)
 {
     this.matcher = matcher;
     this.patternRuleIndex = patternRuleIndex;
     this.pattern = pattern;
     this.patternTree = patternTree;
 }