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 // Class ParseTreePattern 40 /** 41 * @uml 42 * A pattern like {@code <ID> = <expr>;} converted to a {@link ParseTree} by 43 * {@link ParseTreePatternMatcher#compile(String, int)}. 44 */ 45 class ParseTreePattern 46 { 47 48 /** 49 * @uml 50 * This is the backing field for {@link #getPatternRuleIndex()}. 51 * @final 52 */ 53 private int patternRuleIndex; 54 55 /** 56 * @uml 57 * This is the backing field for {@link #getPattern()}. 58 * @final 59 */ 60 private string pattern; 61 62 /** 63 * @uml 64 * This is the backing field for {@link #getPatternTree()}. 65 */ 66 public ParseTree patternTree; 67 68 /** 69 * @uml 70 * This is the backing field for {@link #getMatcher()}. 71 */ 72 public ParseTreePatternMatcher matcher; 73 74 /** 75 * @uml 76 * Construct a new instance of the {@link ParseTreePattern} class. 77 * 78 * @param matcher The {@link ParseTreePatternMatcher} which created this 79 * tree pattern. 80 * @param pattern The tree pattern in concrete syntax form. 81 * @param patternRuleIndex The parser rule which serves as the root of the 82 * tree pattern. 83 * @param patternTree The tree pattern in {@link ParseTree} form. 84 */ 85 public this(ParseTreePatternMatcher matcher, string pattern, int patternRuleIndex, ParseTree patternTree) 86 { 87 this.matcher = matcher; 88 this.patternRuleIndex = patternRuleIndex; 89 this.pattern = pattern; 90 this.patternTree = patternTree; 91 } 92 93 /** 94 * @uml 95 * Match a specific parse tree against this tree pattern. 96 * 97 * @param tree The parse tree to match against this tree pattern. 98 * @return A {@link ParseTreeMatch} object describing the result of the 99 * match operation. The {@link ParseTreeMatch#succeeded()} method can be 100 * used to determine whether or not the match was successful. 101 */ 102 public ParseTreeMatch match(ParseTree tree) 103 { 104 return matcher.match(tree, this); 105 } 106 107 /** 108 * @uml 109 * Determine whether or not a parse tree matches this tree pattern. 110 * 111 * @param tree The parse tree to match against this tree pattern. 112 * @return {@code true} if {@code tree} is a match for the current tree 113 * pattern; otherwise, {@code false}. 114 */ 115 public bool matches(ParseTree tree) 116 { 117 return matcher.match(tree, this).succeeded(); 118 } 119 120 /** 121 * @uml 122 * Find all nodes using XPath and then try to match those subtrees against 123 * this tree pattern. 124 * 125 * @param tree The {@link ParseTree} to match against this pattern. 126 * @param xpath An expression matching the nodes 127 * 128 * @return A collection of {@link ParseTreeMatch} objects describing the 129 * successful matches. Unsuccessful matches are omitted from the result, 130 * regardless of the reason for the failure. 131 */ 132 public ParseTreeMatch[] findAll(ParseTree tree, string xpath) 133 { 134 ParseTree[] subtrees = XPath.findAll(tree, xpath, matcher.getParser()); 135 ParseTreeMatch[] matches; 136 foreach (ParseTree t; subtrees) { 137 ParseTreeMatch match = match(t); 138 if ( match.succeeded() ) { 139 matches ~= match; 140 } 141 } 142 return matches; 143 } 144 145 /** 146 * @uml 147 * et the {@link ParseTreePatternMatcher} which created this tree pattern. 148 * 149 * @return The {@link ParseTreePatternMatcher} which created this tree 150 * pattern. 151 */ 152 public ParseTreePatternMatcher getMatcher() 153 { 154 return matcher; 155 } 156 157 /** 158 * @uml 159 * Get the tree pattern in concrete syntax form. 160 * 161 * @return The tree pattern in concrete syntax form. 162 */ 163 public string getPattern() 164 { 165 return pattern; 166 } 167 168 /** 169 * @uml 170 * Get the parser rule which serves as the outermost rule for the tree 171 * pattern. 172 * 173 * @return The parser rule which serves as the outermost rule for the tree 174 * pattern. 175 */ 176 public int getPatternRuleIndex() 177 { 178 return patternRuleIndex; 179 } 180 181 /** 182 * @uml 183 * Get the tree pattern as a {@link ParseTree}. The rule and token tags from 184 * the pattern are present in the parse tree as terminal nodes with a symbol 185 * of type {@link RuleTagToken} or {@link TokenTagToken}. 186 * 187 * @return The tree pattern as a {@link ParseTree}. 188 */ 189 public ParseTree getPatternTree() 190 { 191 return patternTree; 192 } 193 194 }