Skip to content

Commit 5d05ecf

Browse files
committed
Add ranges and demo output
1 parent b22a83f commit 5d05ecf

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

cql.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ var CQLModifier = function () {
2727
this.name = null;
2828
this.relation = null;
2929
this.value = null;
30+
this._pos = null;
31+
this._range = null;
3032
}
3133

3234
CQLModifier.prototype = {
@@ -52,6 +54,8 @@ CQLModifier.prototype = {
5254
//we assume 'true'
5355
var value = this.value.length > 0 ? this.value : "true";
5456
var s = '"' + this.name + '": "' + value + '"';
57+
if (this._pos !== null) s += ', "' + this.name + '@pos": ' + this._pos;
58+
if (this._range !== null) s += ', "' + this.name + '@range": ' + JSON.stringify(this._range);
5559
return s;
5660
}
5761
}
@@ -67,6 +71,8 @@ var CQLSearchClause = function (field, fielduri, relation, relationuri,
6771
this.term = term;
6872
this.scf = scf || DEFAULT_SERVER_CHOICE_FIELD;
6973
this.scr = scr || DEFAULT_SERVER_CHOICE_RELATION;
74+
this._pos = null;
75+
this._range = null;
7076
}
7177

7278
CQLSearchClause.prototype = {
@@ -128,6 +134,8 @@ CQLSearchClause.prototype = {
128134
continue;
129135
s += ', ' + this.modifiers[i].toFQ();
130136
}
137+
if (this._pos !== null) s += ', "@pos": ' + this._pos;
138+
if (this._range !== null) s += ', "@range": ' + JSON.stringify(this._range);
131139
s += '}';
132140
return s;
133141
},
@@ -163,6 +171,7 @@ var CQLBoolean = function () {
163171
this.modifiers = null;
164172
this.left = null;
165173
this.right = null;
174+
this._pos = null;
166175
}
167176

168177
CQLBoolean.prototype = {
@@ -199,6 +208,7 @@ CQLBoolean.prototype = {
199208
s += ', ' + this.modifiers[i].toFQ();
200209
s += ',' + nl + indent(n, c) + ' "s1": ' + this.left.toFQ(n + 1, c, nl);
201210
s += ',' + nl + indent(n, c) + ' "s2": ' + this.right.toFQ(n + 1, c, nl);
211+
if (this._pos !== null) s += ',' + nl + indent(n, c) + ' "@pos": ' + this._pos;
202212
var fill = n && c ? ' ' : '';
203213
s += nl + indent(n - 1, c) + fill + '}';
204214
return s;
@@ -213,6 +223,7 @@ var CQLParser = function () {
213223
this.look = null;
214224
this.lval = null;
215225
this.val = null;
226+
this._exprStart = null;
216227
this.prefixes = new Object();
217228
this.tree = null;
218229
this.scf = null;
@@ -230,6 +241,7 @@ CQLParser.prototype = {
230241
this.qs = query;
231242
this.ql = this.qs.length;
232243
this.qi = 0;
244+
this.lval = this.val = this._exprStart = null;
233245
this._move();
234246
this.tree = this._parseQuery(this.scf, this.scr, new Array());
235247
if (this.look != "")
@@ -285,6 +297,8 @@ CQLParser.prototype = {
285297
for (var key in fq) {
286298
if (key == 'term' || key == 'field' || key == 'relation')
287299
continue;
300+
if (key.endsWith("@pos") || key.endsWith("@range"))
301+
continue;
288302
var mod = new CQLModifier();
289303
mod.name = key;
290304
mod.relation = '=';
@@ -315,6 +329,7 @@ CQLParser.prototype = {
315329
this.lval == "not" ||
316330
this.lval == "prox")) {
317331
var b = new CQLBoolean();
332+
b._pos = this.qi - this.lval.length + 1;
318333
b.op = this.lval;
319334
this._move();
320335
b.modifiers = this._parseModifiers();
@@ -327,27 +342,35 @@ CQLParser.prototype = {
327342
_parseModifiers: function () {
328343
var ar = new Array();
329344
while (this.look == "/") {
345+
let _mstart = this.qi;
330346
this._move();
331347
if (this.look != "s" && this.look != "q")
332348
throw new CQLError("Invalid modifier.", this.qs, this.qi, this.look, this.val, this.lval)
333349

334350
var name = this.lval;
351+
let _mpos = this.qi - this.lval.length + 1;
352+
let _mend = this.qi;
335353
this._move();
336354
if (this.look.length > 0
337355
&& this._strchr("<>=", this.look.charAt(0))) {
338356
var rel = this.look;
339357
this._move();
358+
_mend = this.qi;
340359
if (this.look != "s" && this.look != "q")
341360
throw new CQLError("Invalid relation within the modifier.", this.qs, this.qi, this.look, this.val, this.lval);
342361

343362
var m = new CQLModifier();
363+
m._pos = _mpos;
364+
m._range = [_mstart, _mend];
344365
m.name = name;
345366
m.relation = rel;
346367
m.value = this.val;
347368
ar.push(m);
348369
this._move();
349370
} else {
350371
var m = new CQLModifier();
372+
m._pos = _mpos;
373+
m._range = [_mstart, _mend];
351374
m.name = name;
352375
m.relation = "";
353376
m.value = "";
@@ -358,6 +381,7 @@ CQLParser.prototype = {
358381
},
359382
_parseSearchClause: function (field, relation, modifiers) {
360383
if (this.look == "(") {
384+
let _qi = this.qi;
361385
this._move();
362386
var b = this._parseQuery(field, relation, modifiers);
363387
if (this.look == ")")
@@ -368,6 +392,9 @@ CQLParser.prototype = {
368392
return b;
369393
} else if (this.look == "s" || this.look == "q") {
370394
var first = this.val; // dont know if field or term yet
395+
if (this._exprStart === null)
396+
this._exprStart = this.qi - this.val.length + 1;
397+
let _tend = this.qi;
371398
this._move();
372399
if (this.look == "q" ||
373400
(this.look == "s" &&
@@ -414,6 +441,8 @@ CQLParser.prototype = {
414441
first,
415442
this.scf,
416443
this.scr);
444+
sc._range = [this._exprStart, _tend];
445+
this._exprStart = null;
417446
return sc;
418447
}
419448
// prefixes
@@ -469,6 +498,8 @@ CQLParser.prototype = {
469498
}
470499
//quoted string
471500
} else if (this._strchr("\"'", c)) {
501+
if (this._exprStart === null)
502+
this._exprStart = this.qi + 1;
472503
this.look = "q";
473504
//remember quote char
474505
var mark = c;

index.html

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@
44
<script type="text/javascript">
55
var cp = new CQLParser();
66

7+
function buildVis(query) {
8+
var cp = new CQLParser();
9+
cp.parse(query);
10+
var fq = JSON.parse(cp.toFQ());
11+
12+
function recMods (obj, s) {
13+
if ("term" in obj) {
14+
Object.entries(obj).filter(x => x[0].endsWith("@range") && x[0].length > 6).map(([_, range]) => {
15+
s += '\n' + "".padStart(range[0] - 1) + "m".padEnd(range[1] - range[0] + 1, "-")
16+
})
17+
if ("@range" in obj)
18+
s += '\n' + "".padStart(obj["@range"][0] - 1) + "t".padEnd(obj["@range"][1] - obj["@range"][0] + 1, "-")
19+
} else if ("op" in obj) {
20+
if ("@pos" in obj)
21+
s += '\n' + "r".padEnd(obj.op.length, "-").padStart(obj["@pos"] + obj.op.length - 1)
22+
23+
Object.entries(obj).filter(x => x[0].endsWith("@range")).map(([_, range]) => {
24+
s += '\n' + "".padStart(range[0] - 1) + "m".padEnd(range[1] - range[0] + 1, "-")
25+
})
26+
27+
s = recMods(obj.s1, s);
28+
s = recMods(obj.s2, s);
29+
}
30+
return s;
31+
}
32+
33+
var vis = query;
34+
vis = recMods(fq, vis);
35+
return vis;
36+
}
37+
738
function parseInput(query) {
839
try {
940
cp.parse(query);
@@ -14,6 +45,8 @@
1445
document.getElementById("output3").value = fq;
1546
cp.parseFromFQ(fq);
1647
document.getElementById("output4").value = cp.toString();
48+
// visualize positions/ranges in original query
49+
document.getElementById("output5").value = buildVis(query);
1750
} catch (e) {
1851
var msg = e.toString();
1952
msg += "\n\n\tquery: " + e.query + "\n\t " + "^".padStart(e.pos) + " (pos: " + e.pos + ")";
@@ -22,6 +55,7 @@
2255
document.getElementById("output2").value = "";
2356
document.getElementById("output3").value = "";
2457
document.getElementById("output4").value = "";
58+
document.getElementById("output5").value = "";
2559
throw e;
2660
}
2761
}
@@ -42,6 +76,7 @@
4276
<textarea id="output2" rows="80" cols="80"></textarea>
4377
<textarea id="output3" rows="80" cols="80"></textarea>
4478
<textarea id="output4" rows="80" cols="80"></textarea>
79+
<textarea id="output5" rows="80" cols="80"></textarea>
4580
</div>
4681
</body>
4782
</html>

0 commit comments

Comments
 (0)