| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 1 | package de.ids_mannheim.korap.query.serialize; |
| 2 | |
| 3 | import java.util.ArrayList; |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 4 | import java.util.Arrays; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 5 | import java.util.LinkedHashMap; |
| 6 | import java.util.LinkedList; |
| 7 | import java.util.List; |
| 8 | import java.util.Map; |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 9 | import java.util.regex.Matcher; |
| 10 | import java.util.regex.Pattern; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 11 | |
| 12 | import org.antlr.runtime.ANTLRStringStream; |
| 13 | import org.antlr.runtime.RecognitionException; |
| 14 | import org.antlr.runtime.tree.Tree; |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 15 | import org.antlr.v4.runtime.tree.ParseTree; |
| 16 | import org.slf4j.Logger; |
| 17 | import org.slf4j.LoggerFactory; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 18 | |
| 19 | import de.ids_mannheim.korap.query.cosmas2.c2psLexer; |
| 20 | import de.ids_mannheim.korap.query.cosmas2.c2psParser; |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 21 | import de.ids_mannheim.korap.query.serialize.util.CosmasCondition; |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 22 | import de.ids_mannheim.korap.util.QueryException; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 23 | |
| 24 | /** |
| 25 | * Map representation of CosmasII syntax tree as returned by ANTLR |
| 26 | * @author joachim |
| 27 | * |
| 28 | */ |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 29 | public class CosmasTree extends Antlr3AbstractSyntaxTree { |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 30 | |
| Michael Hanl | 10d2150 | 2014-02-07 20:09:58 +0000 | [diff] [blame] | 31 | private static Logger log = LoggerFactory.getLogger(CosmasTree.class); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 32 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 33 | /* |
| 34 | * Following collections have the following functions: |
| 35 | * - the request is a map with two keys (meta/query): {meta=[], query=[]} |
| 36 | * - the query is a list of token group maps: {meta=[], query=[tg1=[], tg2=[]]} |
| 37 | * - each token group is a list of tokens: {meta=[], query=[tg1=[t1_1, t1_2], tg2=[t2_1, t2_2, t2_3]]} |
| 38 | * - each token corresponds to a single 'fields' linked list {meta=[], query=[tg1=[t1_1=[], t1_2=[]], ... ]} |
| 39 | * - each fields list contains a logical operator and 'field maps' defining attributes and values |
| 40 | * {meta=[], query=[tg1=[t1_1=[[disj, {base=foo}, {base=bar}]], t1_2=[]], ... ]} |
| 41 | */ |
| 42 | String query; |
| 43 | LinkedHashMap<String,Object> requestMap = new LinkedHashMap<String,Object>(); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 44 | /** |
| 45 | * Keeps track of active object. |
| 46 | */ |
| 47 | LinkedList<LinkedHashMap<String,Object>> objectStack = new LinkedList<LinkedHashMap<String,Object>>(); |
| 48 | /** |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 49 | * Makes it possible to store several distantTokenGroups |
| 50 | */ |
| 51 | LinkedList<ArrayList<List<Object>>> distantTokensStack = new LinkedList<ArrayList<List<Object>>>(); |
| 52 | /** |
| 53 | * Field for repetition query (Kleene + or * operations, or min/max queries: {2,4} |
| 54 | */ |
| 55 | String repetition = ""; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 56 | /** |
| 57 | * Keeps track of open node categories |
| 58 | */ |
| 59 | LinkedList<String> openNodeCats = new LinkedList<String>(); |
| 60 | /** |
| 61 | * Global control structure for fieldGroups, keeps track of open fieldGroups. |
| 62 | */ |
| 63 | LinkedList<ArrayList<Object>> openFieldGroups = new LinkedList<ArrayList<Object>>(); |
| 64 | /** |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 65 | * Keeps track of how many objects there are to pop after every recursion of {@link #processNode(ParseTree)} |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 66 | */ |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 67 | LinkedList<Integer> objectsToPop = new LinkedList<Integer>(); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 68 | /** |
| 69 | * Flag that indicates whether token fields or meta fields are currently being processed |
| 70 | */ |
| 71 | boolean inMeta = false; |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 72 | /** |
| 73 | * |
| 74 | */ |
| 75 | int classRefCounter = 1; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 76 | boolean negate = false; |
| 77 | |
| 78 | Tree cosmasTree; |
| 79 | |
| 80 | LinkedHashMap<String,Object> treeMap = new LinkedHashMap<String,Object>(); |
| 81 | /** |
| 82 | * Keeps track of all visited nodes in a tree |
| 83 | */ |
| 84 | List<Tree> visited = new ArrayList<Tree>(); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 85 | |
| 86 | Integer stackedObjects = 0; |
| 87 | |
| 88 | private static boolean debug = false; |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 89 | /** |
| 90 | * A list of node categories that can be sequenced (i.e. which can be in a sequence with any number of other nodes in this list) |
| 91 | */ |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 92 | private final List<String> sequentiableCats = Arrays.asList(new String[] {"OPWF", "OPLEM", "OPMORPH", "OPBEG", "OPEND", "OPIN", "OPBED"}); |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 93 | /** |
| 94 | * Keeps track of sequenced nodes, i.e. nodes that implicitly govern a sequence, as in (C2PQ (OPWF der) (OPWF Mann)). |
| 95 | * This is necessary in order to know when to take the sequence off the object stack, as the sequence is introduced by the |
| 96 | * first child but cannot be closed after this first child in order not to lose its siblings |
| 97 | */ |
| 98 | private LinkedList<Tree> sequencedNodes = new LinkedList<Tree>(); |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 99 | |
| 100 | private boolean hasSequentiableSiblings; |
| 101 | |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 102 | /** |
| 103 | * Keeps track of operands lists that are to be serialised in an inverted |
| 104 | * order (e.g. the IN() operator) compared to their AST representation. |
| 105 | */ |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 106 | private LinkedList<ArrayList<Object>> invertedOperandsLists = new LinkedList<ArrayList<Object>>(); |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 107 | |
| 108 | private LinkedList<ArrayList<ArrayList<Object>>> distributedOperandsLists = new LinkedList<ArrayList<ArrayList<Object>>>(); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 109 | /** |
| 110 | * |
| 111 | * @param tree The syntax tree as returned by ANTLR |
| 112 | * @param parser The ANTLR parser instance that generated the parse tree |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 113 | * @throws QueryException |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 114 | */ |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 115 | public CosmasTree(String query) throws QueryException { |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 116 | this.query = query; |
| 117 | process(query); |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 118 | System.out.println("\n"+requestMap.get("query")); |
| 119 | log.info(">>> " + requestMap.get("query") + " <<<"); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | @Override |
| 123 | public Map<String, Object> getRequestMap() { |
| 124 | return this.requestMap; |
| 125 | } |
| 126 | |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 127 | |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 128 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 129 | @Override |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 130 | public void process(String query) throws QueryException { |
| 131 | Tree tree = null; |
| 132 | try { |
| 133 | tree = parseCosmasQuery(query); |
| 134 | } catch (RecognitionException e) { |
| 135 | throw new QueryException("Your query could not be processed. Please make sure it is well-formed."); |
| 136 | } catch (NullPointerException e) { |
| 137 | throw new QueryException("Your query could not be processed. Please make sure it is well-formed."); |
| 138 | } |
| 139 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 140 | System.out.println("Processing Cosmas"); |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 141 | requestMap.put("@context", "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld"); |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 142 | // prepareContext(requestMap); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 143 | processNode(tree); |
| 144 | } |
| 145 | |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 146 | @SuppressWarnings("unchecked") |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 147 | private void processNode(Tree node) { |
| 148 | |
| 149 | // Top-down processing |
| 150 | if (visited.contains(node)) return; |
| 151 | else visited.add(node); |
| 152 | |
| 153 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 154 | String nodeCat = getNodeCat(node); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 155 | openNodeCats.push(nodeCat); |
| 156 | |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 157 | stackedObjects = 0; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 158 | |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 159 | if (debug) { |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 160 | System.err.println(" "+objectStack); |
| 161 | System.out.println(openNodeCats); |
| 162 | } |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 163 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 164 | |
| 165 | /* *************************************** |
| 166 | * Processing individual node categories * |
| 167 | *****************************************/ |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 168 | |
| 169 | |
| 170 | // Check for potential implicit sequences as in (C2PQ (OPWF der) (OPWF Mann)). The sequence is introduced |
| 171 | // by the first child if it (and its siblings) is sequentiable. |
| 172 | if (sequentiableCats.contains(nodeCat)) { |
| 173 | // for each node, check if parent has more than one child (-> could be implicit sequence) |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 174 | Tree parent = node.getParent(); |
| 175 | if (parent.getChildCount()>1) { |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 176 | // if node is first child of parent... |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 177 | if (node == parent.getChild(0)) { |
| 178 | hasSequentiableSiblings = false; |
| 179 | for (int i=1; i<parent.getChildCount() ;i++) { |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 180 | if (sequentiableCats.contains(getNodeCat(parent.getChild(i)))) { |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 181 | hasSequentiableSiblings = true; |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 182 | continue; |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 183 | } |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 184 | } |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 185 | if (hasSequentiableSiblings) { |
| 186 | // Step I: create sequence |
| 187 | LinkedHashMap<String, Object> sequence = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 188 | sequence.put("@type", "korap:group"); |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 189 | sequence.put("operation", "operation:sequence"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 190 | sequence.put("operands", new ArrayList<Object>()); |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 191 | // push sequence on object stack but don't increment stackedObjects counter since |
| 192 | // we've got to wait until the parent node is processed - therefore, add the parent |
| 193 | // to the sequencedNodes list and remove the sequence from the stack when the parent |
| 194 | // has been processed |
| 195 | objectStack.push(sequence); |
| 196 | sequencedNodes.push(parent); |
| 197 | // Step II: decide where to put sequence |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 198 | putIntoSuperObject(sequence, 1); |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 199 | } |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 200 | } |
| 201 | } |
| 202 | } |
| 203 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 204 | // Nodes introducing tokens. Process all in the same manner, except for the fieldMap entry |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 205 | if (nodeCat.equals("OPWF") || nodeCat.equals("OPLEM")) { |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 206 | |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 207 | //Step I: get info |
| 208 | LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 209 | token.put("@type", "korap:token"); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 210 | objectStack.push(token); |
| 211 | stackedObjects++; |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 212 | LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 213 | token.put("wrap", fieldMap); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 214 | |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 215 | fieldMap.put("@type", "korap:term"); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 216 | // make category-specific fieldMap entry |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 217 | String attr = nodeCat.equals("OPWF") ? "orth" : "lemma"; |
| 218 | String value = node.getChild(0).toStringTree().replaceAll("\"", ""); |
| Joachim Bingel | ee3b21d | 2014-02-12 12:34:59 +0000 | [diff] [blame] | 219 | if (value.startsWith("$")) { |
| 220 | value = value.substring(1); |
| 221 | fieldMap.put("caseInsensitive", true); |
| 222 | } |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 223 | fieldMap.put("key", value); |
| 224 | fieldMap.put("layer", attr); |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 225 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 226 | // negate field (see above) |
| 227 | if (negate) { |
| Joachim Bingel | 0207d5e | 2014-02-12 14:18:41 +0000 | [diff] [blame] | 228 | fieldMap.put("match", "match:ne"); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 229 | } else { |
| Joachim Bingel | 0207d5e | 2014-02-12 14:18:41 +0000 | [diff] [blame] | 230 | fieldMap.put("match", "match:eq"); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 231 | } |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 232 | //Step II: decide where to put |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 233 | if (! hasChild(node, "TPOS")) { |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 234 | putIntoSuperObject(token, 1); |
| 235 | } else { |
| 236 | |
| 237 | } |
| 238 | |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 239 | } |
| 240 | |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 241 | if (nodeCat.equals("OPMORPH")) { |
| 242 | //Step I: get info |
| 243 | LinkedHashMap<String, Object> token = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 244 | token.put("@type", "korap:token"); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 245 | LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 246 | token.put("wrap", fieldMap); |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 247 | |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 248 | fieldMap.put("@type", "korap:term"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 249 | // fieldMap.put("key", "morph:"+node.getChild(0).toString().replace(" ", "_")); |
| Joachim Bingel | 0207d5e | 2014-02-12 14:18:41 +0000 | [diff] [blame] | 250 | String[] morphValues = node.getChild(0).toString().split(" "); |
| 251 | String pos = morphValues[0]; |
| 252 | |
| 253 | fieldMap.put("key", pos); |
| 254 | fieldMap.put("layer", "pos"); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 255 | // make category-specific fieldMap entry |
| 256 | // negate field (see above) |
| 257 | if (negate) { |
| Joachim Bingel | 0207d5e | 2014-02-12 14:18:41 +0000 | [diff] [blame] | 258 | fieldMap.put("match", "match:ne"); |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 259 | } else { |
| Joachim Bingel | 0207d5e | 2014-02-12 14:18:41 +0000 | [diff] [blame] | 260 | fieldMap.put("match", "match:eq"); |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 261 | } |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 262 | // List<String> morphValues = parseMorph(node.getChild(0).toStringTree()); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 263 | // System.err.println(morphValues); |
| 264 | // if (morphValues.size() == 1) { |
| 265 | // LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 266 | // token.put("key", fieldMap); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 267 | // |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 268 | // fieldMap.put("@type", "korap:term"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 269 | // fieldMap.put("key", morphValues.get(0)); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 270 | // // make category-specific fieldMap entry |
| 271 | // // negate field (see above) |
| 272 | // if (negate) { |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 273 | // fieldMap.put("operation", "operation:"+ "!="); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 274 | // } else { |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 275 | // fieldMap.put("operation", "operation:"+ "="); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 276 | // } |
| 277 | // } else { |
| 278 | // LinkedHashMap<String, Object> conjGroup = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 279 | // token.put("key", conjGroup); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 280 | // ArrayList<Object> conjOperands = new ArrayList<Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 281 | // conjGroup.put("@type", "korap:group"); |
| 282 | // conjGroup.put("operation", "operation:"+ "and"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 283 | // conjGroup.put("operands", conjOperands); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 284 | // for (String value : morphValues) { |
| 285 | // LinkedHashMap<String, Object> fieldMap = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 286 | // token.put("key", fieldMap); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 287 | // |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 288 | // fieldMap.put("@type", "korap:term"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 289 | // fieldMap.put("key", value); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 290 | // // make category-specific fieldMap entry |
| 291 | // // negate field (see above) |
| 292 | // if (negate) { |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 293 | // fieldMap.put("operation", "operation:"+ "!="); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 294 | // } else { |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 295 | // fieldMap.put("operation", "operation:"+ "="); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 296 | // } |
| 297 | // } |
| 298 | // } |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 299 | |
| 300 | |
| 301 | //Step II: decide where to put |
| 302 | putIntoSuperObject(token, 0); |
| 303 | } |
| 304 | |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 305 | if (nodeCat.equals("OPELEM")) { |
| 306 | // Step I: create element |
| 307 | LinkedHashMap<String, Object> elem = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 308 | elem.put("@type", "korap:span"); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 309 | if (node.getChild(0).toStringTree().equals("EMPTY")) { |
| 310 | |
| 311 | } else { |
| 312 | int elname = 0; |
| 313 | Tree elnameNode = getFirstChildWithCat(node, "ELNAME"); |
| 314 | if (elnameNode != null) { |
| 315 | elem.put("key", elnameNode.getChild(0).toStringTree().toLowerCase()); |
| 316 | elname = 1; |
| 317 | } |
| 318 | if (node.getChildCount() > elname) { |
| 319 | LinkedHashMap<String, Object> termGroup = makeTermGroup("and"); |
| 320 | ArrayList<Object> termGroupOperands = (ArrayList<Object>) termGroup.get("operands"); |
| 321 | for (int i=elname; i<node.getChildCount(); i++) { |
| 322 | Tree attrNode = node.getChild(i); |
| 323 | if (attrNode.getChildCount()==2) { |
| 324 | LinkedHashMap<String, Object> term = makeTerm(); |
| 325 | termGroupOperands.add(term); |
| 326 | String layer = attrNode.getChild(0).toStringTree(); |
| 327 | term.put("layer", translateMorph(layer)); |
| 328 | term.put("key", attrNode.getChild(1).toStringTree()); |
| 329 | term.put("match", "match:eq"); |
| 330 | } else { |
| 331 | for (int j=1; j<attrNode.getChildCount(); j++) { |
| 332 | LinkedHashMap<String, Object> term = makeTerm(); |
| 333 | termGroupOperands.add(term); |
| 334 | String layer = attrNode.getChild(0).toStringTree(); |
| 335 | term.put("layer", translateMorph(layer)); |
| 336 | term.put("key", attrNode.getChild(j).toStringTree()); |
| 337 | term.put("match", "match:eq"); |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | |
| 342 | if (getNodeCat(attrNode).equals("NOTEQ")) negate=true; |
| 343 | |
| 344 | } |
| 345 | elem.put("attr", termGroup); |
| 346 | } |
| 347 | } |
| 348 | |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 349 | //Step II: decide where to put |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 350 | putIntoSuperObject(elem); |
| 351 | } |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 352 | |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 353 | if (nodeCat.equals("OPLABEL")) { |
| 354 | // Step I: create element |
| 355 | LinkedHashMap<String, Object> elem = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 356 | elem.put("@type", "korap:span"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 357 | elem.put("key", node.getChild(0).toStringTree().replaceAll("<|>", "")); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 358 | //Step II: decide where to put |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 359 | putIntoSuperObject(elem); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 360 | } |
| 361 | |
| Joachim Bingel | b7a5979 | 2014-02-14 13:52:29 +0000 | [diff] [blame] | 362 | if (nodeCat.equals("OPAND") || nodeCat.equals("OPNOT")) { |
| 363 | // Step I: create group |
| 364 | LinkedHashMap<String, Object> distgroup = new LinkedHashMap<String, Object>(); |
| 365 | distgroup.put("@type", "korap:group"); |
| 366 | distgroup.put("operation", "operation:sequence"); |
| 367 | ArrayList<Object> distances = new ArrayList<Object>(); |
| 368 | LinkedHashMap<String, Object> zerodistance = new LinkedHashMap<String, Object>(); |
| 369 | zerodistance.put("@type", "korap:distance"); |
| 370 | zerodistance.put("key", "t"); |
| 371 | zerodistance.put("min", 0); |
| 372 | zerodistance.put("max", 0); |
| 373 | if (nodeCat.equals("OPNOT")) zerodistance.put("exclude", true); |
| 374 | distances.add(zerodistance); |
| 375 | distgroup.put("distances", distances); |
| 376 | distgroup.put("operands", new ArrayList<Object>()); |
| 377 | objectStack.push(distgroup); |
| 378 | stackedObjects++; |
| 379 | // Step II: decide where to put |
| 380 | putIntoSuperObject(distgroup, 1); |
| 381 | } |
| 382 | |
| 383 | if (nodeCat.equals("OPOR")) { |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 384 | // Step I: create group |
| 385 | LinkedHashMap<String, Object> disjunction = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 386 | disjunction.put("@type", "korap:group"); |
| Joachim Bingel | b7a5979 | 2014-02-14 13:52:29 +0000 | [diff] [blame] | 387 | disjunction.put("operation", "operation:or"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 388 | disjunction.put("operands", new ArrayList<Object>()); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 389 | objectStack.push(disjunction); |
| 390 | stackedObjects++; |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 391 | // Step II: decide where to put |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 392 | putIntoSuperObject(disjunction, 1); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 393 | } |
| 394 | |
| 395 | if (nodeCat.equals("OPPROX")) { |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 396 | //TODO direction "both": wrap in "or" group with operands once flipped, once not |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 397 | // collect info |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 398 | Tree prox_opts = node.getChild(0); |
| 399 | Tree typ = prox_opts.getChild(0); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 400 | Tree dist_list = prox_opts.getChild(1); |
| Joachim Bingel | 89cceac | 2014-01-08 15:51:08 +0000 | [diff] [blame] | 401 | // Step I: create group |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 402 | LinkedHashMap<String, Object> proxSequence = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 403 | proxSequence.put("@type", "korap:group"); |
| 404 | proxSequence.put("operation", "operation:"+ "sequence"); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 405 | objectStack.push(proxSequence); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 406 | stackedObjects++; |
| Joachim Bingel | 89cceac | 2014-01-08 15:51:08 +0000 | [diff] [blame] | 407 | ArrayList<Object> constraints = new ArrayList<Object>(); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 408 | boolean exclusion = ! typ.getChild(0).toStringTree().equals("PROX"); |
| 409 | |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 410 | boolean inOrder = false; |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 411 | proxSequence.put("inOrder", inOrder); |
| 412 | proxSequence.put("distances", constraints); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 413 | |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 414 | ArrayList<Object> operands = new ArrayList<Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 415 | proxSequence.put("operands", operands); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 416 | |
| 417 | // possibly several distance constraints |
| 418 | for (int i=0; i<dist_list.getChildCount(); i++) { |
| 419 | String direction = dist_list.getChild(i).getChild(0).getChild(0).toStringTree().toLowerCase(); |
| 420 | String min = dist_list.getChild(i).getChild(1).getChild(0).toStringTree(); |
| 421 | String max = dist_list.getChild(i).getChild(1).getChild(1).toStringTree(); |
| 422 | String meas = dist_list.getChild(i).getChild(2).getChild(0).toStringTree(); |
| Joachim Bingel | 89cceac | 2014-01-08 15:51:08 +0000 | [diff] [blame] | 423 | if (min.equals("VAL0")) { |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 424 | min="0"; |
| Joachim Bingel | 89cceac | 2014-01-08 15:51:08 +0000 | [diff] [blame] | 425 | } |
| 426 | LinkedHashMap<String, Object> distance = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 427 | distance.put("@type", "korap:distance"); |
| 428 | distance.put("key", meas); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 429 | distance.put("min", Integer.parseInt(min)); |
| 430 | distance.put("max", Integer.parseInt(max)); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 431 | if (exclusion) { |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 432 | distance.put("exclude", exclusion); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 433 | } |
| Joachim Bingel | 89cceac | 2014-01-08 15:51:08 +0000 | [diff] [blame] | 434 | constraints.add(distance); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 435 | if (direction.equals("plus")) { |
| 436 | inOrder=true; |
| 437 | } else if (direction.equals("minus")) { |
| 438 | inOrder=true; |
| 439 | invertedOperandsLists.add(operands); |
| Joachim Bingel | 89cceac | 2014-01-08 15:51:08 +0000 | [diff] [blame] | 440 | } |
| 441 | } |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 442 | proxSequence.put("inOrder", inOrder); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 443 | // Step II: decide where to put |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 444 | putIntoSuperObject(proxSequence, 1); |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 445 | } |
| 446 | |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 447 | // inlcusion or overlap |
| 448 | if (nodeCat.equals("OPIN") || nodeCat.equals("OPOV")) { |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 449 | // Step I: create group |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 450 | LinkedHashMap<String, Object> submatchgroup = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 451 | submatchgroup.put("@type", "korap:group"); |
| 452 | submatchgroup.put("operation", "operation:"+ "submatch"); |
| 453 | ArrayList<Integer> classRef = new ArrayList<Integer>(); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 454 | classRef.add(classRefCounter); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 455 | submatchgroup.put("classRef", classRef); |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 456 | |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 457 | ArrayList<Object> submatchoperands = new ArrayList<Object>(); |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 458 | LinkedHashMap<String, Object> posgroup = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 459 | submatchgroup.put("operands", submatchoperands); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 460 | submatchoperands.add(posgroup); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 461 | posgroup.put("@type", "korap:group"); |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 462 | // String relation = nodeCat.equals("OPIN") ? "position" : "overlaps"; |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 463 | posgroup.put("operation", "operation:"+ "position"); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 464 | if (nodeCat.equals("OPIN")) { |
| 465 | parseOPINOptions(node, posgroup); |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 466 | } else { |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 467 | parseOPOVOptions(node, posgroup); |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 468 | } |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 469 | ArrayList<Object> posoperands = new ArrayList<Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 470 | posgroup.put("operands", posoperands); |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 471 | objectStack.push(posgroup); |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 472 | // mark this an inverted list |
| 473 | invertedOperandsLists.push(posoperands); |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 474 | stackedObjects++; |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 475 | // Step II: decide where to put |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 476 | putIntoSuperObject(submatchgroup, 1); |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 477 | } |
| 478 | |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 479 | |
| 480 | // Wrap the first argument of an #IN operator in a class group |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 481 | if (nodeCat.equals("ARG1") && (openNodeCats.get(1).equals("OPIN") || openNodeCats.get(1).equals("OPOV") || openNodeCats.get(2).equals("OPNHIT"))) { |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 482 | // Step I: create group |
| 483 | LinkedHashMap<String, Object> classGroup = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 484 | classGroup.put("@type", "korap:group"); |
| 485 | classGroup.put("operation", "operation:"+ "class"); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 486 | classGroup.put("class", classRefCounter); |
| 487 | classRefCounter++; |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 488 | classGroup.put("operands", new ArrayList<Object>()); |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 489 | objectStack.push(classGroup); |
| 490 | stackedObjects++; |
| 491 | // Step II: decide where to put |
| 492 | putIntoSuperObject(classGroup, 1); |
| 493 | } |
| 494 | |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 495 | // Wrap the 2nd argument of an #IN operator embedded in NHIT in a class group |
| 496 | if (nodeCat.equals("ARG2") && openNodeCats.get(2).equals("OPNHIT")) { |
| 497 | // Step I: create group |
| 498 | LinkedHashMap<String, Object> classGroup = new LinkedHashMap<String, Object>(); |
| 499 | classGroup.put("@type", "korap:group"); |
| 500 | classGroup.put("operation", "operation:"+ "class"); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 501 | classGroup.put("class", classRefCounter); |
| 502 | classRefCounter++; |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 503 | classGroup.put("operands", new ArrayList<Object>()); |
| 504 | objectStack.push(classGroup); |
| 505 | stackedObjects++; |
| 506 | // Step II: decide where to put |
| 507 | putIntoSuperObject(classGroup, 1); |
| 508 | } |
| 509 | |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 510 | |
| Joachim Bingel | 8c640e4 | 2014-02-07 16:20:47 +0000 | [diff] [blame] | 511 | if (nodeCat.equals("OPNHIT")) { |
| Joachim Bingel | 8c640e4 | 2014-02-07 16:20:47 +0000 | [diff] [blame] | 512 | LinkedHashMap<String, Object> exclGroup = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 513 | exclGroup.put("@type", "korap:group"); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 514 | exclGroup.put("operation", "operation:"+ "submatch"); |
| Joachim Bingel | 8c640e4 | 2014-02-07 16:20:47 +0000 | [diff] [blame] | 515 | ArrayList<Integer> classRef = new ArrayList<Integer>(); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 516 | |
| 517 | classRef.add(classRefCounter); |
| 518 | // classRefCounter++; |
| 519 | // yes, do this twice! |
| 520 | classRef.add(classRefCounter+1); |
| 521 | // classRefCounter++; |
| Joachim Bingel | 8c640e4 | 2014-02-07 16:20:47 +0000 | [diff] [blame] | 522 | exclGroup.put("classRef", classRef); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 523 | exclGroup.put("classRefOp", "classRefOp:"+"intersection"); |
| Joachim Bingel | 8c640e4 | 2014-02-07 16:20:47 +0000 | [diff] [blame] | 524 | ArrayList<Object> operands = new ArrayList<Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 525 | exclGroup.put("operands", operands); |
| Joachim Bingel | 8c640e4 | 2014-02-07 16:20:47 +0000 | [diff] [blame] | 526 | objectStack.push(exclGroup); |
| 527 | stackedObjects++; |
| 528 | putIntoSuperObject(exclGroup, 1); |
| Joachim Bingel | 89cceac | 2014-01-08 15:51:08 +0000 | [diff] [blame] | 529 | } |
| 530 | |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 531 | if (nodeCat.equals("OPEND") || nodeCat.equals("OPBEG")) { |
| 532 | // Step I: create group |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 533 | LinkedHashMap<String, Object> beggroup = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 534 | beggroup.put("@type", "korap:group"); |
| 535 | beggroup.put("operation", "operation:"+ "submatch"); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 536 | ArrayList<Integer> spanRef = new ArrayList<Integer>(); |
| 537 | if (nodeCat.equals("OPBEG")) { |
| 538 | spanRef.add(0); spanRef.add(1); |
| 539 | } else { |
| 540 | spanRef.add(-1); spanRef.add(1); |
| 541 | } |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 542 | beggroup.put("spanRef", spanRef); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 543 | beggroup.put("operands", new ArrayList<Object>()); |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 544 | objectStack.push(beggroup); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 545 | stackedObjects++; |
| 546 | |
| 547 | // Step II: decide where to put |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 548 | putIntoSuperObject(beggroup, 1); |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 549 | } |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 550 | |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 551 | if (nodeCat.equals("OPBED")) { |
| 552 | // Step I: create group |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 553 | int optsChild = node.getChildCount()-1; |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 554 | Tree conditions = node.getChild(optsChild).getChild(0); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 555 | |
| 556 | // create a containing group expressing the submatch constraint on the first argument |
| 557 | LinkedHashMap<String, Object> submatchgroup = new LinkedHashMap<String, Object>(); |
| 558 | submatchgroup.put("@type", "korap:group"); |
| 559 | submatchgroup.put("operation", "operation:"+ "submatch"); |
| 560 | ArrayList<Integer> spanRef = new ArrayList<Integer>(); |
| 561 | spanRef.add(1); |
| 562 | submatchgroup.put("classRef", spanRef); |
| 563 | ArrayList<Object> submatchoperands = new ArrayList<Object>(); |
| 564 | submatchgroup.put("operands", submatchoperands); |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 565 | putIntoSuperObject(submatchgroup, 0); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 566 | |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 567 | // Distinguish two cases. Normal case: query has just one condition, like #BED(X, sa) ... |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 568 | if (conditions.getChildCount()==1) { |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 569 | CosmasCondition c = new CosmasCondition(conditions.getChild(0)); |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 570 | |
| 571 | // create the group expressing the position constraint |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 572 | LinkedHashMap<String, Object> posgroup = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 573 | posgroup.put("@type", "korap:group"); |
| 574 | posgroup.put("operation", "operation:"+ "position"); |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 575 | |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 576 | posgroup.put("frame", "frame:"+c.position); |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 577 | if (c.negated) posgroup.put("exclude", true); |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 578 | ArrayList<Object> operands = new ArrayList<Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 579 | posgroup.put("operands", operands); |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 580 | |
| 581 | // create span representing the element expressed in the condition |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 582 | LinkedHashMap<String, Object> bedElem = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 583 | bedElem.put("@type", "korap:span"); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 584 | bedElem.put("key", c.elem); |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 585 | |
| 586 | // create a class group containing the argument, in order to submatch the arg. |
| 587 | LinkedHashMap<String, Object> classGroup = new LinkedHashMap<String, Object>(); |
| 588 | classGroup.put("@type", "korap:group"); |
| 589 | classGroup.put("operation", "operation:class"); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 590 | classGroup.put("class", classRefCounter); |
| 591 | classRefCounter++; |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 592 | classGroup.put("operands", new ArrayList<Object>()); |
| 593 | objectStack.push(classGroup); |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 594 | stackedObjects++; |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 595 | operands.add(bedElem); |
| 596 | operands.add(classGroup); |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 597 | // Step II: decide where to put |
| Joachim Bingel | cd7b725 | 2014-02-13 08:49:14 +0000 | [diff] [blame] | 598 | submatchoperands.add(posgroup); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 599 | |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 600 | // ... or the query has several conditions specified, like #BED(XY, sa,-pa). In that case, |
| 601 | // create an 'and' group and embed the position groups in its operands |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 602 | } else { |
| 603 | // node has several conditions (like 'sa, -pa') |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 604 | // -> create zero-distance sequence group and embed all position groups there |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 605 | LinkedHashMap<String, Object> conjunct = new LinkedHashMap<String, Object>(); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 606 | conjunct.put("@type", "korap:group"); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 607 | conjunct.put("operation", "operation:"+ "sequence"); |
| 608 | ArrayList<Object> distances = new ArrayList<Object>(); |
| 609 | conjunct.put("distances", distances); |
| 610 | LinkedHashMap<String, Object> zerodistance = new LinkedHashMap<String, Object>(); |
| 611 | zerodistance.put("@type", "korap:distance"); |
| 612 | zerodistance.put("key", "w"); |
| 613 | zerodistance.put("min", 0); |
| 614 | zerodistance.put("max", 0); |
| 615 | distances.add(zerodistance); |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 616 | ArrayList<Object> operands = new ArrayList<Object>(); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 617 | conjunct.put("operands", operands); |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 618 | ArrayList<ArrayList<Object>> distributedOperands = new ArrayList<ArrayList<Object>>(); |
| 619 | |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 620 | for (int i=0; i<conditions.getChildCount(); i++) { |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 621 | // for each condition, create a position group containing a class group. problem: how to get argument into every operands list? |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 622 | // -> use distributedOperandsLists |
| 623 | LinkedHashMap<String, Object> posGroup = new LinkedHashMap<String, Object>(); |
| 624 | operands.add(posGroup); |
| 625 | |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 626 | // make position group |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 627 | CosmasCondition c = new CosmasCondition(conditions.getChild(i)); |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 628 | posGroup.put("@type", "korap:group"); |
| 629 | posGroup.put("operation", "operation:"+ "position"); |
| 630 | posGroup.put("frame", "frame:"+c.position); |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 631 | if (c.negated) posGroup.put("exclude", "true"); |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 632 | ArrayList<Object> posOperands = new ArrayList<Object>(); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 633 | |
| 634 | // make class group |
| 635 | LinkedHashMap<String, Object> classGroup = new LinkedHashMap<String, Object>(); |
| 636 | classGroup.put("@type", "korap:group"); |
| 637 | classGroup.put("operation", "operation:class"); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 638 | classGroup.put("class", classRefCounter); |
| 639 | classRefCounter++; |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 640 | ArrayList<Object> classOperands = new ArrayList<Object>(); |
| 641 | classGroup.put("operands", classOperands); |
| 642 | distributedOperands.add(classOperands); // subtree to be put into every class group -> distribute |
| 643 | |
| 644 | // put the span and the class group into the position group |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 645 | posGroup.put("operands", posOperands); |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 646 | LinkedHashMap<String, Object> span = new LinkedHashMap<String, Object>(); |
| 647 | posOperands.add(span); |
| 648 | posOperands.add(classGroup); |
| 649 | span.put("@type", "korap:span"); |
| 650 | span.put("key", c.elem); |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 651 | } |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 652 | submatchoperands.add(conjunct); |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 653 | distributedOperandsLists.push(distributedOperands); |
| Joachim Bingel | 3f0850c | 2014-01-17 16:50:10 +0000 | [diff] [blame] | 654 | } |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 655 | |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 656 | } |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 657 | objectsToPop.push(stackedObjects); |
| 658 | |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 659 | /* |
| 660 | **************************************************************** |
| 661 | **************************************************************** |
| 662 | * recursion until 'request' node (root of tree) is processed * |
| 663 | **************************************************************** |
| 664 | **************************************************************** |
| 665 | */ |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 666 | for (int i=0; i<node.getChildCount(); i++) { |
| 667 | Tree child = node.getChild(i); |
| 668 | processNode(child); |
| 669 | } |
| 670 | |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 671 | /* |
| 672 | ************************************************************** |
| 673 | * Stuff that happens after processing the children of a node * |
| 674 | ************************************************************** |
| 675 | */ |
| 676 | |
| Joachim Bingel | d5161a1 | 2014-01-08 11:15:49 +0000 | [diff] [blame] | 677 | // remove sequence from object stack if node is implicitly sequenced |
| 678 | if (sequencedNodes.size()>0) { |
| 679 | if (node == sequencedNodes.getFirst()) { |
| 680 | objectStack.pop(); |
| 681 | sequencedNodes.pop(); |
| 682 | } |
| 683 | } |
| 684 | |
| Joachim Bingel | eecc765 | 2014-01-11 17:21:07 +0000 | [diff] [blame] | 685 | for (int i=0; i<objectsToPop.get(0); i++) { |
| 686 | objectStack.pop(); |
| 687 | } |
| 688 | objectsToPop.pop(); |
| 689 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 690 | if (nodeCat.equals("ARG2") && openNodeCats.get(1).equals("OPNOT")) { |
| 691 | negate = false; |
| 692 | } |
| 693 | |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 694 | openNodeCats.pop(); |
| 695 | |
| 696 | } |
| 697 | |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 698 | |
| Joachim Bingel | ffd65e3 | 2014-01-22 14:22:57 +0000 | [diff] [blame] | 699 | |
| 700 | |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 701 | private Object translateMorph(String layer) { |
| 702 | LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(); |
| 703 | map.put("ANA", "pos"); |
| 704 | if (map.containsKey(layer)) |
| 705 | return map.get(layer); |
| 706 | else |
| 707 | return layer; |
| 708 | } |
| 709 | |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 710 | private void parseOPINOptions(Tree node, LinkedHashMap<String, Object> posgroup) { |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 711 | Tree posnode = getFirstChildWithCat(node, "POS"); |
| 712 | Tree rangenode = getFirstChildWithCat(node, "RANGE"); |
| 713 | Tree exclnode = getFirstChildWithCat(node, "EXCL"); |
| 714 | Tree groupnode = getFirstChildWithCat(node, "GROUP"); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 715 | boolean negatePosition = false; |
| 716 | |
| 717 | String position = ""; |
| 718 | if (posnode != null) { |
| 719 | String value = posnode.getChild(0).toStringTree(); |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 720 | position = translateTextAreaArgument(value, "in"); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 721 | if (value.equals("N")) { |
| 722 | negatePosition = !negatePosition; |
| 723 | } |
| 724 | } else { |
| 725 | position = "contains"; |
| 726 | } |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 727 | posgroup.put("frame", "frame:"+position); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 728 | position = openNodeCats.get(1).equals("OPIN") ? "contains" : "full"; |
| 729 | |
| 730 | if (rangenode != null) { |
| 731 | String range = rangenode.getChild(0).toStringTree(); |
| 732 | posgroup.put("range", range.toLowerCase()); |
| 733 | } |
| 734 | |
| 735 | if (exclnode != null) { |
| 736 | if (exclnode.getChild(0).toStringTree().equals("YES")) { |
| 737 | negatePosition = !negatePosition; |
| 738 | } |
| 739 | } |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 740 | System.err.println(negatePosition); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 741 | if (negatePosition) { |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 742 | posgroup.put("exclude", "true"); |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 743 | // negate = !negate; |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 744 | } |
| 745 | |
| 746 | if (groupnode != null) { |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 747 | String grouping = groupnode.getChild(0).toStringTree().equals("max") ? "true" : "false"; |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 748 | posgroup.put("grouping", grouping); |
| 749 | } |
| 750 | } |
| 751 | |
| 752 | private void parseOPOVOptions(Tree node, LinkedHashMap<String, Object> posgroup) { |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 753 | Tree posnode = getFirstChildWithCat(node, "POS"); |
| 754 | Tree exclnode = getFirstChildWithCat(node, "EXCL"); |
| 755 | Tree groupnode = getFirstChildWithCat(node, "GROUP"); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 756 | |
| 757 | String position = ""; |
| 758 | if (posnode != null) { |
| 759 | String value = posnode.getChild(0).toStringTree(); |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 760 | position = "-"+translateTextAreaArgument(value, "ov"); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 761 | } |
| Joachim Bingel | 2daf986 | 2014-02-12 10:18:54 +0000 | [diff] [blame] | 762 | posgroup.put("frame", "frame:"+"overlaps"+position); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 763 | |
| 764 | if (exclnode != null) { |
| 765 | if (exclnode.getChild(0).toStringTree().equals("YES")) { |
| Joachim Bingel | ee3b21d | 2014-02-12 12:34:59 +0000 | [diff] [blame] | 766 | posgroup.put("match", "match:"+"ne"); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 767 | } |
| 768 | } |
| 769 | if (groupnode != null) { |
| Joachim Bingel | ba9a0ab | 2014-01-29 10:12:25 +0000 | [diff] [blame] | 770 | String grouping = groupnode.getChild(0).toStringTree().equals("@max") ? "true" : "false"; |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 771 | posgroup.put("grouping", grouping); |
| 772 | } |
| 773 | |
| 774 | } |
| 775 | |
| 776 | /** |
| Joachim Bingel | 36233b5 | 2014-02-13 10:48:24 +0000 | [diff] [blame] | 777 | * Translates the text area specifications (position option arguments) to terms used in serialisation. |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 778 | * For the allowed argument types and their values for OPIN and OPOV, see |
| 779 | * http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/ARGUMENT_I.html or |
| 780 | * http://www.ids-mannheim.de/cosmas2/win-app/hilfe/suchanfrage/eingabe-grafisch/syntax/ARGUMENT_O.html, respectively. |
| 781 | * @param argument |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 782 | * @param mode |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 783 | * @return |
| 784 | */ |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 785 | private String translateTextAreaArgument(String argument, String mode) { |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 786 | String position = ""; |
| 787 | switch (argument) { |
| 788 | case "L": |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 789 | position = mode.equals("in") ? "startswith" : "left"; |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 790 | break; |
| 791 | case "R": |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 792 | position = mode.equals("in") ? "endswith" : "right"; |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 793 | break; |
| 794 | case "F": |
| 795 | position = "leftrightmatch"; |
| 796 | break; |
| 797 | case "FE": |
| Joachim Bingel | 84e33df | 2014-01-31 14:02:46 +0000 | [diff] [blame] | 798 | position = "matches"; |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 799 | break; |
| 800 | case "FI": |
| 801 | position = "leftrightmatch-noident"; |
| 802 | break; |
| 803 | case "N": // for OPIN only - exclusion constraint formulated in parseOPINOptions |
| 804 | position = "leftrightmatch"; |
| 805 | break; |
| 806 | case "X": // for OPOV only |
| 807 | position = "residual"; |
| 808 | break; |
| 809 | } |
| 810 | return position; |
| 811 | } |
| 812 | |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 813 | @SuppressWarnings("unchecked") |
| 814 | private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) { |
| Joachim Bingel | e98d088 | 2014-01-21 12:58:54 +0000 | [diff] [blame] | 815 | if (distributedOperandsLists.size()>0) { |
| 816 | ArrayList<ArrayList<Object>> distributedOperands = distributedOperandsLists.pop(); |
| 817 | for (ArrayList<Object> operands : distributedOperands) { |
| 818 | operands.add(object); |
| 819 | } |
| 820 | } else if (objectStack.size()>objStackPosition) { |
| Joachim Bingel | 11d5b15 | 2014-02-11 21:33:47 +0000 | [diff] [blame] | 821 | ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands"); |
| Joachim Bingel | cc1dc24 | 2014-01-15 09:32:38 +0000 | [diff] [blame] | 822 | if (!invertedOperandsLists.contains(topObjectOperands)) { |
| 823 | topObjectOperands.add(object); |
| 824 | } else { |
| 825 | topObjectOperands.add(0, object); |
| 826 | } |
| 827 | |
| 828 | } else { |
| 829 | requestMap.put("query", object); |
| 830 | } |
| 831 | } |
| 832 | |
| 833 | private void putIntoSuperObject(LinkedHashMap<String, Object> object) { |
| 834 | putIntoSuperObject(object, 0); |
| 835 | } |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 836 | |
| Joachim Bingel | b5f7bf0 | 2014-01-07 16:36:54 +0000 | [diff] [blame] | 837 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 838 | private Tree parseCosmasQuery(String q) throws RecognitionException { |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 839 | Pattern p = Pattern.compile("(\\w+):((\\+|-)?(sa|se|pa|pe|ta|te),?)+"); |
| 840 | Matcher m = p.matcher(q); |
| 841 | |
| 842 | String rewrittenQuery = q; |
| 843 | while (m.find()) { |
| 844 | String match = m.group(); |
| 845 | String conditionsString = match.split(":")[1]; |
| 846 | Pattern conditionPattern = Pattern.compile("(\\+|-)?(sa|se|pa|pe|ta|te)"); |
| 847 | Matcher conditionMatcher = conditionPattern.matcher(conditionsString); |
| 848 | String replacement = "#BED("+m.group(1)+" , "; |
| 849 | while (conditionMatcher.find()) { |
| 850 | replacement = replacement+conditionMatcher.group()+","; |
| 851 | } |
| 852 | replacement = replacement.substring(0, replacement.length()-1)+")"; //remove trailing comma and close parenthesis |
| 853 | System.out.println(replacement); |
| 854 | rewrittenQuery = rewrittenQuery.replace(match, replacement); |
| 855 | } |
| 856 | q = rewrittenQuery; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 857 | Tree tree = null; |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 858 | ANTLRStringStream ss = new ANTLRStringStream(q); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 859 | c2psLexer lex = new c2psLexer(ss); |
| 860 | org.antlr.runtime.CommonTokenStream tokens = new org.antlr.runtime.CommonTokenStream(lex); //v3 |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 861 | parser = new c2psParser(tokens); |
| 862 | c2psParser.c2ps_query_return c2Return = ((c2psParser) parser).c2ps_query(); // statt t(). |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 863 | // AST Tree anzeigen: |
| 864 | tree = (Tree)c2Return.getTree(); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 865 | |
| 866 | String treestring = tree.toStringTree(); |
| 867 | if (treestring.contains("<mismatched token") || treestring.contains("<error") || treestring.contains("<unexpected")) { |
| 868 | throw new RecognitionException(); |
| 869 | } |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 870 | return tree; |
| 871 | } |
| 872 | |
| 873 | /** |
| 874 | * @param args |
| 875 | */ |
| 876 | public static void main(String[] args) { |
| 877 | /* |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 878 | * For debugging |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 879 | */ |
| 880 | String[] queries = new String[] { |
| 881 | /* COSMAS 2 */ |
| Joachim Bingel | 8c640e4 | 2014-02-07 16:20:47 +0000 | [diff] [blame] | 882 | // "MORPH(V)", |
| 883 | // "MORPH(V PRES)", |
| 884 | // "wegen #IN(%, L) <s>", |
| 885 | // "wegen #IN(%) <s>", |
| 886 | // "(Mann oder Frau) #IN <s>", |
| 887 | // "#BEG(der /w3:5 Mann) /+w10 kommt", |
| 888 | // "&würde /w0 MORPH(V)", |
| Joachim Bingel | 8181263 | 2014-02-18 08:55:22 +0000 | [diff] [blame] | 889 | // "#NHIT(gehen /w1:10 voran)", |
| 890 | // "#BED(der Mann , sa,-pa)", |
| 891 | // "Mann /t0 Frau", |
| 892 | "sagt der:sa Bundeskanzler", |
| 893 | // "Der:sa,-pe,+te ", |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 894 | "#ELEM(W POS!='N V' title=tada)", |
| 895 | "#ELEM(W ANA != 'N V')" |
| 896 | // "(&Baum #IN #ELEM(NP)) #IN(L) #ELEM(S)" |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 897 | }; |
| Joachim Bingel | 5dd9168 | 2014-02-14 13:10:29 +0000 | [diff] [blame] | 898 | // CosmasTree.debug=true; |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 899 | for (String q : queries) { |
| 900 | try { |
| 901 | System.out.println(q); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 902 | try { |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 903 | CosmasTree act = new CosmasTree(q); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 904 | System.out.println(act.parseCosmasQuery(q).toStringTree()); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 905 | } catch (QueryException e) { |
| 906 | e.printStackTrace(); |
| Joachim Bingel | 402c6e1 | 2014-05-08 17:09:06 +0000 | [diff] [blame^] | 907 | } catch (RecognitionException e) { |
| 908 | e.printStackTrace(); |
| Joachim Bingel | 87480d0 | 2014-01-17 14:07:46 +0000 | [diff] [blame] | 909 | } |
| Joachim Bingel | 5c93f90 | 2013-11-19 14:49:04 +0000 | [diff] [blame] | 910 | System.out.println(); |
| 911 | |
| 912 | } catch (NullPointerException npe) { |
| 913 | npe.printStackTrace(); |
| 914 | System.out.println("null\n"); |
| 915 | } |
| 916 | } |
| 917 | } |
| 918 | } |