%}
%pure_parser
-%token SIMPLE_STRING AND OR NOT PROX GE LE NE EXACT SORTBY
+%token PREFIX_NAME SIMPLE_STRING AND OR NOT PROX GE LE NE EXACT SORTBY
%%
$$.cql = $3.cql;
}
|
-searchTerm {
+searchTerm extraTerms {
struct cql_node *st = cql_node_dup(((CQL_parser) parm)->nmem, $0.rel);
+ st->u.st.extra_terms = $2.cql;
st->u.st.term = nmem_strdup(((CQL_parser)parm)->nmem, $1.buf);
$$.cql = st;
}
-
|
index relation modifiers {
$$.rel = cql_node_mk_sc(((CQL_parser) parm)->nmem, $1.buf, $2.buf, 0);
}
;
+extraTerms:
+SIMPLE_STRING extraTerms {
+ struct cql_node *st = cql_node_mk_sc(((CQL_parser) parm)->nmem,
+ /* index */ 0, /* rel */ 0, $1.buf);
+ st->u.st.extra_terms = $2.cql;
+ $$.cql = st;
+}
+|
+{ $$.cql = 0; }
+;
+
+
/* unary NOT search SIMPLE_STRING here .. */
boolean:
}
;
-relation: SIMPLE_STRING | relation_symbol;
+relation: PREFIX_NAME | relation_symbol;
relation_symbol:
'='
searchTerm:
SIMPLE_STRING
+| PREFIX_NAME
| AND
| OR
| NOT
}
else
{
+ int relation_like = 0;
while (c != 0 && !strchr(" \n()=<>/", c))
{
+ if (c == '.')
+ relation_like = 1;
if (c == '\\')
{
putb(lval, cp, c);
lval->buf = "sortby";
return SORTBY;
}
+ if (!cql_strcmp(lval->buf, "all"))
+ relation_like = 1;
+ if (!cql_strcmp(lval->buf, "any"))
+ relation_like = 1;
+ if (!cql_strcmp(lval->buf, "adj"))
+ relation_like = 1;
+ if (!cql_strcmp(lval->buf, "within"))
+ relation_like = 1;
+ if (!cql_strcmp(lval->buf, "encloses"))
+ relation_like = 1;
+ if (relation_like)
+ return PREFIX_NAME;
}
return SIMPLE_STRING;
}
const char *split_op = 0;
const char *ccl_rel = 0;
const char *rel = cn->u.st.relation;
- const char *cp;
if (cn->u.st.index && strcmp(cn->u.st.index,
"cql.serverChoice"))
/* unsupported relation */
return -1;
}
- cp = cn->u.st.term;
- while (1)
+ for (; cn; cn = cn->u.st.extra_terms)
{
- if (ccl_field && ccl_rel)
+ const char *cp = cn->u.st.term;
+ while (1)
{
- pr(ccl_field, client_data);
- pr(ccl_rel, client_data);
- if (!split_op)
- ccl_rel = 0;
+ if (ccl_field && ccl_rel)
+ {
+ pr(ccl_field, client_data);
+ pr(ccl_rel, client_data);
+ if (!split_op)
+ ccl_rel = 0;
+ }
+ pr_term(&cp, split_op ? 1 : 0, pr, client_data);
+ while (*cp == ' ')
+ cp++;
+ if (*cp == '\0')
+ break;
+ pr(" ", client_data);
+ if (split_op)
+ {
+ pr(split_op, client_data);
+ pr(" ", client_data);
+ }
}
- pr_term(&cp, split_op ? 1 : 0, pr, client_data);
- while (*cp == ' ')
- cp++;
- if (*cp == '\0')
- break;
- pr(" ", client_data);
- if (split_op)
+ if (cn->u.st.extra_terms)
{
- pr(split_op, client_data);
pr(" ", client_data);
+ if (split_op)
+ {
+ pr(split_op, client_data);
+ pr(" ", client_data);
+ }
}
}
return 0;
static void emit_terms(cql_transform_t ct,
struct cql_node *cn,
void (*pr)(const char *buf, void *client_data),
- void *client_data)
+ void *client_data,
+ const char *op)
{
+ struct cql_node *ne = cn->u.st.extra_terms;
+ if (ne)
+ {
+ (*pr)("@", client_data);
+ (*pr)(op, client_data);
+ (*pr)(" ", client_data);
+ }
emit_term(ct, cn, cn->u.st.term, strlen(cn->u.st.term),
pr, client_data);
+ for (; ne; ne = ne->u.st.extra_terms)
+ {
+ if (ne->u.st.extra_terms)
+ {
+ (*pr)("@", client_data);
+ (*pr)(op, client_data);
+ (*pr)(" ", client_data);
+ }
+ emit_term(ct, cn, ne->u.st.term, strlen(ne->u.st.term),
+ pr, client_data);
+ }
}
static void emit_wordlist(cql_transform_t ct,
else if (cn->u.st.relation && !cql_strcmp(cn->u.st.relation, "any"))
emit_wordlist(ct, cn, pr, client_data, "or");
else
- emit_terms(ct, cn, pr, client_data);
+ emit_terms(ct, cn, pr, client_data, "and");
break;
case CQL_NODE_BOOL:
(*pr)("@", client_data);
pr_cdata(cn->u.st.term, pr, client_data);
pr_n("</term>\n", pr, client_data, 0);
}
+ if (cn->u.st.extra_terms)
+ {
+ struct cql_node *n = cn->u.st.extra_terms;
+ for (; n; n = n->u.st.extra_terms)
+ {
+ pr_n("<term>", pr, client_data, level+2);
+ pr_cdata(n->u.st.term, pr, client_data);
+ pr_n("</term>\n", pr, client_data, 0);
+ }
+ }
cql_sort_to_xml(sort_node, pr, client_data, level+2);
pr_n("</searchClause>\n", pr, client_data, level);
break;
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>a</term>
+ <term>b</term>
+</searchClause>
<searchClause>
- <index>a</index>
+ <index>cql.serverChoice</index>
<relation>
- <value>b</value>
+ <value>=</value>
</relation>
+ <term>a</term>
+ <term>b</term>
<term>c</term>
</searchClause>
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>a.b</term>
+ <term>c</term>
+</searchClause>
<searchClause>
- <index>and</index>
+ <index>cql.serverChoice</index>
<relation>
- <value>b</value>
+ <value>=</value>
</relation>
+ <term>and</term>
+ <term>b</term>
<term>c</term>
</searchClause>
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>all</term>
+ <term>a</term>
+</searchClause>
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>dc.title</term>
+ <term>a</term>
+ <term>b</term>
+ <term>c</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>d</term>
+ </searchClause>
+ </rightOperand>
+</triple>
Parsing CQL a b
+@attr 6=1 @attr 2=3 @attr 4=1 @and @attr 3=3 @attr 6=1 @attr 5=100 @attr 1=1016 "a" @attr 3=3 @attr 6=1 @attr 5=100 @attr 1=1016 "b"
YAZ_CHECK(tst_query("\\*", "\"*\""));
YAZ_CHECK(tst_query("\"\\*\"", "\"*\""));
- YAZ_CHECK(tst_query("\"a b\"", "\"a b\""));
+ YAZ_CHECK(tst_query("a b", "\"a\" \"b\""));
+ YAZ_CHECK(tst_query("ab bc", "\"ab\" \"bc\""));
YAZ_CHECK(tst_query("\\\\", "\"\\\\\""));
YAZ_CHECK(tst_query("\\\"", "\"\\\"\""));
YAZ_CHECK(tst_query("title all \"\"", "title=\"\""));
YAZ_CHECK(tst_query("title all x", "title=\"x\""));
+ YAZ_CHECK(tst_query("title all x y", "title=\"x\" and title=\"y\""));
YAZ_CHECK(tst_query("title all \"x y\"", "title=\"x\" and title=\"y\""));
YAZ_CHECK(tst_query("title any x", "title=\"x\""));
+ YAZ_CHECK(tst_query("title any x y", "title=\"x\" or title=\"y\""));
YAZ_CHECK(tst_query("title any \"x y\"", "title=\"x\" or title=\"y\""));
YAZ_CHECK(tst_query("title = \"x y\"", "title=\"x y\""));
+ YAZ_CHECK(tst_query("title = x y", "title=\"x\" \"y\""));
+
+ YAZ_CHECK(tst_query("title = x y z", "title=\"x\" \"y\" \"z\""));
YAZ_CHECK(tst_query("dc.title=encyclopedia prox dinosaurs",
"(dc.title=\"encyclopedia\") % (\"dinosaurs\")"));