bugfix (mixed var references and direct declarations)
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
index 7b9a7e4..eee2507 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/AbstractSyntaxTree.java
@@ -6,10 +6,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.antlr.runtime.tree.Tree;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
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 64141aa..fdda503 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
@@ -42,7 +42,7 @@
/**
* Keeps track of explicitly (by #-var definition) or implicitly (number as reference) introduced entities (for later reference by #-operator)
*/
- Map<String, LinkedHashMap<String,Object>> variableReferences = new LinkedHashMap<String, LinkedHashMap<String,Object>>();
+ Map<String, LinkedHashMap<String,Object>> nodeVariables = new LinkedHashMap<String, LinkedHashMap<String,Object>>();
/**
* Counter for variable definitions.
*/
@@ -108,6 +108,12 @@
if (verbose) System.out.println(tree.toStringTree(parser));
processNode(tree);
log.info(requestMap.toString());
+
+ for (String ref : nodeVariables.keySet()) {
+ if (nodeReferencesTotal.get(ref) == null) {
+ System.err.println(ref);
+ }
+ }
}
@SuppressWarnings("unchecked")
@@ -177,12 +183,13 @@
}
}
}
+ System.err.println(nodeVariables);
}
if (nodeCat.equals("unary_linguistic_term")) {
LinkedHashMap<String, Object> unaryOperator = parseUnaryOperator(node);
String reference = node.getChild(0).toStringTree(parser).substring(1);
- LinkedHashMap<String, Object> object = variableReferences.get(reference);
+ LinkedHashMap<String, Object> object = nodeVariables.get(reference);
object.putAll(unaryOperator);
}
@@ -191,62 +198,7 @@
}
if (nodeCat.equals("variableExpr")) {
- // simplex word or complex assignment (like qname = textSpec)?
- String firstChildNodeCat = getNodeCat(node.getChild(0));
- LinkedHashMap<String, Object> object = null;
- if (firstChildNodeCat.equals("node")) {
- object = makeSpan();
- } else if (firstChildNodeCat.equals("tok")) {
- object = makeToken();
- if (node.getChildCount() > 1) { // empty tokens do not wrap a term
- LinkedHashMap<String, Object> term = makeTerm();
- term.put("layer", "orth");
- object.put("wrap", term);
- }
- } else if (firstChildNodeCat.equals("qName")) { // only (foundry/)?layer specified
- // may be token or span, depending on indicated layer! (e.g. cnx/cat=NP vs mate/pos=NN)
- // TODO generalize the list below -> look up layers associated with tokens rather than spans somewhere
- HashMap<String, Object> qNameParse = parseQNameNode(node.getChild(0));
- if (Arrays.asList(new String[]{"p", "lemma", "m", "orth"}).contains(qNameParse.get("layer"))) {
- object = makeToken();
- LinkedHashMap<String, Object> term = makeTerm();
- object.put("wrap", term);
- term.putAll(qNameParse);
- } else {
- object = makeSpan();
- object.putAll(qNameParse);
- }
- } else if (firstChildNodeCat.equals("textSpec")) {
- object = makeToken();
- LinkedHashMap<String, Object> term = makeTerm();
- object.put("wrap", term);
- term.put("layer", "orth");
- term.putAll(parseTextSpec(node.getChild(0)));
- }
-
- if (node.getChildCount() == 3) { // (foundry/)?layer=key specification
- if (object.get("@type").equals("korap:token")) {
- HashMap<String, Object> term = (HashMap<String, Object>) object.get("wrap");
- term.putAll(parseTextSpec(node.getChild(2)));
- term.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
- } else {
- object.putAll(parseTextSpec(node.getChild(2)));
- object.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
- }
- }
-
- if (object != null) {
- if (! operandOnlyNodeRefs.contains(variableCounter.toString())) {
- putIntoSuperObject(object);
- }
- ParseTree parentsFirstChild = node.getParent().getChild(0);
- if (getNodeCat(parentsFirstChild).endsWith("#")) {
- variableReferences.put(getNodeCat(parentsFirstChild).replaceAll("#", ""), object);
- }
- variableReferences.put(variableCounter.toString(), object);
- variableCounter++;
- System.out.println(variableReferences);
- }
+ processVariableExpr(node);
}
objectsToPop.push(stackedObjects);
@@ -278,24 +230,85 @@
+ private LinkedHashMap<String, Object> processVariableExpr(ParseTree node) {
+ // simplex word or complex assignment (like qname = textSpec)?
+ String firstChildNodeCat = getNodeCat(node.getChild(0));
+ LinkedHashMap<String, Object> object = null;
+ if (firstChildNodeCat.equals("node")) {
+ object = makeSpan();
+ } else if (firstChildNodeCat.equals("tok")) {
+ object = makeToken();
+ if (node.getChildCount() > 1) { // empty tokens do not wrap a term
+ LinkedHashMap<String, Object> term = makeTerm();
+ term.put("layer", "orth");
+ object.put("wrap", term);
+ }
+ } else if (firstChildNodeCat.equals("qName")) { // only (foundry/)?layer specified
+ // may be token or span, depending on indicated layer! (e.g. cnx/cat=NP vs mate/pos=NN)
+ // TODO generalize the list below -> look up layers associated with tokens rather than spans somewhere
+ HashMap<String, Object> qNameParse = parseQNameNode(node.getChild(0));
+ if (Arrays.asList(new String[]{"p", "lemma", "m", "orth"}).contains(qNameParse.get("layer"))) {
+ object = makeToken();
+ LinkedHashMap<String, Object> term = makeTerm();
+ object.put("wrap", term);
+ term.putAll(qNameParse);
+ } else {
+ object = makeSpan();
+ object.putAll(qNameParse);
+ }
+ } else if (firstChildNodeCat.equals("textSpec")) {
+ object = makeToken();
+ LinkedHashMap<String, Object> term = makeTerm();
+ object.put("wrap", term);
+ term.put("layer", "orth");
+ term.putAll(parseTextSpec(node.getChild(0)));
+ }
+
+ if (node.getChildCount() == 3) { // (foundry/)?layer=key specification
+ if (object.get("@type").equals("korap:token")) {
+ HashMap<String, Object> term = (HashMap<String, Object>) object.get("wrap");
+ term.putAll(parseTextSpec(node.getChild(2)));
+ term.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
+ } else {
+ object.putAll(parseTextSpec(node.getChild(2)));
+ object.put("match", parseMatchOperator(getFirstChildWithCat(node, "eqOperator")));
+ }
+ }
+
+ if (object != null) {
+// if (! operandOnlyNodeRefs.contains(variableCounter.toString())) {
+// putIntoSuperObject(object);
+// }
+ if (! getNodeCat(node.getParent().getParent()).equals("n_ary_linguistic_term")) {
+ putIntoSuperObject(object);
+ }
+ ParseTree parentsFirstChild = node.getParent().getChild(0);
+ if (getNodeCat(parentsFirstChild).endsWith("#")) {
+ nodeVariables.put(getNodeCat(parentsFirstChild).replaceAll("#", ""), object);
+ }
+ nodeVariables.put(variableCounter.toString(), object);
+ variableCounter++;
+ }
+ return object;
+ }
+
/**
* Processes an operand node, creating a map for the operand containing all its information
- * given in the node definition (referenced via '#'). If this node has been referred to and used earlier,
- * a korap:reference is created in its place.
+ * given in the node definition (referenced via '#'). If this node has been referred to and used earlier,
+ * a reference is created in its place.
* The operand will be wrapped in a class group if necessary.
- * @param operandTree
+ * @param operandNode
* @return A map object with the appropriate CQLF representation of the operand
*/
- private LinkedHashMap<String, Object> retrieveOperand(ParseTree operandTree) {
+ private LinkedHashMap<String, Object> retrieveOperand(ParseTree operandNode) {
LinkedHashMap<String, Object> operand = null;
- if (!getNodeCat(operandTree.getChild(0)).equals("variableExpr")) {
- String ref = operandTree.getChild(0).toStringTree(parser).substring(1);
- operand = variableReferences.get(ref);
+ if (!getNodeCat(operandNode.getChild(0)).equals("variableExpr")) {
+ String ref = operandNode.getChild(0).toStringTree(parser).substring(1);
+ operand = nodeVariables.get(ref);
if (nodeReferencesTotal.get(ref) > 1) {
if (nodeReferencesProcessed.get(ref)==0) {
refClassMapping.put(ref, classCounter);
operand = wrapInClass(operand, classCounter++);
- nodeReferencesProcessed.put(ref, nodeReferencesProcessed.get(ref)+1);
} else if (nodeReferencesProcessed.get(ref)>0 && nodeReferencesTotal.get(ref)>1) {
try {
operand = wrapInReference(operandStack.pop(), refClassMapping.get(ref));
@@ -303,7 +316,10 @@
operand = makeReference(refClassMapping.get(ref));
}
}
+ nodeReferencesProcessed.put(ref, nodeReferencesProcessed.get(ref)+1);
}
+ } else {
+ operand = processVariableExpr(operandNode.getChild(0));
}
return operand;
}
@@ -324,7 +340,6 @@
// Retrieve operands.
LinkedHashMap<String, Object> operand1 = retrieveOperand(operandTree1);
LinkedHashMap<String, Object> operand2 = retrieveOperand(operandTree2);
-
// 'Proper' n_ary_linguistic_operators receive a considerably different serialisation than 'commonparent' and 'commonancestor'.
// For the latter cases, a dummy span is introduced and declared as a span class that has a dominance relation towards
// the two operands, one after the other, thus resulting in two nested relations! A Poliqarp+ equivalent for A $ B would be
@@ -393,7 +408,7 @@
ParseTree leftChildSpec = getFirstChildWithCat(node.getChild(i).getChild(0), "@l");
ParseTree rightChildSpec = getFirstChildWithCat(node.getChild(i).getChild(0), "@r");
- if (leftChildSpec != null || rightChildSpec != null) { //XXX
+ if (leftChildSpec != null || rightChildSpec != null) {
String frame = (leftChildSpec!=null) ? "frames:startswith" : "frames:endswith";
LinkedHashMap<String,Object> positionGroup = makePosition(new String[]{frame}, null);
operand2 = wrapInClass(operand2, ++classCounter);
@@ -480,8 +495,6 @@
if (operator.equals("dominance")) {
relation = makeRelation();
relation.put("groupType", "relation");
- ParseTree leftChildSpec = getFirstChildWithCat(operatorNode, "@l");
- ParseTree rightChildSpec = getFirstChildWithCat(operatorNode, "@r");
ParseTree qName = getFirstChildWithCat(operatorNode, "qName");
ParseTree edgeSpecNode = getFirstChildWithCat(operatorNode, "edgeSpec");
ParseTree star = getFirstChildWithCat(operatorNode, "*");
@@ -736,7 +749,9 @@
* For testing
*/
String[] queries = new String[] {
- "cat=\"S\" & node & #1 >@l #2"
+ "cat=\"S\" & cat=/NP/ & cat=/PP/ > #2",
+ "pos & tok & #1 . node",
+ "cat=/S/ & cat=/NP/ & cat=/PP/ > #1",
};
// AqlTree.verbose=true;
for (String q : queries) {
diff --git a/src/test/java/AqlTreeTest.java b/src/test/java/AqlTreeTest.java
index a2412bb..a65d2b1 100644
--- a/src/test/java/AqlTreeTest.java
+++ b/src/test/java/AqlTreeTest.java
@@ -167,6 +167,20 @@
res = mapper.readTree(qs.toJSON());
assertEquals(true, res.at("/query/operands/1/key").isMissingNode());
assertEquals("np", res.at("/query/operands/0/key").asText());
+
+ query = "cat=/NP/ & cat=/PP/ > #1";
+ qs.setQuery(query, "annis");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("korap:group", res.at("/query/@type").asText());
+ assertEquals("operation:relation", res.at("/query/operation").asText());
+ assertEquals("korap:span", res.at("/query/operands/0/@type").asText());
+ assertEquals("PP", res.at("/query/operands/0/key").asText());
+ assertEquals("korap:span", res.at("/query/operands/1/@type").asText());
+ assertEquals("NP", res.at("/query/operands/1/key").asText());
+ assertEquals(true, res.at("/query/operands/2").isMissingNode());
+ assertEquals("korap:relation", res.at("/query/relation/@type").asText());
+ assertEquals("korap:term", res.at("/query/relation/wrap/@type").asText());
+ assertEquals("c", res.at("/query/relation/wrap/layer").asText());
}
@Test
@@ -294,9 +308,11 @@
assertEquals(true, res.at("/query/relation/boundary/max").isMissingNode());
}
- //
-// @Test
-// public void testMultipleDominance() throws QueryException {
+
+ @Test
+ public void testMultipleDominance() throws QueryException {
+
+ }
// query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";
// String dom1 =
// "{@type=korap:group, operation=operation:relation, operands=[" +
diff --git a/src/test/java/CosmasTreeTest.java b/src/test/java/CosmasTreeTest.java
index 308f777..fe6370e 100644
--- a/src/test/java/CosmasTreeTest.java
+++ b/src/test/java/CosmasTreeTest.java
@@ -17,7 +17,6 @@
* @author Joachim Bingel (bingel@ids-mannheim.de)
* @version 1.0
*/
-
public class CosmasTreeTest {