1 /* 2 * [The "BSD license"] 3 * Copyright (c) 2013 Terence Parr 4 * Copyright (c) 2013 Sam Harwell 5 * Copyright (c) 2017 Egbert Voigt 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 module antlr.v4.runtime.tree.pattern.ParseTreePattern; 33 34 import antlr.v4.runtime.tree.ParseTree; 35 import antlr.v4.runtime.tree.pattern.ParseTreeMatch; 36 import antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher; 37 import antlr.v4.runtime.tree.xpath.XPath; 38 39 /** 40 * @uml 41 * A pattern like {@code <ID> = <expr>;} converted to a {@link ParseTree} by 42 * {@link ParseTreePatternMatcher#compile(String, int)}. 43 */ 44 class ParseTreePattern 45 { 46 47 /** 48 * @uml 49 * This is the backing field for {@link #getPatternRuleIndex()}. 50 * @final 51 */ 52 private int patternRuleIndex; 53 54 /** 55 * @uml 56 * This is the backing field for {@link #getPattern()}. 57 * @final 58 */ 59 private string pattern; 60 61 /** 62 * @uml 63 * This is the backing field for {@link #getPatternTree()}. 64 */ 65 public ParseTree patternTree; 66 67 /** 68 * @uml 69 * This is the backing field for {@link #getMatcher()}. 70 */ 71 public ParseTreePatternMatcher matcher; 72 73 /** 74 * @uml 75 * Construct a new instance of the {@link ParseTreePattern} class. 76 * 77 * @param matcher The {@link ParseTreePatternMatcher} which created this 78 * tree pattern. 79 * @param pattern The tree pattern in concrete syntax form. 80 * @param patternRuleIndex The parser rule which serves as the root of the 81 * tree pattern. 82 * @param patternTree The tree pattern in {@link ParseTree} form. 83 */ 84 public this(ParseTreePatternMatcher matcher, string pattern, int patternRuleIndex, ParseTree patternTree) 85 { 86 this.matcher = matcher; 87 this.patternRuleIndex = patternRuleIndex; 88 this.pattern = pattern; 89 this.patternTree = patternTree; 90 } 91 92 /** 93 * @uml 94 * Match a specific parse tree against this tree pattern. 95 * 96 * @param tree The parse tree to match against this tree pattern. 97 * @return A {@link ParseTreeMatch} object describing the result of the 98 * match operation. The {@link ParseTreeMatch#succeeded()} method can be 99 * used to determine whether or not the match was successful. 100 */ 101 public ParseTreeMatch match(ParseTree tree) 102 { 103 return matcher.match(tree, this); 104 } 105 106 /** 107 * @uml 108 * Determine whether or not a parse tree matches this tree pattern. 109 * 110 * @param tree The parse tree to match against this tree pattern. 111 * @return {@code true} if {@code tree} is a match for the current tree 112 * pattern; otherwise, {@code false}. 113 */ 114 public bool matches(ParseTree tree) 115 { 116 return matcher.match(tree, this).succeeded(); 117 } 118 119 /** 120 * @uml 121 * Find all nodes using XPath and then try to match those subtrees against 122 * this tree pattern. 123 * 124 * @param tree The {@link ParseTree} to match against this pattern. 125 * @param xpath An expression matching the nodes 126 * 127 * @return A collection of {@link ParseTreeMatch} objects describing the 128 * successful matches. Unsuccessful matches are omitted from the result, 129 * regardless of the reason for the failure. 130 */ 131 public ParseTreeMatch[] findAll(ParseTree tree, string xpath) 132 { 133 ParseTree[] subtrees = XPath.findAll(tree, xpath, matcher.getParser()); 134 ParseTreeMatch[] matches; 135 foreach (ParseTree t; subtrees) { 136 ParseTreeMatch match = match(t); 137 if ( match.succeeded() ) { 138 matches ~= match; 139 } 140 } 141 return matches; 142 } 143 144 /** 145 * @uml 146 * et the {@link ParseTreePatternMatcher} which created this tree pattern. 147 * 148 * @return The {@link ParseTreePatternMatcher} which created this tree 149 * pattern. 150 */ 151 public ParseTreePatternMatcher getMatcher() 152 { 153 return matcher; 154 } 155 156 /** 157 * @uml 158 * Get the tree pattern in concrete syntax form. 159 * 160 * @return The tree pattern in concrete syntax form. 161 */ 162 public string getPattern() 163 { 164 return pattern; 165 } 166 167 /** 168 * @uml 169 * Get the parser rule which serves as the outermost rule for the tree 170 * pattern. 171 * 172 * @return The parser rule which serves as the outermost rule for the tree 173 * pattern. 174 */ 175 public int getPatternRuleIndex() 176 { 177 return patternRuleIndex; 178 } 179 180 /** 181 * @uml 182 * Get the tree pattern as a {@link ParseTree}. The rule and token tags from 183 * the pattern are present in the parse tree as terminal nodes with a symbol 184 * of type {@link RuleTagToken} or {@link TokenTagToken}. 185 * 186 * @return The tree pattern as a {@link ParseTree}. 187 */ 188 public ParseTree getPatternTree() 189 { 190 return patternTree; 191 } 192 193 }