Introduce query references in Poliqarp
Change-Id: I4d047a4635e0ff7e8fd4e70334e485a6da8e3bd1
diff --git a/Changes b/Changes
index 06e541a..dabde93 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,6 @@
+0.37 2020-10-23
+ - [feature] Introduced query references in Poliqarp (diewald)
+
0.36 2020-07-24
- [security] Upgraded version of Google Guava
(CVE-2018-10237; diewald)
diff --git a/pom.xml b/pom.xml
index 610d340..14a93b9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
<groupId>de.ids_mannheim.korap</groupId>
<artifactId>Koral</artifactId>
- <version>0.36</version>
+ <version>0.37</version>
<packaging>jar</packaging>
<name>Koral</name>
<url>https://korap.ids-mannheim.de</url>
diff --git a/src/main/antlr/poliqarpplus/PoliqarpPlusLexer.g4 b/src/main/antlr/poliqarpplus/PoliqarpPlusLexer.g4
index 02d1ffd..420856e 100644
--- a/src/main/antlr/poliqarpplus/PoliqarpPlusLexer.g4
+++ b/src/main/antlr/poliqarpplus/PoliqarpPlusLexer.g4
@@ -13,7 +13,7 @@
-- author: Joachim Bingel
-- date: 14-06-27
- -- updated: 28-09-2018 (diewald)
+ -- updated: 18-09-28 (diewald)
Poliqarp Query Language lexer
@@ -58,7 +58,7 @@
fragment FOCC : '{' WS* ( [0-9]* WS* ',' WS* [0-9]+ | [0-9]+ WS* ','? ) WS* '}';
fragment NO_RE : ~[ \t/];
fragment ALPHABET : ~('\t' | ' ' | '/' | '*' | '?' | '+' | '{' | '}' | '[' | ']'
- | '(' | ')' | '|' | '"' | ',' | ':' | '\'' | '\\' | '!' | '=' | '~' | '&' | '^' | '<' | '>' );
+ | '(' | ')' | '|' | '"' | ',' | ':' | '\'' | '\\' | '!' | '=' | '~' | '&' | '^' | '<' | '>' | '#' );
NUMBER : [0-9]+;
NL : [\r\n] -> skip;
@@ -90,6 +90,7 @@
EMPTYREL : '@';
BACKSLASH : '\\';
SQUOTE : '\'';
+HASH : '#';
/* Regular expressions and Regex queries */
fragment RE_symbol : ~('*' | '?' | '+' | '{' | '}' | '[' | ']'
diff --git a/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4 b/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4
index 0ba3451..e65d8db 100644
--- a/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4
+++ b/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4
@@ -66,7 +66,7 @@
value
: (WORD | NUMBER) | regex
;
-
+
/* Fields */
term
: NEG* (foundry SLASH)? layer termOp key (COLON value)? flag?
@@ -185,6 +185,18 @@
: emptyTokenSequence
;
+user
+: WORD
+;
+
+ref
+: WORD
+;
+
+queryref
+: LBRACE HASH (user SLASH)? ref RBRACE
+;
+
spanclass
: LBRACE spanclass_id? (segment|sequence) RBRACE
;
@@ -201,6 +213,7 @@
| LRPAREN segment RRPAREN
| emptyTokenSequence
| emptyTokenSequenceClass
+ | queryref
)
repetition?
;
diff --git a/src/main/java/de/ids_mannheim/korap/query/object/KoralType.java b/src/main/java/de/ids_mannheim/korap/query/object/KoralType.java
index cfa0f97..e86dbc3 100644
--- a/src/main/java/de/ids_mannheim/korap/query/object/KoralType.java
+++ b/src/main/java/de/ids_mannheim/korap/query/object/KoralType.java
@@ -12,6 +12,7 @@
RELATION("koral:relation"), DISTANCE("koral:distance"), REFERENCE(
"koral:reference"), DOCUMENT("koral:doc"), DOCUMENT_GROUP("koral:docGroup"),
DOCUMENT_GROUP_REF("koral:docGroupRef"),
+ QUERY_REF("koral:queryRef"),
COSMAS_DISTANCE("cosmas:distance");
String value;
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
index 7cde9c1..6829202 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
@@ -188,6 +188,10 @@
processSubmatch(node);
}
+ if (nodeCat.equals("queryref")) {
+ processQueryref(node);
+ }
+
if (nodeCat.equals("meta")) {
processMeta(node);
}
@@ -297,6 +301,26 @@
}
+ private void processQueryref (ParseTree node) {
+
+ String queryNameStr = "";
+
+ if (getNodeCat(node.getChild(2)).equals("user")) {
+ queryNameStr = node.getChild(2).getText();
+ queryNameStr += '/';
+ queryNameStr += node.getChild(4).getText();
+ }
+ else {
+ queryNameStr = node.getChild(2).getText();
+ }
+
+ Map<String, Object> object = KoralObjectGenerator.makeQueryRef(queryNameStr);
+ putIntoSuperObject(object);
+ objectStack.push(object);
+ stackedObjects++;
+ }
+
+
private void processEmptyTokenSequenceClass (ParseTree node) {
int classId = 1;
if (hasChild(node, "spanclass_id")) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
index 2c65416..9f2a72a 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
@@ -74,7 +74,6 @@
return term;
}
-
public static Map<String, Object> makeDocGroup (String relation) {
Map<String, Object> term = new HashMap<String, Object>();
term.put("@type", KoralType.DOCUMENT_GROUP.toString());
@@ -151,6 +150,12 @@
return group;
}
+ public static Map<String, Object> makeQueryRef (String ref) {
+ Map<String, Object> term = new HashMap<String, Object>();
+ term.put("@type", KoralType.QUERY_REF.toString());
+ term.put("ref", ref);
+ return term;
+ }
public static Map<String, Object> makeClassRefCheck (
ArrayList<ClassRefCheck> checks, ArrayList<Integer> classIn) {
diff --git a/src/test/java/de/ids_mannheim/korap/query/test/poliqarpplus/PoliqarpPlusQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/test/poliqarpplus/PoliqarpPlusQueryProcessorTest.java
index f1562a0..dd4daad 100644
--- a/src/test/java/de/ids_mannheim/korap/query/test/poliqarpplus/PoliqarpPlusQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/test/poliqarpplus/PoliqarpPlusQueryProcessorTest.java
@@ -1615,6 +1615,39 @@
assertEquals("koral:token", res.at("/query/operands/1/@type").asText());
}
+ @Test
+ public void testQueryReferences () throws JsonProcessingException, IOException {
+ query = "{#test}";
+ qs.setQuery(query, "poliqarpplus");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("koral:queryRef", res.at("/query/@type").asText());
+ assertEquals("test", res.at("/query/ref").asText());
+
+ query = "{#admin/example}";
+ qs.setQuery(query, "poliqarpplus");
+ res = mapper.readTree(qs.toJSON());
+ assertEquals("koral:queryRef", res.at("/query/@type").asText());
+ assertEquals("admin/example", res.at("/query/ref").asText());
+
+ query = "Der {#admin/example} [orth=Baum]";
+ qs.setQuery(query, "poliqarpplus");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("koral:token", res.at("/query/operands/0/@type").asText());
+ assertEquals("koral:queryRef", res.at("/query/operands/1/@type").asText());
+ assertEquals("admin/example", res.at("/query/operands/1/ref").asText());
+ assertEquals("koral:token", res.at("/query/operands/2/@type").asText());
+
+ query = "[orth=Der]{#admin/example}{1,}[orth=Baum]";
+ qs.setQuery(query, "poliqarpplus");
+ res = mapper.readTree(qs.toJSON());
+
+ assertEquals("koral:token", res.at("/query/operands/0/@type").asText());
+ assertEquals("koral:group", res.at("/query/operands/1/@type").asText());
+ assertEquals("koral:queryRef", res.at("/query/operands/1/operands/0/@type").asText());
+ assertEquals("admin/example", res.at("/query/operands/1/operands/0/ref").asText());
+ assertEquals("koral:token", res.at("/query/operands/2/@type").asText());
+ }
@Test
public void testMeta () throws JsonProcessingException, IOException {