Commit ae5c4b0b authored by Romain Courteaud's avatar Romain Courteaud

Grammar: replace JSCC by Jison

http://zaach.github.io/jison/about/

Jison is maintained and used by other JS projects (like Coffeescript)
parent 0a1e517d
......@@ -6,7 +6,7 @@ PARSER_PAR = $(QUERIES_DIR)/core/parser.par
PARSER_OUT = $(QUERIES_DIR)/build/parser.js
# npm install jscc-node
JSCC_CMD = node ./node_modules/jscc-node/jscc.js -t ./node_modules/jscc-node/driver_node.js_
JSCC_CMD = node ./node_modules/.bin/jison -m js
auto: compile
......
......@@ -36,7 +36,6 @@
},
"devDependencies": {
"renderjs": "git+https://lab.nexedi.com/nexedi/renderjs.git",
"jscc-node": "0.3.x",
"grunt": "0.4.x",
"grunt-cli": "~0.1.11",
"grunt-contrib-concat": "0.3.x",
......@@ -47,6 +46,7 @@
"grunt-jslint": "~1.0.0",
"lz-string": "^1.4.4",
"sinon": "~1.7.3",
"jison": "~0.4.16",
"connect-livereload": "~0.3.0",
"grunt-open": "~0.2.2",
"grunt-contrib-connect": "~0.5.0"
......
This diff is collapsed.
/~ Token definitions ~/
/* description: jio grammar */
/* lexical grammar */
%lex
! ' |\t' ;
%x letsquote
%x endquote
' |\t' WHITESPACE ;
'\(' LEFT_PARENTHESE ;
'\)' RIGHT_PARENTHESE ;
'AND' AND ;
'OR' OR ;
'NOT' NOT ;
'[^><!= :\(\)"][^ :\(\)"]*:' COLUMN ;
'"(\\.|[^\\"])*"' STRING ;
'[^><!= :\(\)"][^ :\(\)"]*' WORD ;
'(>=?|<=?|!?=)' OPERATOR ;
%%
##
"\"" {this.begin("letsquote"); return "QUOTE";}
<letsquote>(\\\"|[^"])* {this.popState(); this.begin("endquote"); return "QUOTED_STRING";}
<endquote>"\"" {this.popState(); return "QUOTE";}
/~ Grammar specification ~/
[^\S]+ /* skip whitespace */
"(" {return "LEFT_PARENTHESE";}
")" {return "RIGHT_PARENTHESE";}
"AND" {return "AND";}
"OR" {return "OR";}
"NOT" {return "NOT";}
":" {return "DEFINITION";}
begin: search_text [* result = %1; *];
(\!?\=|\<\=?|\>\=?) {return 'OPERATOR';}
[^\s\n"():><!=]+ {return 'WORD';}
<<EOF>> {return 'EOF';}
/lex
/* operator associations and precedence */
%start begin
%% /* language grammar */
begin
: search_text end { return $1; }
;
end
:
| EOF
| NEWLINE
;
search_text
: and_expression [* %% = %1; *]
| and_expression search_text [* %% = mkComplexQuery('OR',[%1,%2]); *]
| and_expression OR search_text [* %% = mkComplexQuery('OR',[%1,%3]); *]
: and_expression { $$ = $1; }
| and_expression search_text { $$ = mkComplexQuery('OR', [$1, $2]); }
| and_expression OR search_text { $$ = mkComplexQuery('OR', [$1, $3]); }
;
and_expression
: boolean_expression [* %% = %1 ; *]
| boolean_expression AND and_expression [* %% = mkComplexQuery('AND',[%1,%3]); *]
: boolean_expression { $$ = $1; }
| boolean_expression AND and_expression { $$ = mkComplexQuery('AND', [$1, $3]); }
;
boolean_expression
: NOT expression [* %% = mkNotQuery(%2); *]
| expression [* %% = %1; *]
: NOT expression { $$ = mkNotQuery($2); }
| expression { $$ = $1; }
;
expression
: LEFT_PARENTHESE search_text RIGHT_PARENTHESE [* %% = %2; *]
| COLUMN expression [* simpleQuerySetKey(%2,%1.split(':').slice(0,-1).join(':')); %% = %2; *]
| value [* %% = %1; *]
: LEFT_PARENTHESE search_text RIGHT_PARENTHESE { $$ = $2; }
| WORD DEFINITION expression { simpleQuerySetKey($3, $1); $$ = $3; }
| value { $$ = $1; }
;
value
: OPERATOR string [* %2.operator = %1 ; %% = %2; *]
| string [* %% = %1; *]
: OPERATOR string { $2.operator = $1 ; $$ = $2; }
| string { $$ = $1; }
;
string
: WORD [* %% = mkSimpleQuery('',%1); *]
| STRING [* %% = mkSimpleQuery('',%1.split('"').slice(1,-1).join('"')); *]
: WORD { $$ = mkSimpleQuery('', $1); }
| QUOTE QUOTED_STRING QUOTE { $$ = mkSimpleQuery('', $2); }
;
[*
var arrayExtend = function () {
var j, i, newlist = [], list_list = arguments;
for (j = 0; j < list_list.length; j += 1) {
for (i = 0; i < list_list[j].length; i += 1) {
newlist.push(list_list[j][i]);
}
}
return newlist;
}, mkSimpleQuery = function (key, value, operator) {
var object = {"type": "simple", "key": key, "value": value};
if (operator !== undefined) {
object.operator = operator;
}
return object;
}, mkNotQuery = function (query) {
if (query.operator === "NOT") {
return query.query_list[0];
}
return {"type": "complex", "operator": "NOT", "query_list": [query]};
}, mkComplexQuery = function (operator, query_list) {
var i, query_list2 = [];
for (i = 0; i < query_list.length; i += 1) {
if (query_list[i].operator === operator) {
query_list2 = arrayExtend(query_list2, query_list[i].query_list);
} else {
query_list2.push(query_list[i]);
}
}
return {type:"complex",operator:operator,query_list:query_list2};
}, simpleQuerySetKey = function (query, key) {
var i;
if (query.type === "complex") {
for (i = 0; i < query.query_list.length; ++i) {
simpleQuerySetKey (query.query_list[i],key);
}
return true;
}
if (query.type === "simple" && !query.key) {
query.key = key;
return true;
}
return false;
},
error_offsets = [],
error_lookaheads = [],
error_count = 0,
result;
if ((error_count = __##PREFIX##parse(string, error_offsets, error_lookaheads)) > 0) {
var i;
for (i = 0; i < error_count; i += 1) {
throw new Error("Parse error near \"" +
string.substr(error_offsets[i]) +
"\", expecting \"" +
error_lookaheads[i].join() + "\"");
}
}
*]
......@@ -5,3 +5,55 @@
* @return {Object} The json query tree
*/
function parseStringToObject(string) {
var arrayExtend = function () {
var j, i, newlist = [], list_list = arguments;
for (j = 0; j < list_list.length; j += 1) {
for (i = 0; i < list_list[j].length; i += 1) {
newlist.push(list_list[j][i]);
}
}
return newlist;
}, mkSimpleQuery = function (key, value, operator) {
var object = {"type": "simple", "key": key, "value": value};
if (operator !== undefined) {
object.operator = operator;
}
return object;
}, mkNotQuery = function (query) {
if (query.operator === "NOT") {
return query.query_list[0];
}
return {"type": "complex", "operator": "NOT", "query_list": [query]};
}, mkComplexQuery = function (operator, query_list) {
var i, query_list2 = [];
for (i = 0; i < query_list.length; i += 1) {
if (query_list[i].operator === operator) {
query_list2 = arrayExtend(query_list2, query_list[i].query_list);
} else {
query_list2.push(query_list[i]);
}
}
return {type:"complex",operator:operator,query_list:query_list2};
}, simpleQuerySetKey = function (query, key) {
var i;
if (query.type === "complex") {
for (i = 0; i < query.query_list.length; ++i) {
simpleQuerySetKey (query.query_list[i],key);
}
return true;
}
if (query.type === "simple" && !query.key) {
query.key = key;
return true;
}
return false;
},
error_offsets = [],
error_lookaheads = [],
error_count = 0,
result;
return result;
return parser.parse(string);
} // parseStringToObject
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment