src/lib/rqlParse.c 1.5
1.5 2009/12/03 19:26:04 kent
Making rqlParser handle arrays and field-separating-dots. Evaluation handles arrays but not dots yet.
Index: src/lib/rqlParse.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/lib/rqlParse.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -b -B -U 4 -r1.4 -r1.5
--- src/lib/rqlParse.c 3 Dec 2009 18:19:28 -0000 1.4
+++ src/lib/rqlParse.c 3 Dec 2009 19:26:04 -0000 1.5
@@ -18,16 +18,8 @@
case rqlOpLiteral:
return "rqlOpLiteral";
case rqlOpSymbol:
return "rqlOpSymbol";
- case rqlOpEq:
- return "rqlOpEq";
- case rqlOpNe:
- return "rqlOpNe";
- case rqlOpAnd:
- return "rqlOpAnd";
- case rqlOpOr:
- return "rqlOpOr";
case rqlOpStringToBoolean:
return "rqlOpStringToBoolean";
case rqlOpIntToBoolean:
@@ -35,22 +27,23 @@
case rqlOpDoubleToBoolean:
return "rqlOpDoubleToBoolean";
case rqlOpStringToInt:
return "rqlOpStringToInt";
- case rqlOpStringToDouble:
- return "rqlOpStringToDouble";
+ case rqlOpDoubleToInt:
+ return "rqlOpDoubleToInt";
case rqlOpBooleanToInt:
return "rqlOpBooleanToInt";
+ case rqlOpStringToDouble:
+ return "rqlOpStringToDouble";
case rqlOpBooleanToDouble:
return "rqlOpBooleanToDouble";
case rqlOpIntToDouble:
return "rqlOpIntToDouble";
- case rqlOpUnaryMinusInt:
- return "rqlOpUnaryMinusInt";
- case rqlOpUnaryMinusDouble:
- return "rqlOpUnaryMinusDouble";
-
+ case rqlOpEq:
+ return "rqlOpEq";
+ case rqlOpNe:
+ return "rqlOpNe";
case rqlOpGt:
return "rqlOpGt";
case rqlOpLt:
return "rqlOpLt";
@@ -60,11 +53,25 @@
return "rqlOpLe";
case rqlOpLike:
return "rqlOpLike";
+ case rqlOpAnd:
+ return "rqlOpAnd";
+ case rqlOpOr:
+ return "rqlOpOr";
case rqlOpNot:
return "rqlOpNot";
+ case rqlOpUnaryMinusInt:
+ return "rqlOpUnaryMinusInt";
+ case rqlOpUnaryMinusDouble:
+ return "rqlOpUnaryMinusDouble";
+
+ case rqlOpArrayIx:
+ return "rqlOpArrayIx";
+ case rqlOpSubDot:
+ return "rqlSubDot";
+
default:
return "rqlOpUnknown";
}
}
@@ -216,8 +223,10 @@
case rqlTypeString:
return rqlOpStringToInt;
case rqlTypeBoolean:
return rqlOpBooleanToInt;
+ case rqlTypeDouble:
+ return rqlOpDoubleToInt;
default:
internalErr();
return rqlOpUnknown;
}
@@ -270,15 +279,51 @@
return cast;
}
}
+static struct rqlParse *rqlParsePartSelect(struct tokenizer *tkz)
+/* Handle the . in this.that or the [] in this[6] */
+{
+struct rqlParse *collection = rqlParseAtom(tkz);
+struct rqlParse *p = collection;
+char *tok = tokenizerNext(tkz);
+if (tok == NULL)
+ tokenizerReuse(tkz);
+else if (tok[0] == '[')
+ {
+ // struct rqlParse *index = rqlParseExpression(tkz);
+ struct rqlParse *index = rqlParseAtom(tkz);
+ index = rqlParseCoerce(index, rqlTypeInt);
+ skipOverRequired(tkz, "]");
+ AllocVar(p);
+ p->op = rqlOpArrayIx;
+ p->type = rqlTypeString;
+ p->children = collection;
+ collection->next = index;
+ }
+else if (tok[0] == '.')
+ {
+ struct rqlParse *field = rqlParseExpression(tkz);
+ field = rqlParseCoerce(field, rqlTypeString);
+ AllocVar(p);
+ p->op = rqlOpSubDot;
+ p->type = rqlTypeString;
+ p->children = collection;
+ collection->next = field;
+ }
+else
+ tokenizerReuse(tkz);
+return p;
+}
+
+
static struct rqlParse *rqlParseUnaryMinus(struct tokenizer *tkz)
/* Return unary minus sort of parse tree if there's a leading '-' */
{
char *tok = tokenizerMustHaveNext(tkz);
if (tok[0] == '-')
{
- struct rqlParse *c = rqlParseAtom(tkz);
+ struct rqlParse *c = rqlParsePartSelect(tkz);
struct rqlParse *p;
AllocVar(p);
if (c->type == rqlTypeInt)
{
@@ -296,9 +341,9 @@
}
else
{
tokenizerReuse(tkz);
- return rqlParseAtom(tkz);
+ return rqlParsePartSelect(tkz);
}
}
static boolean eatMatchingTok(struct tokenizer *tkz, char *s)
@@ -427,11 +472,10 @@
static struct rqlParse *rqlParseAnd(struct tokenizer *tkz)
/* Parse out and or or. */
{
-struct rqlParse *l = rqlParseCoerce(rqlParseNot(tkz), rqlTypeBoolean);
+struct rqlParse *p = rqlParseNot(tkz);
struct rqlParse *parent = NULL;
-struct rqlParse *p = l;
for (;;)
{
char *tok = tokenizerNext(tkz);
if (tok == NULL || !sameString(tok, "and"))
@@ -442,8 +486,9 @@
else
{
if (parent == NULL)
{
+ p = rqlParseCoerce(p, rqlTypeBoolean);
AllocVar(parent);
parent->op = rqlOpAnd;
parent->type = rqlTypeBoolean;
parent->children = p;
@@ -457,11 +502,10 @@
static struct rqlParse *rqlParseOr(struct tokenizer *tkz)
/* Parse out and or or. */
{
-struct rqlParse *l = rqlParseCoerce(rqlParseAnd(tkz), rqlTypeBoolean);
+struct rqlParse *p = rqlParseAnd(tkz);
struct rqlParse *parent = NULL;
-struct rqlParse *p = l;
for (;;)
{
char *tok = tokenizerNext(tkz);
if (tok == NULL || !sameString(tok, "or"))
@@ -472,8 +516,9 @@
else
{
if (parent == NULL)
{
+ p = rqlParseCoerce(p, rqlTypeBoolean);
AllocVar(parent);
parent->op = rqlOpOr;
parent->type = rqlTypeBoolean;
parent->children = p;