blob: e6b2d59aec5faf2d518598c128e0959a73e06d77 [file] [log] [blame]
Joachim Bingelc8a28e42014-04-24 15:06:42 +00001package de.ids_mannheim.korap.query.serialize;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.regex.Matcher;
6import java.util.regex.Pattern;
7
8import org.antlr.runtime.Parser;
9import org.antlr.runtime.tree.Tree;
10
Joachim Bingela145c982015-02-18 18:31:57 +010011/**
Joachim Bingela6954de2015-03-20 16:37:37 +010012 * This class is provides methods for navigation and search in
13 * Abstract Syntax
14 * Trees returned by ANTLR v3 parsers, using ANTLR v3 libraries. Any
15 * class that
16 * extends this abstract class will thus be equipped with such
17 * methods,
18 * which makes it easier to, e.g., retrieve children of a specific
19 * category
20 * for some node.
Joachim Bingela145c982015-02-18 18:31:57 +010021 *
22 * @author Joachim Bingel (bingel@ids-mannheim.de)
Joachim Bingel7cb346e2015-03-09 10:56:20 +010023 * @version 0.3.0
Joachim Bingela145c982015-02-18 18:31:57 +010024 * @since 0.1.0
25 */
Joachim Bingel20e06ac2015-01-15 10:31:33 +000026public abstract class Antlr3AbstractQueryProcessor extends
27 AbstractQueryProcessor {
28
Joachim Bingela145c982015-02-18 18:31:57 +010029 /**
30 * The ANTLR parser. Subclasses need to instantiate this field.
31 */
Joachim Bingel20e06ac2015-01-15 10:31:33 +000032 protected Parser parser;
Joachim Bingelc8a28e42014-04-24 15:06:42 +000033
Joachim Bingela6954de2015-03-20 16:37:37 +010034
Joachim Bingelc8a28e42014-04-24 15:06:42 +000035 /**
Joachim Bingel20e06ac2015-01-15 10:31:33 +000036 * Returns the category (or 'label') of the root of a (sub-)
37 * ParseTree (ANTLR 3).
Joachim Bingela6954de2015-03-20 16:37:37 +010038 *
39 * @param node
40 * The tree node.
Joachim Bingela145c982015-02-18 18:31:57 +010041 * @return The category of the node.
Joachim Bingelc8a28e42014-04-24 15:06:42 +000042 */
Joachim Bingela6954de2015-03-20 16:37:37 +010043 protected static String getNodeCat (Tree node) {
Joachim Bingelc8a28e42014-04-24 15:06:42 +000044 String nodeCat = node.toStringTree();
Joachim Bingel20e06ac2015-01-15 10:31:33 +000045 // from opening parenthesis to 1st whitespace
Joachim Bingela6954de2015-03-20 16:37:37 +010046 Pattern p = Pattern.compile("\\((.*?)\\s");
Joachim Bingelc8a28e42014-04-24 15:06:42 +000047 Matcher m = p.matcher(node.toStringTree());
48 if (m.find()) {
49 nodeCat = m.group(1);
50 }
51 return nodeCat;
52 }
53
Joachim Bingela6954de2015-03-20 16:37:37 +010054
Joachim Bingelc8a28e42014-04-24 15:06:42 +000055 /**
Joachim Bingela145c982015-02-18 18:31:57 +010056 * Tests whether a certain node has a child of a certain category.
Joachim Bingela6954de2015-03-20 16:37:37 +010057 *
Joachim Bingel20e06ac2015-01-15 10:31:33 +000058 * @param node
59 * The parent node.
60 * @param childCat
61 * The category of the potential child.
62 * @return true iff one or more children belong to the specified
Joachim Bingela145c982015-02-18 18:31:57 +010063 * category.
Joachim Bingelc8a28e42014-04-24 15:06:42 +000064 */
Joachim Bingela6954de2015-03-20 16:37:37 +010065 protected static boolean hasChild (Tree node, String childCat) {
Joachim Bingelc8a28e42014-04-24 15:06:42 +000066 for (int i = 0; i < node.getChildCount(); i++) {
67 if (getNodeCat(node.getChild(i)).equals(childCat)) {
68 return true;
69 }
70 }
71 return false;
72 }
Joachim Bingel20e06ac2015-01-15 10:31:33 +000073
Joachim Bingela6954de2015-03-20 16:37:37 +010074
Joachim Bingela145c982015-02-18 18:31:57 +010075 /**
Joachim Bingela6954de2015-03-20 16:37:37 +010076 * Tests whether a certain node has a descendant (direct or
77 * indirect child)
Joachim Bingela145c982015-02-18 18:31:57 +010078 * of a certain category.
Joachim Bingela6954de2015-03-20 16:37:37 +010079 *
Joachim Bingela145c982015-02-18 18:31:57 +010080 * @param node
81 * The parent node.
82 * @param childCat
83 * The category of the potential descendant.
Joachim Bingela6954de2015-03-20 16:37:37 +010084 * @return true iff one or more descendants belong to the
85 * specified
Joachim Bingela145c982015-02-18 18:31:57 +010086 * category.
87 */
Joachim Bingela6954de2015-03-20 16:37:37 +010088 protected static boolean hasDescendantWithCat (Tree node, String childCat) {
Joachim Bingel0e54d222015-01-12 13:22:16 +000089 for (int i = 0; i < node.getChildCount(); i++) {
90 Tree child = node.getChild(i);
91 if (getNodeCat(child).equals(childCat)) {
92 return true;
93 }
Joachim Bingel3d5b69b2015-01-14 10:46:44 +000094 if (hasDescendantWithCat(child, childCat)) {
Joachim Bingel0e54d222015-01-12 13:22:16 +000095 return true;
96 }
97 }
98 return false;
99 }
Joachim Bingelc8a28e42014-04-24 15:06:42 +0000100
Joachim Bingela6954de2015-03-20 16:37:37 +0100101
Joachim Bingela145c982015-02-18 18:31:57 +0100102 /**
103 * Returns all children of a node.
Joachim Bingela6954de2015-03-20 16:37:37 +0100104 *
105 * @param node
106 * The node.
107 * @return A list containing all children.
Joachim Bingela145c982015-02-18 18:31:57 +0100108 */
Joachim Bingela6954de2015-03-20 16:37:37 +0100109 protected static List<Tree> getChildren (Tree node) {
Joachim Bingel896067a2014-11-07 19:02:27 +0000110 ArrayList<Tree> children = new ArrayList<Tree>();
111 for (int i = 0; i < node.getChildCount(); i++) {
112 children.add(node.getChild(i));
113 }
114 return children;
115 }
116
Joachim Bingela6954de2015-03-20 16:37:37 +0100117
Joachim Bingela145c982015-02-18 18:31:57 +0100118 /**
119 * Returns all children of a node which are of a given category.
Joachim Bingela6954de2015-03-20 16:37:37 +0100120 *
121 * @param node
122 * The node.
123 * @param nodeCat
124 * The node category constraining the returned
125 * children.
126 * @return A (possibly empty) list containing all children of the
127 * given
128 * category.
Joachim Bingela145c982015-02-18 18:31:57 +0100129 */
Joachim Bingela6954de2015-03-20 16:37:37 +0100130 protected static List<Tree> getChildrenWithCat (Tree node, String nodeCat) {
Joachim Bingelc8a28e42014-04-24 15:06:42 +0000131 ArrayList<Tree> children = new ArrayList<Tree>();
132 for (int i = 0; i < node.getChildCount(); i++) {
133 if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
134 children.add(node.getChild(i));
135 }
136 }
137 return children;
138 }
Joachim Bingel20e06ac2015-01-15 10:31:33 +0000139
Joachim Bingela6954de2015-03-20 16:37:37 +0100140
Joachim Bingela145c982015-02-18 18:31:57 +0100141 /**
Joachim Bingela6954de2015-03-20 16:37:37 +0100142 * Returns all descendants (direct or indirect children) of a node
143 * which
Joachim Bingela145c982015-02-18 18:31:57 +0100144 * are of a given category.
Joachim Bingela6954de2015-03-20 16:37:37 +0100145 *
146 * @param node
147 * The node.
148 * @param nodeCat
149 * The node category constraining the returned
150 * descendants.
151 * @return A (possibly empty) list containing all descendants of
152 * the given
153 * category.
Joachim Bingela145c982015-02-18 18:31:57 +0100154 */
Joachim Bingela6954de2015-03-20 16:37:37 +0100155 protected List<Tree> getDescendantsWithCat (Tree node, String nodeCat) {
Joachim Bingela145c982015-02-18 18:31:57 +0100156 ArrayList<Tree> descendants = new ArrayList<Tree>();
157 for (Tree child : getChildren(node)) {
158 if (getNodeCat(child).equals(nodeCat)) {
159 descendants.add(child);
160 }
161 descendants.addAll(getDescendantsWithCat(child, nodeCat));
162 }
163 return descendants;
164 }
Joachim Bingela6954de2015-03-20 16:37:37 +0100165
166
Joachim Bingela145c982015-02-18 18:31:57 +0100167 /**
168 * Returns the first child of a node which is of a given category.
Joachim Bingela6954de2015-03-20 16:37:37 +0100169 *
170 * @param node
171 * The node.
172 * @param nodeCat
173 * The node category constraining the returned child.
174 * @return The first child with the given category, <tt>null</tt>
175 * if no
176 * such child exists.
Joachim Bingela145c982015-02-18 18:31:57 +0100177 */
Joachim Bingela6954de2015-03-20 16:37:37 +0100178 protected static Tree getFirstChildWithCat (Tree node, String nodeCat) {
Joachim Bingel0e54d222015-01-12 13:22:16 +0000179 return getNthChildWithCat(node, nodeCat, 1);
180 }
Joachim Bingel20e06ac2015-01-15 10:31:33 +0000181
Joachim Bingela6954de2015-03-20 16:37:37 +0100182
Joachim Bingela145c982015-02-18 18:31:57 +0100183 /**
184 * Returns the nth child of a node which is of a given category.
Joachim Bingela6954de2015-03-20 16:37:37 +0100185 *
186 * @param node
187 * The node.
188 * @param nodeCat
189 * The node category constraining the returned child.
190 * @param n
191 * The index of the child to return, among all children
192 * with the
193 * given category.
194 * @return The nth child with the given category, <tt>null</tt> if
195 * no
196 * such child exists (i.e., if n is larger than the number
197 * of children
198 * with the given category).
Joachim Bingela145c982015-02-18 18:31:57 +0100199 */
Joachim Bingela6954de2015-03-20 16:37:37 +0100200 protected static Tree getNthChildWithCat (Tree node, String nodeCat, int n) {
Joachim Bingel20e06ac2015-01-15 10:31:33 +0000201 int counter = 0;
202 for (int i = 0; i < node.getChildCount(); i++) {
203 if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
204 counter++;
205 if (counter == n) {
206 return node.getChild(i);
207 }
208 }
209 }
Joachim Bingelc8a28e42014-04-24 15:06:42 +0000210 return null;
211 }
212}