precedence in AQL
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
index 493cb47..327f585 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AqlTree.java
@@ -228,8 +228,24 @@
// get referenced operands
// TODO generalize operator
// TODO capture variableExprs
- LinkedHashMap<String, Object> group = makeGroup("relation");
- group.put("relation", parseOperatorNode(node.getChild(1).getChild(0)));
+
+ // get operator and determine type of group (sequence/treeRelation/relation/...)
+ LinkedHashMap<String, Object> operatorTree = parseOperatorNode(node.getChild(1).getChild(0));
+ String groupType;
+ try {
+ groupType = (String) operatorTree.get("groupType");
+ } catch (ClassCastException | NullPointerException n) {
+ groupType = "relation";
+ }
+ LinkedHashMap<String, Object> group = makeGroup(groupType);
+ if (groupType.equals("relation") || groupType.equals("treeRelation")) {
+ LinkedHashMap<String, Object> relationGroup = new LinkedHashMap<String, Object>();
+ putAllButGroupType(relationGroup, operatorTree);
+ group.put("relation", relationGroup);
+ } else if (groupType.equals("sequence")) {
+ putAllButGroupType(group, operatorTree);
+ }
+
List<Object> operands = (List<Object>) group.get("operands");
for (ParseTree refOrNode : getChildrenWithCat(node, "refOrNode")) {
String ref = refOrNode.getChild(0).toStringTree(parser).substring(1);
@@ -319,6 +335,7 @@
// DOMINANCE
if (operator.equals("dominance")) {
relation = makeTreeRelation("dominance");
+ relation.put("groupType", "relation");
ParseTree leftChildSpec = getFirstChildWithCat(operatorNode, "@l");
ParseTree rightChildSpec = getFirstChildWithCat(operatorNode, "@r");
ParseTree qName = getFirstChildWithCat(operatorNode, "qName");
@@ -336,6 +353,7 @@
else if (operator.equals("pointing")) {
// String reltype = operatorNode.getChild(1).toStringTree(parser);
relation = makeRelation(null);
+ relation.put("groupType", "relation");
ParseTree qName = getFirstChildWithCat(operatorNode, "qName");
ParseTree edgeSpec = getFirstChildWithCat(operatorNode, "edgeSpec");
ParseTree star = getFirstChildWithCat(operatorNode, "*");
@@ -347,7 +365,20 @@
}
else if (operator.equals("precedence")) {
-
+ relation = new LinkedHashMap<String, Object>();
+ relation.put("groupType", "sequence");
+ ParseTree rangeSpec = getFirstChildWithCat(operatorNode, "rangeSpec");
+ ParseTree star = getFirstChildWithCat(operatorNode, "*");
+ ArrayList<Object> distances = new ArrayList<Object>();
+ if (star != null) {
+ distances.add(makeDistance("w", 0, 100));
+ relation.put("distances", distances);
+ }
+ if (rangeSpec != null) {
+ distances.add(parseDistance(rangeSpec));
+ relation.put("distances", distances);
+ }
+ relation.put("inOrder", true);
}
else if (operator.equals("spanrelation")) {
@@ -399,6 +430,14 @@
return makeBoundary(min, max);
}
+ private LinkedHashMap<String, Object> parseDistance(ParseTree rangeSpec) {
+ Integer min = Integer.parseInt(rangeSpec.getChild(0).toStringTree(parser));
+ Integer max = MAXIMUM_DISTANCE;
+ if (rangeSpec.getChildCount()==3)
+ max = Integer.parseInt(rangeSpec.getChild(2).toStringTree(parser));
+ return makeDistance("w", min, max);
+ }
+
private LinkedHashMap<String, Object> parseTextSpec(ParseTree node) {
LinkedHashMap<String, Object> term = new LinkedHashMap<String, Object>();
if (hasChild(node, "regex")) {
@@ -456,12 +495,6 @@
@SuppressWarnings({ "unchecked" })
private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) {
-// if (distributedOperandsLists.size()>0) {
-// ArrayList<ArrayList<Object>> distributedOperands = distributedOperandsLists.pop();
-// for (ArrayList<Object> operands : distributedOperands) {
-// operands.add(object);
-// }
-// } else if (objectStack.size()>objStackPosition) {
if (objectStack.size()>objStackPosition) {
ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands");
topObjectOperands.add(0, object);
@@ -471,6 +504,14 @@
}
}
+ private void putAllButGroupType(Map<String, Object> container, Map<String, Object> input) {
+ for (String key : input.keySet()) {
+ if (!key.equals("groupType")) {
+ container.put(key, input.get(key));
+ }
+ }
+ }
+
private ParserRuleContext parseAnnisQuery (String p) throws QueryException {
Lexer poliqarpLexer = new AqlLexer((CharStream)null);
ParserRuleContext tree = null;
@@ -511,35 +552,38 @@
*/
String[] queries = new String[] {
- "#1 . #2 ",
- "#1 . #2 & meta::Genre=\"Sport\"",
- "A _i_ B",
- "A .* B",
- "A >* B",
- "#1 > [label=\"foo\"] #2",
- "pos=\"VVFIN\" & cas=\"Nom\" & #1 . #2",
- "A .* B ",
- "A .* B .* C",
-
- "#1 ->LABEL[lbl=\"foo\"] #2",
- "#1 ->LABEL[lbl=/foo/] #2",
- "#1 ->LABEL[foundry/layer=\"foo\"] #2",
- "#1 ->LABEL[foundry/layer=\"foo\"] #2",
- "node & pos=\"VVFIN\" & #2 > #1",
- "node & pos=\"VVFIN\" & #2 > #1",
- "pos=\"VVFIN\" > cas=\"Nom\" ",
- "pos=\"VVFIN\" >* cas=\"Nom\" ",
- "tiger/pos=\"NN\" > node",
- "ref#node & pos=\"NN\" > #ref",
- "node & tree/pos=\"NN\"",
- "/node/",
- "\"Mann\"",
- "tok!=/Frau/",
- "node",
- "treetagger/pos=\"NN\"",
- "node & node & #2 ->foundry/dep[anno=\"key\"],2,4 #1",
- "tiger/pos=\"NN\" >cnx/cat node",
- "\"Mann\" & node & #2 >[cat=\"NP\"] #1"
+// "#1 . #2 ",
+// "#1 . #2 & meta::Genre=\"Sport\"",
+// "A _i_ B",
+// "A .* B",
+// "A >* B",
+// "#1 > [label=\"foo\"] #2",
+// "pos=\"VVFIN\" & cas=\"Nom\" & #1 . #2",
+// "A .* B ",
+// "A .* B .* C",
+//
+// "#1 ->LABEL[lbl=\"foo\"] #2",
+// "#1 ->LABEL[lbl=/foo/] #2",
+// "#1 ->LABEL[foundry/layer=\"foo\"] #2",
+// "#1 ->LABEL[foundry/layer=\"foo\"] #2",
+// "node & pos=\"VVFIN\" & #2 > #1",
+// "node & pos=\"VVFIN\" & #2 > #1",
+// "pos=\"VVFIN\" > cas=\"Nom\" ",
+// "pos=\"VVFIN\" >* cas=\"Nom\" ",
+// "tiger/pos=\"NN\" > node",
+// "ref#node & pos=\"NN\" > #ref",
+// "node & tree/pos=\"NN\"",
+// "/node/",
+// "\"Mann\"",
+// "tok!=/Frau/",
+// "node",
+// "treetagger/pos=\"NN\"",
+// "node & node & #2 ->foundry/dep[anno=\"key\"],2,4 #1",
+// "tiger/pos=\"NN\" >cnx/cat node",
+// "\"Mann\" & node & #2 >[cat=\"NP\"] #1",
+ "node & node & #1 . #2",
+ "node & node & #1 .2,6 #2",
+ "node & node & #1 .* #2"
// "node & node & #2 ->[foundry/layer=\"key\"],2,4 #1",
};
diff --git a/src/test/java/AqlTreeTest.java b/src/test/java/AqlTreeTest.java
index ccb9eaf..922ca27 100644
--- a/src/test/java/AqlTreeTest.java
+++ b/src/test/java/AqlTreeTest.java
@@ -3,7 +3,6 @@
import org.junit.Test;
import de.ids_mannheim.korap.query.serialize.AqlTree;
-import de.ids_mannheim.korap.query.serialize.PoliqarpPlusTree;
import de.ids_mannheim.korap.util.QueryException;
public class AqlTreeTest {
@@ -137,6 +136,51 @@
assertEquals(dom5.replaceAll(" ", ""), map.replaceAll(" ", ""));
}
+ @Test
+ public void testPointingRelations() throws QueryException {
+ query = "node & node & #2 ->label[coref=\"true\"] #1";
+ String dom1 =
+ "{@type=korap:group, operation=operation:relation, operands=[" +
+ "{@type=korap:span}," +
+ "{@type=korap:span}" +
+ "], relation={@type=korap:relation, layer=coref, label=label, key=true}" +
+ "}";
+ aqlt = new AqlTree(query);
+ map = aqlt.getRequestMap().get("query").toString();
+ assertEquals(dom1.replaceAll(" ", ""), map.replaceAll(" ", ""));
+
+ }
+
+ @Test
+ public void testSequence() throws QueryException {
+ query = "node & node & #1 . #2";
+ String dom1 =
+ "{@type=korap:group, operation=operation:sequence, " +
+ "operands=[" +
+ "{@type=korap:span}," +
+ "{@type=korap:span}" +
+ "], inOrder=true" +
+ "}";
+ aqlt = new AqlTree(query);
+ map = aqlt.getRequestMap().get("query").toString();
+ assertEquals(dom1.replaceAll(" ", ""), map.replaceAll(" ", ""));
+
+ query = "node & node & #1 .* #2";
+ String dom2 =
+ "{@type=korap:group, operation=operation:sequence, " +
+ "operands=[" +
+ "{@type=korap:span}," +
+ "{@type=korap:span}" +
+ "], distances=[" +
+ "{@type=korap:distance, key=w, min=0, max=100}" +
+ "], inOrder=true" +
+ "}";
+ aqlt = new AqlTree(query);
+ map = aqlt.getRequestMap().get("query").toString();
+ assertEquals(dom2.replaceAll(" ", ""), map.replaceAll(" ", ""));
+
+ }
+
}