From 853c9129dd6b005993dcb51f560529721c59559e Mon Sep 17 00:00:00 2001 From: Eduardo Neira Date: Fri, 20 Sep 2019 15:34:19 -0300 Subject: [PATCH] Change to syntax grammar to disable reserved characters in string --- lib/rasti/db/nql/nodes.rb | 4 +- lib/rasti/db/nql/syntax.rb | 93 ++++++++++++++++++++++++++++----- lib/rasti/db/nql/syntax.treetop | 23 +++++--- spec/nql/syntax_parser_spec.rb | 10 +++- 4 files changed, 107 insertions(+), 23 deletions(-) diff --git a/lib/rasti/db/nql/nodes.rb b/lib/rasti/db/nql/nodes.rb index 5cd2c5a..502bc92 100644 --- a/lib/rasti/db/nql/nodes.rb +++ b/lib/rasti/db/nql/nodes.rb @@ -23,8 +23,8 @@ def tables _tables.elements.map{ |e| e.table.text_value } end - def column - _column.text_value + def name + _name.text_value end end diff --git a/lib/rasti/db/nql/syntax.rb b/lib/rasti/db/nql/syntax.rb index 23aae49..d822d0f 100644 --- a/lib/rasti/db/nql/syntax.rb +++ b/lib/rasti/db/nql/syntax.rb @@ -265,11 +265,11 @@ def _nt_statement end i0 = index - r1 = _nt_parenthesis_sentence + r1 = _nt_comparison if r1 r0 = r1 else - r2 = _nt_comparison + r2 = _nt_parenthesis_sentence if r2 r0 = r2 else @@ -414,7 +414,7 @@ def _tables elements[0] end - def _column + def _name elements[1] end end @@ -1307,17 +1307,31 @@ def _nt_literal_string end s0 << r1 if r1 - r2 = _nt_string + s2, i2 = [], index + loop do + r3 = _nt_any_character + if r3 + s2 << r3 + else + break + end + end + if s2.empty? + @index = i2 + r2 = nil + else + r2 = instantiate_node(SyntaxNode,input, i2...index, s2) + end s0 << r2 if r2 if has_terminal?('"', false, index) - r3 = instantiate_node(SyntaxNode,input, index...(index + 1)) + r4 = instantiate_node(SyntaxNode,input, index...(index + 1)) @index += 1 else terminal_parse_failure('"') - r3 = nil + r4 = nil end - s0 << r3 + s0 << r4 end end if s0.last @@ -1346,7 +1360,7 @@ def _nt_string s0, i0 = [], index loop do - r1 = _nt_character + r1 = _nt_valid_character if r1 s0 << r1 else @@ -1365,10 +1379,10 @@ def _nt_string r0 end - def _nt_character + def _nt_any_character start_index = index - if node_cache[:character].has_key?(index) - cached = node_cache[:character][index] + if node_cache[:any_character].has_key?(index) + cached = node_cache[:any_character][index] if cached cached = SyntaxNode.new(input, index...(index + 1)) if cached == true @index = cached.interval.end @@ -1376,14 +1390,44 @@ def _nt_character return cached end - if has_terminal?('\G[0-9a-zA-ZÁÀÄÂÃÅĀĂǍáàäâãåāăǎÉÈËÊĒĔĖĚéèëêēĕėěÍÌÏÎĨĬǏíìïîĩĭǐÓÒÖÔÕŌŎŐǑóòöôõōŏőǒÚÙÜÛŨŪŬŮŰǓúùüûũūŭůűǔÑñçÇ%&@#\\|\\:\\+\\-_=ß\'\\?!$\\*\\/\\s\\(\\)\\.]', true, index) + i0 = index + r1 = _nt_valid_character + if r1 + r0 = r1 + else + r2 = _nt_reserved_character + if r2 + r0 = r2 + else + @index = i0 + r0 = nil + end + end + + node_cache[:any_character][start_index] = r0 + + r0 + end + + def _nt_valid_character + start_index = index + if node_cache[:valid_character].has_key?(index) + cached = node_cache[:valid_character][index] + if cached + cached = SyntaxNode.new(input, index...(index + 1)) if cached == true + @index = cached.interval.end + end + return cached + end + + if has_terminal?('\G[0-9a-zA-ZÁÀÄÂÃÅĀĂǍáàäâãåāăǎÉÈËÊĒĔĖĚéèëêēĕėěÍÌÏÎĨĬǏíìïîĩĭǐÓÒÖÔÕŌŎŐǑóòöôõōŏőǒÚÙÜÛŨŪŬŮŰǓúùüûũūŭůűǔÑñçÇ%@#+-_\'?!$*/\\s]', true, index) r0 = instantiate_node(SyntaxNode,input, index...(index + 1)) @index += 1 else r0 = nil end - node_cache[:character][start_index] = r0 + node_cache[:valid_character][start_index] = r0 r0 end @@ -1593,6 +1637,29 @@ def _nt_digit r0 end + def _nt_reserved_character + start_index = index + if node_cache[:reserved_character].has_key?(index) + cached = node_cache[:reserved_character][index] + if cached + cached = SyntaxNode.new(input, index...(index + 1)) if cached == true + @index = cached.interval.end + end + return cached + end + + if has_terminal?('\G[&|.():!=<>~]', true, index) + r0 = instantiate_node(SyntaxNode,input, index...(index + 1)) + @index += 1 + else + r0 = nil + end + + node_cache[:reserved_character][start_index] = r0 + + r0 + end + end class SyntaxParser < Treetop::Runtime::CompiledParser diff --git a/lib/rasti/db/nql/syntax.treetop b/lib/rasti/db/nql/syntax.treetop index 815fb74..6b6514c 100644 --- a/lib/rasti/db/nql/syntax.treetop +++ b/lib/rasti/db/nql/syntax.treetop @@ -22,8 +22,8 @@ module Rasti end rule statement - parenthesis_sentence / - comparison + comparison / + parenthesis_sentence end rule parenthesis_sentence @@ -35,7 +35,7 @@ module Rasti end rule field - _tables:(table:field_name '.')* _column:field_name + _tables:(table:field_name '.')* _name:field_name end rule comparator @@ -89,15 +89,20 @@ module Rasti end rule literal_string - '"' string:string '"' + '"' string:any_character+ '"' end rule string - character+ + valid_character+ end - rule character - [0-9a-zA-ZÁÀÄÂÃÅĀĂǍáàäâãåāăǎÉÈËÊĒĔĖĚéèëêēĕėěÍÌÏÎĨĬǏíìïîĩĭǐÓÒÖÔÕŌŎŐǑóòöôõōŏőǒÚÙÜÛŨŪŬŮŰǓúùüûũūŭůűǔÑñçÇ%&@#\|\:\+\-_=ß'\?!$\*\/\s\(\)\.] + rule any_character + valid_character / + reserved_character + end + + rule valid_character + [0-9a-zA-ZÁÀÄÂÃÅĀĂǍáàäâãåāăǎÉÈËÊĒĔĖĚéèëêēĕėěÍÌÏÎĨĬǏíìïîĩĭǐÓÒÖÔÕŌŎŐǑóòöôõōŏőǒÚÙÜÛŨŪŬŮŰǓúùüûũūŭůűǔÑñçÇ%@#+-_'?!$*/\s] end rule boolean @@ -125,6 +130,10 @@ module Rasti [0-9] end + rule reserved_character + [&|.():!=<>~] + end + end end end diff --git a/spec/nql/syntax_parser_spec.rb b/spec/nql/syntax_parser_spec.rb index adcf71b..0e8b9cc 100644 --- a/spec/nql/syntax_parser_spec.rb +++ b/spec/nql/syntax_parser_spec.rb @@ -127,8 +127,16 @@ left_hand_operand = tree.proposition.left left_hand_operand.tables.must_equal ['relation_table_one', 'relation_table_two'] - left_hand_operand.column.must_equal 'column' + left_hand_operand.name.must_equal 'column' end end + + it 'must parse parenthesis sentence' do + tree = parser.parse '(column: name)' + tree.wont_be_nil + + tree.proposition.sentence.text_value.must_equal 'column: name' + end + end \ No newline at end of file