aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/nodejs/parse.js159
-rw-r--r--src/nodejs/tests/pathparsing.js8
2 files changed, 119 insertions, 48 deletions
diff --git a/src/nodejs/parse.js b/src/nodejs/parse.js
index 932f91f..321823b 100644
--- a/src/nodejs/parse.js
+++ b/src/nodejs/parse.js
@@ -1,60 +1,131 @@
-exports.urlToXpathObj = function urlToXpathObj(url){
- // FIXMEresult.shift(): more validaiton
- // filter stars in keys
- // filter no enough arguments
- var parseKeyList = function(string){
-
- console.log("input f1: " + string);
- result = /([^\|]*)/g.exec(string);
- console.log(result);
- result.shift();
- return result;
- }
+var parser = function(){
- var parseBboxList = function(string){
+ var offset =0;
+ var expr ="";
- console.log("input: " + string);
- result = /(.+),(.+),(.+),(.+)/.exec(string);
+ var keys = [];
+ var values = [];
+ var bbox= {};
+ var object = "";
- console.log(result);
+ var check = function(char){
+ if (expr.charAt(offset) != char) {
+ throw "Unexpected char " + expr[offset] + " at " + offset + " expected: " + char;
+ }
+ offset ++;
+ }
+
+ var parsePredicate = function(){
+ check('[');
+ parseInnerPredicate();
+ check(']');
+ }
- if(result.length != 4){
- throw "error";
- }
+ var parseInnerPredicate = function(){
+ tmpKeys=[];
+ parseKeyValue(tmpKeys,'=');
+ check('=');
+ if(tmpKeys.length==1 && tmpKeys[0] == "bbox"){
+ parseBboxValues();
+ } else {
+ keys = tmpKeys;
+ parseKeyValue(values,']');
+ }
+ }
- result.shift();
+ var parseBboxValues = function(){
+ bbox.left = parseBboxFloat();
+ check(',');
+ bbox.bottom = parseBboxFloat();
+ check(',');
+ bbox.right = parseBboxFloat();
+ check(',');
+ bbox.top = parseBboxFloat();
+ }
- return {
- 'left' : result[0],
- 'bottom' : result[1],
- 'right' : result[2],
- 'top' : result[3]
- }
- }
-
- var xp = {};
+ var parseBboxFloat = function(){
+ var floatStr = "";
+ while(expr[offset]!=',' && expr[offset]!=']' && offset < expr.length){
+ floatStr += expr[offset];
+ offset ++;
+ }
+ return parseFloat(floatStr);
+ }
- result = url.match(/\/(\*|node|way|relation)\[(.*)=(.*)\]*/);
- console.log("OUTER: " + result);
+ var parseKeyValue = function(list,delim){
+ var word = "";
+ while(expr[offset]!=delim && offset < expr.length){
+ if(expr[offset]=='|'){
+ list.push(word);
+ word="";
+ offset ++;
+ continue;
+ }
+ // jump escaped chars
+ if(expr[offset]=='\\'){
+ word += expr[offset];
+ offset ++;
+ }
+ word += expr[offset];
+ offset ++;
+ }
+ list.push(word);
+
+ }
+ this.parse = function(exprLocal){
+ expr = exprLocal;
+ offset = 0;
+ object = "";
- xp.object=result[1];
- for(i=2;i<=result.length;i++){
- if(result[i]==="bbox" && result[i]){
- xp.bbox = parseBboxList(result[i+1]);
- } else {
- if(result[i]){
- xp.tag ={};
- xp.tag.keys = parseKeyList(result[i]);
- xp.tag.values = parseKeyList(result[i+1]);
+
+ check('/');
+
+ for(;expr[offset]!='[' && offset<expr.length;offset++){
+ if(expr[offset] == '/' && offset == expr.length-1){
+ offset ++;
+ break;
}
- }
- i++;
+ object += expr[offset];
+ }
+
+ if (object != "*" && object != "way" && object != "node" && object != "relation"){
+ throw "invalid identifier: " + object;
+ }
+
+
+ for(var i=0; i<3 && offset < expr.length;i++) {
+ parsePredicate();
+ }
+ if (offset < expr.length){
+
+ throw "string longer than excepected";
+ }
+
+ var result = {
+ object : object
+ };
+
+ if(bbox.left != undefined){
+ result.bbox = bbox;
+ }
+
+ if(keys.length > 0){
+
+ result.tag = {
+ key : keys,
+ value : values
+ }
+ }
+ return result;
}
- console.log(xp);
- return(xp);
}
+
+exports.urlToXpathObj = function urlToXpathObj(url){
+ var parse = new parser();
+ return parse.parse(url);
+}
diff --git a/src/nodejs/tests/pathparsing.js b/src/nodejs/tests/pathparsing.js
index e1a20f5..ebd5baf 100644
--- a/src/nodejs/tests/pathparsing.js
+++ b/src/nodejs/tests/pathparsing.js
@@ -54,7 +54,7 @@ module.exports =
test.ok(true);
var simpleRelationStringTrail = "/relation/";
var expected = { object: "relation" };
- assert.deepEqual(toTest(simpleRelationStringTrail), expectedi);
+ assert.deepEqual(toTest(simpleRelationStringTrail), expected);
test.finish();
}
@@ -78,20 +78,20 @@ module.exports =
, 'tag with two values': function(test) {
test.ok(true);
var nodeWithTwoValues = "/node[tag=foo|bar]";
- var expected = { object: "node", tag: { key:["key"], value:["foo", "bar"]}};
+ var expected = { object: "node", tag: { key:["tag"], value:["foo", "bar"]}};
assert.deepEqual(toTest(nodeWithTwoValues), expected);
test.finish();
}
, 'tag with two keys': function(test) {
test.ok(true);
- var nodeWithTwoKeys = "/node[foo,bar=value]";
+ var nodeWithTwoKeys = "/node[foo|bar=value]";
var expected = { object: "node", tag: { key:["foo", "bar"], value:["value"]}};
assert.deepEqual(toTest(nodeWithTwoKeys), expected);
test.finish();
}
, 'tags with cross product': function(test) {
test.ok(true);
- var tagCrossProduct = "/node[key1,key2=value1,value2]";
+ var tagCrossProduct = "/node[key1|key2=value1|value2]";
var expected = { object: "node", tag: {key:["key1", "key2"], value:["value1", "value2"]}};
assert.deepEqual(toTest(tagCrossProduct), expected);
test.finish();