Added FCS ExpressionGroup.
Change-Id: I31680e81ff454fd20192ca14f0503adf8caa1535
diff --git a/Changes b/Changes
index 2747707..1a233bd 100644
--- a/Changes
+++ b/Changes
@@ -2,6 +2,7 @@
- Spans now always wrap terms (diewald)
- Cosmas-II "und", "oder", and "nicht" operations
now serialize to unordered sequences (diewald)
+ - Cleanup POM (diewald)
0.21 2015-10-27
- Improved meta query builder (hanl)
diff --git a/pom.xml b/pom.xml
index f575129..e59fd5c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,8 +1,6 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <!-- <parent> <groupId>KorAP-modules</groupId> <artifactId>KorAP-core-modules</artifactId>
- <version>1.1</version> </parent> -->
<groupId>de.ids_mannheim.korap</groupId>
<artifactId>Koral</artifactId>
@@ -10,6 +8,36 @@
<packaging>jar</packaging>
<name>Koral</name>
<url>http://maven.apache.org</url>
+
+ <organization>
+ <name>IDS Mannheim</name>
+ <url>http://www.ids-mannheim.de/</url>
+ </organization>
+
+ <developers>
+ <developer>
+ <name>Joachim Bingel</name>
+ <email>bingel@ids-mannheim.de</email>
+ </developer>
+ <developer>
+ <name>Nils Diewald</name>
+ <email>diewald@ids-mannheim.de</email>
+ <url>http://nils-diewald.de</url>
+ </developer>
+ <developer>
+ <name>Michael Hanl</name>
+ <email>hanl@ids-mannheim.de</email>
+ </developer>
+ <developer>
+ <name>Eliza Margaretha</name>
+ <email>margaretha@ids-mannheim.de</email>
+ </developer>
+ </developers>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
<repositories>
<repository>
<id>id-maven-repo</id>
@@ -119,16 +147,16 @@
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.3</version>
- <configuration>
- <compilerVersion>1.7</compilerVersion>
- <source>1.7</source>
- <target>1.7</target>
- </configuration>
- </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <compilerVersion>1.7</compilerVersion>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
<!--
Formatter plugin for Eclipse based coding conventions
http://maven-java-formatter-plugin.googlecode.com/svn/site/0.4/usage.html
@@ -229,7 +257,6 @@
<outputDirectory>${basedir}/src/main/java/de/ids_mannheim/korap/query/parse/cosmas</outputDirectory>
<libDirectory>${basedir}/src/main/antlr</libDirectory>
</configuration>
-
<executions>
<execution>
<goals>
diff --git a/src/main/java/de/ids_mannheim/korap/query/object/KoralContext.java b/src/main/java/de/ids_mannheim/korap/query/object/KoralContext.java
index ca789a9..abdde0b 100644
--- a/src/main/java/de/ids_mannheim/korap/query/object/KoralContext.java
+++ b/src/main/java/de/ids_mannheim/korap/query/object/KoralContext.java
@@ -1,5 +1,9 @@
package de.ids_mannheim.korap.query.object;
+/**
+ * @author margaretha
+ *
+ */
public enum KoralContext {
SENTENCE("s"), PARAGRAPH("p"), TEXT("t");
diff --git a/src/main/java/de/ids_mannheim/korap/query/object/KoralMatchOperator.java b/src/main/java/de/ids_mannheim/korap/query/object/KoralMatchOperator.java
index 2a25202..bd5f6ea 100644
--- a/src/main/java/de/ids_mannheim/korap/query/object/KoralMatchOperator.java
+++ b/src/main/java/de/ids_mannheim/korap/query/object/KoralMatchOperator.java
@@ -1,5 +1,9 @@
package de.ids_mannheim.korap.query.object;
+/**
+ * @author margaretha
+ *
+ */
public enum KoralMatchOperator {
EQUALS("eq"), NOT_EQUALS("ne");
diff --git a/src/main/java/de/ids_mannheim/korap/query/object/KoralTermGroup.java b/src/main/java/de/ids_mannheim/korap/query/object/KoralTermGroup.java
index e9eba9f..eaae803 100644
--- a/src/main/java/de/ids_mannheim/korap/query/object/KoralTermGroup.java
+++ b/src/main/java/de/ids_mannheim/korap/query/object/KoralTermGroup.java
@@ -5,10 +5,8 @@
import java.util.List;
import java.util.Map;
-import de.ids_mannheim.korap.query.parse.fcsql.ExpressionParser;
import de.ids_mannheim.korap.query.serialize.MapBuilder;
import de.ids_mannheim.korap.query.serialize.util.KoralException;
-import eu.clarin.sru.server.fcs.parser.QueryNode;
/**
* @author margaretha
@@ -19,18 +17,12 @@
private static final KoralType type = KoralType.TERMGROUP;
private String relation;
- private List<Object> operands = new ArrayList<Object>();
+ private List<KoralObject> operands = new ArrayList<KoralObject>();
- public KoralTermGroup () {
-
- }
-
- public KoralTermGroup (ExpressionParser parser, KoralRelation relation,
- List<QueryNode> nodes) throws KoralException {
+ public KoralTermGroup (KoralRelation relation, List<KoralObject> operands)
+ throws KoralException {
this.relation = relation.toString();
- for (QueryNode node : nodes) {
- operands.add(parser.parseExpression(node, false, false));
- }
+ this.operands = operands;
}
public String getRelation() {
@@ -41,11 +33,11 @@
this.relation = relation;
}
- public List<Object> getOperands() {
+ public List<KoralObject> getOperands() {
return operands;
}
- public void setOperands(List<Object> operands) {
+ public void setOperands(List<KoralObject> operands) {
this.operands = operands;
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/ExpressionParser.java b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/ExpressionParser.java
index d62f4a7..488b4c8 100644
--- a/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/ExpressionParser.java
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/ExpressionParser.java
@@ -1,20 +1,23 @@
package de.ids_mannheim.korap.query.parse.fcsql;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
-import de.ids_mannheim.korap.query.serialize.util.KoralException;
-import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
import de.ids_mannheim.korap.query.object.KoralMatchOperator;
import de.ids_mannheim.korap.query.object.KoralObject;
import de.ids_mannheim.korap.query.object.KoralRelation;
import de.ids_mannheim.korap.query.object.KoralTerm;
+import de.ids_mannheim.korap.query.object.KoralTerm.KoralTermType;
import de.ids_mannheim.korap.query.object.KoralTermGroup;
import de.ids_mannheim.korap.query.object.KoralToken;
-import de.ids_mannheim.korap.query.object.KoralTerm.KoralTermType;
+import de.ids_mannheim.korap.query.serialize.util.KoralException;
+import de.ids_mannheim.korap.query.serialize.util.StatusCodes;
import eu.clarin.sru.server.fcs.parser.Expression;
import eu.clarin.sru.server.fcs.parser.ExpressionAnd;
+import eu.clarin.sru.server.fcs.parser.ExpressionGroup;
import eu.clarin.sru.server.fcs.parser.ExpressionNot;
import eu.clarin.sru.server.fcs.parser.ExpressionOr;
import eu.clarin.sru.server.fcs.parser.Operator;
@@ -56,9 +59,10 @@
return parseBooleanExpression(operands, KoralRelation.AND);
}
}
- // else if (queryNode instanceof ExpressionGroup) {
- //
- // }
+ else if (queryNode instanceof ExpressionGroup) {
+ // Ignore the group
+ return parseExpression(queryNode.getFirstChild());
+ }
else if (queryNode instanceof ExpressionNot) {
boolean negation = isNot ? false : true;
return parseExpression(queryNode.getChild(0), negation, isToken);
@@ -81,9 +85,13 @@
}
}
- private KoralObject parseBooleanExpression(List<QueryNode> operands,
+ private KoralToken parseBooleanExpression(List<QueryNode> operands,
KoralRelation relation) throws KoralException {
- KoralTermGroup termGroup = new KoralTermGroup(this, relation, operands);
+ List<KoralObject> terms = new ArrayList<>();
+ for (QueryNode node : operands) {
+ terms.add(parseExpression(node, false, false));
+ }
+ KoralTermGroup termGroup = new KoralTermGroup(relation, terms);
return new KoralToken(termGroup);
}
@@ -179,20 +187,32 @@
private void parseRegexFlags(KoralTerm koralTerm, Set<RegexFlag> set) throws KoralException {
// default case sensitive
- if (set != null) {
- for (RegexFlag f : set) {
- if (f == RegexFlag.CASE_SENSITVE) {
- koralTerm.setCaseSensitive(true);
- }
- else if (f == RegexFlag.CASE_INSENSITVE) {
- koralTerm.setCaseSensitive(false);
- }
- else {
- throw new KoralException(StatusCodes.UNKNOWN_QUERY_ELEMENT,
- "SRU diagnostic 48:" + f.name()
- + " is unsupported.");
- }
+ if (set == null) return;
+
+ ArrayList<String> names = new ArrayList<String>();
+ Iterator<RegexFlag> i = set.iterator();
+ while (i.hasNext()) {
+ RegexFlag f = i.next();
+ if (f == RegexFlag.CASE_SENSITVE) {
+ koralTerm.setCaseSensitive(true);
}
+ else if (f == RegexFlag.CASE_INSENSITVE) {
+ koralTerm.setCaseSensitive(false);
+ }
+ else {
+ names.add(f.name());
+ }
+ }
+
+ if (names.size() == 1) {
+ throw new KoralException(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48: Regexflag: " + names.get(0)
+ + " is unsupported.");
+ }
+ else if (names.size() > 1) {
+ throw new KoralException(StatusCodes.UNKNOWN_QUERY_ELEMENT,
+ "SRU diagnostic 48: Regexflags: " + names.toString()
+ + " are unsupported.");
}
}
diff --git a/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/FCSSRUQueryParser.java b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/FCSSRUQueryParser.java
index 2c83c5d..85be144 100644
--- a/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/FCSSRUQueryParser.java
+++ b/src/main/java/de/ids_mannheim/korap/query/parse/fcsql/FCSSRUQueryParser.java
@@ -49,9 +49,11 @@
else if (queryNode instanceof QueryDisjunction) {
return parseGroupQuery(queryNode.getChildren(),
KoralOperation.DISJUNCTION);
- } else if (queryNode instanceof QueryWithWithin) {
+ }
+ else if (queryNode instanceof QueryWithWithin) {
return parseWithinQuery((QueryWithWithin)queryNode);
- } else if (queryNode instanceof SimpleWithin) {
+ }
+ else if (queryNode instanceof SimpleWithin) {
SimpleWithin withinNode = (SimpleWithin) queryNode;
return parseWithinScope(withinNode.getScope());
}
diff --git a/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLComplexTest.java b/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLComplexTest.java
new file mode 100644
index 0000000..3973aea
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLComplexTest.java
@@ -0,0 +1,173 @@
+package de.ids_mannheim.korap.query.serialize;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * @author margaretha
+ *
+ */
+public class FCSQLComplexTest {
+
+ // -------------------------------------------------------------------------
+ // simple-query ::= '(' main_query ')' /* grouping */
+ // | implicit-query
+ // | segment-query
+ // -------------------------------------------------------------------------
+ // implicit-query ::= flagged-regexp
+ // segment-query ::= "[" expression? "]"
+ // -------------------------------------------------------------------------
+ // simple-query ::= '(' main_query ')' /* grouping */
+ @Test
+ public void testGroupQuery() throws IOException {
+ String query = "(\"blaue\"|\"grüne\")";
+ String jsonLd = "{@type:koral:group,"
+ + "operation:operation:disjunction,"
+ + "operands:["
+ + "{@type:koral:token, wrap:{@type:koral:term,key:blaue,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}},"
+ + "{@type:koral:token, wrap:{@type:koral:term,key:grüne,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}]}";;
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ // group and disjunction
+ query = "([pos=\"NN\"]|[cnx:pos=\"N\"]|[text=\"Mann\"])";
+ jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:N,foundry:cnx,layer:p,type:type:regex,match:match:eq}}";
+ FCSQLQueryProcessorTest
+ .validateNode(query, "/query/operands/1", jsonLd);
+
+ // sequence and disjunction
+ query = "([pos=\"NN\"]|[cnx:pos=\"N\"])[text=\"Mann\"]";
+ jsonLd = "{@type:koral:group,"
+ + "operation:operation:sequence,"
+ + "operands:["
+ + "{@type:koral:group,"
+ + "operation:operation:disjunction,"
+ + "operands:[{@type:koral:token,wrap:{@type:koral:term,key:NN,foundry:tt,layer:p,type:type:regex,match:match:eq}},"
+ + "{@type:koral:token,wrap:{@type:koral:term,key:N,foundry:cnx,layer:p,type:type:regex,match:match:eq}}"
+ + "]},"
+ + "{@type:koral:token,wrap:{@type:koral:term,key:Mann,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}"
+ + "]}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ // group and sequence
+ query = "([text=\"blaue\"][pos=\"NN\"])";
+ jsonLd = "{@type:koral:group,"
+ + "operation:operation:sequence,"
+ + "operands:["
+ + "{@type:koral:token,wrap:{@type:koral:term,key:blaue,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}},"
+ + "{@type:koral:token,wrap:{@type:koral:term,key:NN,foundry:tt,layer:p,type:type:regex,match:match:eq}}"
+ + "]}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+ }
+
+ // -------------------------------------------------------------------------
+ // main-query ::= simple-query
+ // | simple-query "|" main-query /* or */
+ // | simple-query main-query /* sequence */
+ // | simple-query quantifier /* quatification */
+ // -------------------------------------------------------------------------
+
+ // | simple-query "|" main-query /* or */
+ @Test
+ public void testOrQuery() throws IOException {
+ String query = "\"man\"|\"Mann\"";
+ String jsonLd = "{@type:koral:group,"
+ + "operation:operation:disjunction,"
+ + "operands:["
+ + "{@type:koral:token,wrap:{@type:koral:term,key:man,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}},"
+ + "{@type:koral:token,wrap:{@type:koral:term,key:Mann,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}]}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "[pos=\"NN\"]|\"Mann\"";
+ jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:NN,foundry:tt,layer:p,type:type:regex,match:match:eq}}";
+ FCSQLQueryProcessorTest
+ .validateNode(query, "/query/operands/0", jsonLd);
+
+ // group with two segment queries
+ query = "[pos=\"NN\"]|[text=\"Mann\"]";
+ jsonLd = "{@type:koral:group,"
+ + "operation:operation:disjunction,"
+ + "operands:["
+ + "{@type:koral:token, wrap:{@type:koral:term,key:NN,foundry:tt,layer:p,type:type:regex,match:match:eq}},"
+ + "{@type:koral:token, wrap:{@type:koral:term,key:Mann,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}]}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "[pos=\"NN\"]&[text=\"Mann\"]";
+ List<Object> error = FCSQLQueryProcessorTest
+ .getError(new FCSQLQueryProcessor(query, "2.0"));
+ assertEquals(399, error.get(0));
+ String msg = (String) error.get(1);
+ assertEquals(true, msg.startsWith("FCS diagnostic 10"));
+ }
+
+ // | simple-query main-query /* sequence */
+ @Test
+ public void testSequenceQuery() throws IOException {
+ String query = "\"blaue|grüne\" [pos = \"NN\"]";
+ String jsonLd = "{@type:koral:group, "
+ + "operation:operation:sequence, "
+ + "operands:["
+ + "{@type:koral:token, wrap:{@type:koral:term, key:blaue|grüne, foundry:opennlp, layer:orth, type:type:regex, match:match:eq}},"
+ + "{@type:koral:token, wrap:{@type:koral:term, key:NN, foundry:tt, layer:p, type:type:regex, match:match:eq}}"
+ + "]}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "[text=\"blaue|grüne\"][pos = \"NN\"]";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "\"blaue\" \"grüne\" [pos = \"NN\"]";
+ jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:grüne, foundry:opennlp, layer:orth, type:type:regex, match:match:eq}}";
+ FCSQLQueryProcessorTest
+ .validateNode(query, "/query/operands/1", jsonLd);
+
+ }
+
+ // | simple-query quantifier /* quatification */
+ @Test
+ public void testQueryWithQuantifier() throws IOException {
+
+ }
+
+ // -------------------------------------------------------------------------
+ // query ::= main-query within-part?
+ // -------------------------------------------------------------------------
+ // within-part ::= simple-within-part
+ // simple-within-part ::= "within" simple-within-scope
+
+ @Test
+ public void testWithinQuery() throws IOException {
+ String query = "[cnx:pos=\"VVFIN\"] within s";
+ String jsonLd = "{@type:koral:group,"
+ + "operation:operation:position,"
+ + "operands:["
+ + "{@type:koral:span,wrap:{@type:koral:term,key:s,foundry:base,layer:s}},"
+ + "{@type:koral:token,wrap:{@type:koral:term,key:VVFIN,foundry:cnx,layer:p,type:type:regex,match:match:eq}}"
+ + "]}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "[cnx:pos=\"VVFIN\"] within sentence";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "[cnx:pos=\"VVFIN\"] within p";
+ jsonLd = "{@type:koral:span,wrap:{@type:koral:term,key:p,foundry:base,layer:s}}";
+ FCSQLQueryProcessorTest
+ .validateNode(query, "/query/operands/0", jsonLd);
+
+ query = "[cnx:pos=\"VVFIN\"] within text";
+ jsonLd = "{@type:koral:span,wrap:{@type:koral:term,key:t,foundry:base,layer:s}}";
+ FCSQLQueryProcessorTest
+ .validateNode(query, "/query/operands/0", jsonLd);
+
+ query = "[cnx:pos=\"VVFIN\"] within u";
+ List<Object> error = FCSQLQueryProcessorTest
+ .getError(new FCSQLQueryProcessor(query, "2.0"));
+ assertEquals(310, error.get(0));
+ assertEquals(
+ "FCS diagnostic 11: Within scope UTTERANCE is currently unsupported.",
+ (String) error.get(1));
+ }
+
+}
diff --git a/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessorTest.java
index 475606a..7fa90d0 100644
--- a/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/FCSQLQueryProcessorTest.java
@@ -17,11 +17,11 @@
*/
public class FCSQLQueryProcessorTest {
- QuerySerializer qs = new QuerySerializer();
- ObjectMapper mapper = new ObjectMapper();
- JsonNode node;
+ static QuerySerializer qs = new QuerySerializer();
+ static ObjectMapper mapper = new ObjectMapper();
+ static JsonNode node;
- private void runAndValidate(String query, String jsonLD)
+ public static void runAndValidate(String query, String jsonLD)
throws JsonProcessingException {
FCSQLQueryProcessor processor = new FCSQLQueryProcessor(query, "2.0");
String serializedQuery = mapper.writeValueAsString(processor
@@ -29,7 +29,7 @@
assertEquals(jsonLD.replace(" ", ""), serializedQuery.replace("\"", ""));
}
- private void validateNode(String query, String path, String jsonLd)
+ public static void validateNode(String query, String path, String jsonLd)
throws JsonProcessingException, IOException {
qs.setQuery(query, "fcsql", "2.0");
node = mapper.readTree(qs.toJSON());
@@ -37,7 +37,7 @@
assertEquals(jsonLd.replace(" ", ""), serializedQuery.replace("\"", ""));
}
- private List<Object> getError(FCSQLQueryProcessor processor) {
+ public static List<Object> getError(FCSQLQueryProcessor processor) {
List<Object> errors = (List<Object>) processor.requestMap.get("errors");
return (List<Object>) errors.get(0);
}
@@ -56,6 +56,7 @@
error.get(1));
}
+ // regexp ::= quoted-string
@Test
public void testTermQuery() throws JsonProcessingException {
String query = "\"Sonne\"";
@@ -65,31 +66,102 @@
}
@Test
- public void testTermQueryWithRegexFlag() throws JsonProcessingException {
+ public void testRegex() throws JsonProcessingException {
+ String query = "[text=\"M(a|ä)nn(er)?\"]";
+ String jsonLd = "{@type:koral:token,wrap:{@type:koral:term,"
+ + "key:M(a|ä)nn(er)?,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
+ runAndValidate(query, jsonLd);
+
+ query = "\".*?Mann.*?\"";
+ jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:.*?Mann.*?,"
+ + "foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
+ runAndValidate(query, jsonLd);
+
+ query = "\"z.B.\"";
+ jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:z.B.,"
+ + "foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
+ runAndValidate(query, jsonLd);
+
+ query = "\"Sonne&scheint\"";
+ jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:Sonne&scheint,"
+ + "foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
+ runAndValidate(query, jsonLd);
+
+ // Not possible
+ // query = "\"a\\.\"";
+ }
+
+ // flagged-regexp ::= regexp
+ // | regexp "/" regexp-flag+
+ @Test
+ public void testTermQueryWithRegexFlag() throws IOException {
String query = "\"Fliegen\" /c";
String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, caseInsensitive:true, "
+ "key:Fliegen, foundry:opennlp, layer:orth, type:type:regex, match:match:eq}}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "\"Fliegen\" /i";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+
+ query = "\"Fliegen\" /C";
+ jsonLd = "{@type:koral:term, key:Fliegen, foundry:opennlp, layer:orth, type:type:regex, match:match:eq}";
+ FCSQLQueryProcessorTest.validateNode(query, "/query/wrap", jsonLd);
+
+ query = "\"Fliegen\" /I";
+ FCSQLQueryProcessorTest.validateNode(query, "/query/wrap", jsonLd);
+
+ query = "\"Fliegen\" /l";
+ List<Object> error = FCSQLQueryProcessorTest
+ .getError(new FCSQLQueryProcessor(query, "2.0"));
+ assertEquals(306, error.get(0));
+ String msg = (String) error.get(1);
+ assertEquals(true, msg.startsWith("SRU diagnostic 48: Regexflags"));
+
+ query = "\"Fliegen\" /d";
+ error = FCSQLQueryProcessorTest.getError(new FCSQLQueryProcessor(query,
+ "2.0"));
+ assertEquals(306, error.get(0));
+ assertEquals(
+ "SRU diagnostic 48: Regexflag: IGNORE_DIACRITICS is unsupported.",
+ (String) error.get(1));
+ }
+
+ // operator ::= "=" /* equals */
+ // | "!=" /* non-equals */
+ @Test
+ public void testOperator() throws IOException {
+ String query = "[cnx:pos != \"N\"]";
+ String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:N, "
+ + "foundry:cnx, layer:p, type:type:regex, match:match:ne}}";
runAndValidate(query, jsonLd);
}
+
+ // attribute operator flagged-regexp
+ // -------------------------------------------------------------------------
+ // attribute ::= simple-attribute | qualified-attribute
+ // -------------------------------------------------------------------------
+
+ // simple-attribute ::= identifier
@Test
public void testTermQueryWithSpecificLayer() throws JsonProcessingException {
String query = "[text = \"Sonne\"]";
String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:Sonne, "
+ "foundry:opennlp, layer:orth, type:type:regex, match:match:eq}}";
- runAndValidate(query, jsonLd);
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
query = "[lemma = \"sein\"]";
jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:sein, "
+ "foundry:tt, layer:l, type:type:regex, match:match:eq}}";
- runAndValidate(query, jsonLd);
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
query = "[pos = \"NN\"]";
jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:NN, "
+ "foundry:tt, layer:p, type:type:regex, match:match:eq}}";
- runAndValidate(query, jsonLd);
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
}
+ // qualified-attribute ::= identifier ":" identifier
@Test
public void testTermQueryWithQualifier() throws JsonProcessingException {
String query = "[mate:lemma = \"sein\"]";
@@ -126,47 +198,76 @@
}
+ // segment-query ::= "[" expression? "]"
+ // -------------------------------------------------------------------------
+ // expression ::= basic-expression
+ // | expression "|" expression /* or */
+ // | expression "&" expression /* and */
+ // -------------------------------------------------------------------------
+
+ // | expression "|" expression /* or */
@Test
- public void testRegex() throws JsonProcessingException {
- String query = "[text=\"M(a|ä)nn(er)?\"]";
- String jsonLd = "{@type:koral:token,wrap:{@type:koral:term,"
- + "key:M(a|ä)nn(er)?,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
- runAndValidate(query, jsonLd);
+ public void testExpressionOr() throws IOException {
+ String query = "[mate:lemma=\"sein\" | mate:pos=\"PPOSS\"]";
+ String jsonLd = "{@type: koral:token,"
+ + " wrap: { @type: koral:termGroup,"
+ + "relation: relation:or,"
+ + " operands:["
+ + "{@type: koral:term, key: sein, foundry: mate, layer: l, type:type:regex, match: match:eq},"
+ + "{@type: koral:term, key: PPOSS, foundry: mate, layer: p, type:type:regex, match: match:eq}]}}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
- query = "\".*?Mann.*?\"";
- jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:.*?Mann.*?,"
- + "foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
- runAndValidate(query, jsonLd);
+ query = "[cnx:lemma=\"sein\" | mate:lemma=\"sein\" | mate:pos=\"PPOSS\"]";
+ jsonLd = "{@type: koral:term, key: sein, foundry: cnx, layer: l, type:type:regex, match: match:eq}";
+ FCSQLQueryProcessorTest.validateNode(query, "/query/wrap/operands/0",
+ jsonLd);
- query = "\"z.B.\"";
- jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:z.B.,"
- + "foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
- runAndValidate(query, jsonLd);
-
- query = "\"Sonne&scheint\"";
- jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:Sonne&scheint,"
- + "foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}";
- runAndValidate(query, jsonLd);
-
- // Not possible
- // query = "\"a\\.\"";
}
+ // | expression "&" expression /* and */
@Test
- public void testNot() throws IOException {
- String query = "[cnx:pos != \"N\"]";
- String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:N, "
- + "foundry:cnx, layer:p, type:type:regex, match:match:ne}}";
- runAndValidate(query, jsonLd);
+ public void testExpressionAnd() throws IOException {
+ String query = "[mate:lemma=\"sein\" & mate:pos=\"PPOSS\"]";
+ String jsonLd = "{@type: koral:token,"
+ + " wrap: { @type: koral:termGroup,"
+ + "relation: relation:and,"
+ + " operands:["
+ + "{@type: koral:term, key: sein, foundry: mate, layer: l, type:type:regex, match: match:eq},"
+ + "{@type: koral:term, key: PPOSS, foundry: mate, layer: p, type:type:regex, match: match:eq}]}}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+ }
- jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:NN, "
+ // -------------------------------------------------------------------------
+ // basic-expression ::= '(' expression ')' /* grouping */
+ // | "!" expression /* not */
+ // | attribute operator flagged-regexp
+ // -------------------------------------------------------------------------
+
+ // basic-expression ::= '(' expression ')' /* grouping */
+
+ @Test
+ public void testExpressionGroup() throws JsonProcessingException {
+ String query = "[(text=\"blau\"|pos=\"ADJ\")]";
+ String jsonLd = "{@type: koral:token,"
+ + "wrap: {@type: koral:termGroup,"
+ + "relation: relation:or,"
+ + "operands: ["
+ + "{@type: koral:term, key: blau, foundry: opennlp, layer: orth, type:type:regex,match: match:eq},"
+ + "{@type: koral:term, key: ADJ, foundry: tt, layer: p, type:type:regex, match: match:eq}]}}";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
+ }
+
+ // "!" expression /* not */
+ @Test
+ public void testExpressionNot() throws IOException {
+ String jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:NN, "
+ "foundry:tt, layer:p, type:type:regex, match:match:eq}}";
- query = "[!pos != \"NN\"]";
- runAndValidate(query, jsonLd);
+ String query = "[!pos != \"NN\"]";
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
query = "[!!pos = \"NN\"]";
- runAndValidate(query, jsonLd);
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
query = "[!!!pos != \"NN\"]";
- runAndValidate(query, jsonLd);
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
query = "[mate:lemma=\"sein\" & !mate:pos=\"PPOSS\"]";
jsonLd = "{@type: koral:token,"
@@ -176,9 +277,10 @@
+ " operands:["
+ "{@type: koral:term, key: sein, foundry: mate, layer: l, type:type:regex, match: match:eq},"
+ "{@type: koral:term, key: PPOSS, foundry: mate, layer: p, type:type:regex, match: match:ne}]}}";
- runAndValidate(query, jsonLd);
+ FCSQLQueryProcessorTest.runAndValidate(query, jsonLd);
}
+
@Test
public void testWrongQuery() throws IOException {
String query = "!(mate:lemma=\"sein\" | mate:pos=\"PPOSS\")";
@@ -198,109 +300,4 @@
error.get(1).toString().startsWith("FCS diagnostic 10"));
}
- @Test
- public void testSequenceQuery() throws IOException {
- String query = "\"blaue|grüne\" [pos = \"NN\"]";
- String jsonLd = "{@type:koral:group, "
- + "operation:operation:sequence, "
- + "operands:["
- + "{@type:koral:token, wrap:{@type:koral:term, key:blaue|grüne, foundry:opennlp, layer:orth, type:type:regex, match:match:eq}},"
- + "{@type:koral:token, wrap:{@type:koral:term, key:NN, foundry:tt, layer:p, type:type:regex, match:match:eq}}"
- + "]}";
- runAndValidate(query, jsonLd);
-
- query = "[text=\"blaue|grüne\"][pos = \"NN\"]";
- runAndValidate(query, jsonLd);
-
- query = "\"blaue\" \"grüne\" [pos = \"NN\"]";
- jsonLd = "{@type:koral:token, wrap:{@type:koral:term, key:grüne, foundry:opennlp, layer:orth, type:type:regex, match:match:eq}}";
- validateNode(query, "/query/operands/1", jsonLd);
-
- }
-
- @Test
- public void testBooleanQuery() throws IOException {
- String query = "[mate:lemma=\"sein\" & mate:pos=\"PPOSS\"]";
- String jsonLd = "{@type: koral:token,"
- + " wrap: { @type: koral:termGroup,"
- + "relation: relation:and,"
- + " operands:["
- + "{@type: koral:term, key: sein, foundry: mate, layer: l, type:type:regex, match: match:eq},"
- + "{@type: koral:term, key: PPOSS, foundry: mate, layer: p, type:type:regex, match: match:eq}]}}";
- runAndValidate(query, jsonLd);
-
- query = "[mate:lemma=\"sein\" | mate:pos=\"PPOSS\"]";
- validateNode(query, "/query/wrap/relation", "relation:or");
-
- query = "[cnx:lemma=\"sein\" | mate:lemma=\"sein\" | mate:pos=\"PPOSS\"]";
- jsonLd = "{@type: koral:term, key: sein, foundry: cnx, layer: l, type:type:regex, match: match:eq}";
- validateNode(query, "/query/wrap/operands/0", jsonLd);
-
- // group with two tokens
- query = "[pos=\"NN\"]|[text=\"Mann\"]";
- jsonLd = "{@type:koral:group,"
- + "operation:operation:disjunction,"
- + "operands:["
- + "{@type:koral:token, wrap:{@type:koral:term,key:NN,foundry:tt,layer:p,type:type:regex,match:match:eq}},"
- + "{@type:koral:token, wrap:{@type:koral:term,key:Mann,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}]}";
- runAndValidate(query, jsonLd);
-
- query = "[pos=\"NN\"]&[text=\"Mann\"]";
- List<Object> error = getError(new FCSQLQueryProcessor(query, "2.0"));
- assertEquals(399, error.get(0));
- String msg = (String) error.get(1);
- assertEquals(true, msg.startsWith("FCS diagnostic 10"));
- }
-
- @Test
- public void testGroupQuery() throws IOException {
- String query = "(\"blaue\"|\"grüne\")";
- String jsonLd = "{@type:koral:group,"
- + "operation:operation:disjunction,"
- + "operands:["
- + "{@type:koral:token, wrap:{@type:koral:term,key:blaue,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}},"
- + "{@type:koral:token, wrap:{@type:koral:term,key:grüne,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}]}";;
- runAndValidate(query, jsonLd);
-
- // group and disjunction
- query = "([pos=\"NN\"]|[cnx:pos=\"N\"]|[text=\"Mann\"])";
- jsonLd = "{@type:koral:token,wrap:{@type:koral:term,key:N,foundry:cnx,layer:p,type:type:regex,match:match:eq}}";
- validateNode(query, "/query/operands/1", jsonLd);
-
- // sequence and disjunction
- query = "([pos=\"NN\"]|[cnx:pos=\"N\"])[text=\"Mann\"]";
- jsonLd = "{@type:koral:group,"
- + "operation:operation:sequence,"
- + "operands:["
- + "{@type:koral:group,"
- + "operation:operation:disjunction,"
- + "operands:[{@type:koral:token,wrap:{@type:koral:term,key:NN,foundry:tt,layer:p,type:type:regex,match:match:eq}},"
- + "{@type:koral:token,wrap:{@type:koral:term,key:N,foundry:cnx,layer:p,type:type:regex,match:match:eq}}"
- + "]},"
- + "{@type:koral:token,wrap:{@type:koral:term,key:Mann,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}}"
- + "]}";
- runAndValidate(query, jsonLd);
-
- // group and sequence
- query = "([text=\"blaue\"][pos=\"NN\"])";
- jsonLd = "{@type:koral:group,"
- + "operation:operation:sequence,"
- + "operands:["
- + "{@type:koral:token,wrap:{@type:koral:term,key:blaue,foundry:opennlp,layer:orth,type:type:regex,match:match:eq}},"
- + "{@type:koral:token,wrap:{@type:koral:term,key:NN,foundry:tt,layer:p,type:type:regex,match:match:eq}}"
- + "]}";
- runAndValidate(query, jsonLd);
- }
-
- @Test
- public void testWithinQuery() throws JsonProcessingException {
- String query = "[cnx:pos=\"VVFIN\"] within s";
- String jsonLd = "{@type:koral:group,"
- + "operation:operation:position,"
- + "operands:["
- + "{@type:koral:span,wrap:{@type:koral:term,key:s,foundry:base,layer:s}},"
- + "{@type:koral:token,wrap:{@type:koral:term,key:VVFIN,foundry:cnx,layer:p,type:type:regex,match:match:eq}}"
- + "]}";
- runAndValidate(query, jsonLd);
- }
}