From 8e17425ccd7cbccf9aaa03ca008ca7b2c1205cd7 Mon Sep 17 00:00:00 2001 From: Mo Morsi Date: Wed, 17 Jun 2020 00:43:40 -0400 Subject: [PATCH] Enable 'greedy' regex to capture entire script/filter expression Right now the following expression will trip up the parser: $..[(')]')] The parser will encounter the ')]' inside the static string and use that as the end of the script expression & child-member-component. When it encounters the closing single-quote a lexical error will be thrown. This patch removes the '?' constraining the character wildcard in the script and filter expression matcher so that we completely parse expressions to the end. It also adds a test for this edge case. Note: this causes issues with multiple filter expressions such as: $..[?('expr1')][?('expr2')] The parser will now pickup the expression as everything between the first '[?(' and the last ')]', in this case the expression will be: 'expr1')][?('expr2' Which will throw the expression evaluator off. At the current time it is not aparent how to handle both cases w/ the current BNF based parser. --- generated/parser.js | 2 +- lib/grammar.js | 4 ++-- test/lessons.js | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/generated/parser.js b/generated/parser.js index 02de9cc..52cef31 100644 --- a/generated/parser.js +++ b/generated/parser.js @@ -689,7 +689,7 @@ case 13:return 31 break; } }, -rules: [/^(?:\$)/,/^(?:\.\.)/,/^(?:\.)/,/^(?:\*)/,/^(?:[a-zA-Z_]+[a-zA-Z0-9_]*)/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?:((-?(?:0|[1-9][0-9]*)))?\:((-?(?:0|[1-9][0-9]*)))?(\:((-?(?:0|[1-9][0-9]*)))?)?)/,/^(?:(-?(?:0|[1-9][0-9]*)))/,/^(?:"(?:\\["bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^"\\])*")/,/^(?:'(?:\\['bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^'\\])*')/,/^(?:\(.+?\)(?=\]))/,/^(?:\?\(.+?\)(?=\]))/], +rules: [/^(?:\$)/,/^(?:\.\.)/,/^(?:\.)/,/^(?:\*)/,/^(?:[a-zA-Z_]+[a-zA-Z0-9_]*)/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?:((-?(?:0|[1-9][0-9]*)))?\:((-?(?:0|[1-9][0-9]*)))?(\:((-?(?:0|[1-9][0-9]*)))?)?)/,/^(?:(-?(?:0|[1-9][0-9]*)))/,/^(?:"(?:\\["bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^"\\])*")/,/^(?:'(?:\\['bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^'\\])*')/,/^(?:\(.+\)(?=\]))/,/^(?:\?\(.+\)(?=\]))/], conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}} }; return lexer; diff --git a/lib/grammar.js b/lib/grammar.js index af0b2a1..77a18a0 100755 --- a/lib/grammar.js +++ b/lib/grammar.js @@ -22,8 +22,8 @@ var grammar = { ["{int}", "return 'INTEGER'"], [dict.qq_string, "yytext = yytext.substr(1,yyleng-2); return 'QQ_STRING';"], [dict.q_string, "yytext = yytext.substr(1,yyleng-2); return 'Q_STRING';"], - ["\\(.+?\\)(?=\\])", "return 'SCRIPT_EXPRESSION'"], - ["\\?\\(.+?\\)(?=\\])", "return 'FILTER_EXPRESSION'"] + ["\\(.+\\)(?=\\])", "return 'SCRIPT_EXPRESSION'"], + ["\\?\\(.+\\)(?=\\])", "return 'FILTER_EXPRESSION'"] ] }, diff --git a/test/lessons.js b/test/lessons.js index 2101bb0..a7c6d56 100644 --- a/test/lessons.js +++ b/test/lessons.js @@ -36,3 +36,10 @@ suite('orig-google-code-issues', function() { }); +suite('greedy expressions', function() { + test(')] in expression', function() { + var data = { 'answer': 42 }; + var results = jp.query(data, "$[?(')]')]"); + assert.deepEqual(results, [ 42 ]); + }) +});