filter_lexer 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 47fbb2acdc5535e2e74b0355dbb042e289de54b1
4
- data.tar.gz: 4be18e0e750a3b298e4572e175e2b2e43fbeea3e
3
+ metadata.gz: 7b1d2010a2fac9cc9e4a08944bc449531745baaa
4
+ data.tar.gz: 30772a55499dde15575d62e07855a320273a366f
5
5
  SHA512:
6
- metadata.gz: 9e83318063753adab91aeddb75fbe34f3405a35f47b82dd01eed69a9276b5b97e9110a830da5f981a1a8d633159da158ce38a636562ce82d0da591a48c8e4503
7
- data.tar.gz: a7ff4f435b9ab633daf95f8b31c1a98b5c001b8b86cd82dfcfaf69749b4e2b61bcbbfffb4f8ff020af0f2cee9d081297d12060c9b2a6008b2628a3599829c513
6
+ metadata.gz: 616e680238ad483a026a977d2dee20f418b60a677eec3b4559d4a85fd45a045dc0327497547043b2d54e9a7fc927c40484498a5423f99d09c5cff01f0ba395fd
7
+ data.tar.gz: f4ed9510505531fc897ab7d269de8e05c69b251e26e0e642d3abdf0c8a21ba62905711c3e8ce3c8ee5d944992f4d18cb9b3f4703c425dbb836935e2129803f9e
data/.rubocop.yml CHANGED
@@ -27,6 +27,10 @@ Style/IndentationWidth:
27
27
  Style/MultilineOperationIndentation:
28
28
  EnforcedStyle: 'indented'
29
29
 
30
+ Style/PercentLiteralDelimiters:
31
+ PreferredDelimiters:
32
+ '%': '[]'
33
+
30
34
  Style/RedundantReturn:
31
35
  Enabled: false
32
36
 
data/Rakefile CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rubocop/rake_task'
3
3
 
4
- RuboCop::RakeTask.new(:rubocop, [:options]) do |task|
4
+ RuboCop::RakeTask.new(:rubocop, [:options]) do |task, args|
5
5
  task.options.push '--cache=false'
6
+
7
+ require 'shellwords'
8
+ task.options += Shellwords.shellsplit(args[:options]) unless args[:options].nil?
6
9
  end
7
10
  module RuboCop
8
11
  # We use tabs for indentation, not spaces. As many of the RuboCop cops seem
@@ -29,7 +29,7 @@ module FilterLexer
29
29
  end
30
30
 
31
31
  def query_variables
32
- return [data.sql]
32
+ return [data.data]
33
33
  end
34
34
  end
35
35
 
@@ -39,7 +39,7 @@ module FilterLexer
39
39
  end
40
40
  end
41
41
 
42
- class LogicOperator
42
+ class LogicalOperator
43
43
  def query_string
44
44
  return sql
45
45
  end
@@ -61,7 +61,7 @@ module FilterLexer
61
61
  end
62
62
  end
63
63
 
64
- class Operator
64
+ class RelationalOperator
65
65
  def query_string
66
66
  return sql
67
67
  end
@@ -73,15 +73,23 @@ module FilterLexer
73
73
 
74
74
  class EQOperator
75
75
  def sql
76
- return 'IS' if parent.data.is_a?(ValueSpecial)
77
- return '='
76
+ case parent.data
77
+ when BooleanLiteral, NullLiteral
78
+ return 'IS'
79
+ else
80
+ return '='
81
+ end
78
82
  end
79
83
  end
80
84
 
81
85
  class NEQOperator
82
86
  def sql
83
- return 'IS NOT' if parent.data.is_a?(ValueSpecial)
84
- return '<>'
87
+ case parent.data
88
+ when BooleanLiteral, NullLiteral
89
+ return 'IS NOT'
90
+ else
91
+ return '<>'
92
+ end
85
93
  end
86
94
  end
87
95
 
@@ -109,45 +117,15 @@ module FilterLexer
109
117
  end
110
118
  end
111
119
 
112
- class NotLikeOperator
113
- def sql
114
- return 'NOT LIKE'
115
- end
116
- end
117
-
118
120
  class LikeOperator
119
121
  def sql
120
122
  return 'LIKE'
121
123
  end
122
124
  end
123
125
 
124
- class BooleanLiteralFalse
125
- def sql
126
- return 'FALSE'
127
- end
128
- end
129
-
130
- class BooleanLiteralTrue
131
- def sql
132
- return 'TRUE'
133
- end
134
- end
135
-
136
- class NullLiteral
137
- def sql
138
- return 'NULL'
139
- end
140
- end
141
-
142
- class StringLiteral
143
- def sql
144
- return text_value
145
- end
146
- end
147
-
148
- class NumberLiteral
126
+ class NotLikeOperator
149
127
  def sql
150
- return text_value
128
+ return 'NOT LIKE'
151
129
  end
152
130
  end
153
131
  end
@@ -0,0 +1,9 @@
1
+ module FilterLexer
2
+ # The root element, expression is a collection of other expressions and and/or operators
3
+ class Expression < Treetop::Runtime::SyntaxNode
4
+ end
5
+
6
+ # A group is simply an expression in parenthesis
7
+ class Group < Treetop::Runtime::SyntaxNode
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ module FilterLexer
2
+ # A filter is the core object of the lexer: an indentifier, an relational operator and data
3
+ class Filter < Treetop::Runtime::SyntaxNode
4
+ # The identifier element
5
+ #
6
+ # Of type FilterLexer::Identifier
7
+ def identifier
8
+ return elements[0]
9
+ end
10
+
11
+ # The operator element
12
+ #
13
+ # Subclass of FilterLexer::RelationalOperator
14
+ def operator
15
+ return elements[1]
16
+ end
17
+
18
+ # The data element
19
+ #
20
+ # Subclass of FilterLexer::Literal
21
+ def data
22
+ return elements[2]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module FilterLexer
2
+ # An identifier is the target (variable) of the filter
3
+ class Identifier < Treetop::Runtime::SyntaxNode
4
+ end
5
+ end
@@ -0,0 +1,47 @@
1
+ module FilterLexer
2
+ # A literal is the value (data) of the filter
3
+ class Literal < Treetop::Runtime::SyntaxNode
4
+ def data
5
+ return text_value
6
+ end
7
+ end
8
+
9
+ # A boolean is a dual-state true/false literal
10
+ class BooleanLiteral < Literal
11
+ # The data for the boolean will be set during lexing
12
+ end
13
+
14
+ # A null is an unset or undefined literal
15
+ class NullLiteral < Literal
16
+ def data
17
+ return nil
18
+ end
19
+ end
20
+
21
+ # A string is a series of characters
22
+ class StringLiteral < Literal
23
+ def data
24
+ # Try to parse the string
25
+ string = text_value
26
+ quote_char = string[0]
27
+ string = string.slice(1, string.size - 2)
28
+ string = string.gsub(%[\\\\], %[\\])
29
+ string = string.gsub(%[\\] + quote_char, quote_char)
30
+ return string
31
+ end
32
+ end
33
+
34
+ # A number is an integer or a float, with an optional sign and an optional exponent
35
+ class NumberLiteral < Literal
36
+ def data
37
+ return text_value.to_f
38
+ end
39
+ end
40
+
41
+ # A datetime is a moment in time
42
+ class DatetimeLiteral < Literal
43
+ def data
44
+ return DateTime.parse(elements.first.data)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ module FilterLexer
2
+ # An logical operator is the glue between filters
3
+ class LogicalOperator < Treetop::Runtime::SyntaxNode
4
+ end
5
+
6
+ # An logical OR operator
7
+ class OrOperator < LogicalOperator
8
+ end
9
+
10
+ # An logical AND operator
11
+ class AndOperator < LogicalOperator
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ module FilterLexer
2
+ # An relational operator is the type (function) of the filter
3
+ class RelationalOperator < Treetop::Runtime::SyntaxNode
4
+ end
5
+
6
+ # An relational equality operator
7
+ class EQOperator < RelationalOperator
8
+ end
9
+
10
+ # An relational negative equality operator
11
+ class NEQOperator < RelationalOperator
12
+ end
13
+
14
+ # An relational less-than operator
15
+ class LTOperator < RelationalOperator
16
+ end
17
+
18
+ # An relational less-than-or-equal operator
19
+ class LEOperator < RelationalOperator
20
+ end
21
+
22
+ # An relational greater-than operator
23
+ class GTOperator < RelationalOperator
24
+ end
25
+
26
+ # An relational greater-than-or-equal operator
27
+ class GEOperator < RelationalOperator
28
+ end
29
+
30
+ # An relational string matching operator
31
+ class LikeOperator < RelationalOperator
32
+ end
33
+
34
+ # An relational negative string matching operator
35
+ class NotLikeOperator < RelationalOperator
36
+ end
37
+ end
@@ -1,100 +1,6 @@
1
- module FilterLexer
2
- # The root element, expression is a collection of other expressions and and/or operators
3
- class Expression < Treetop::Runtime::SyntaxNode
4
- end
5
-
6
- # A group is simply an expression in parenthesis
7
- class Group < Treetop::Runtime::SyntaxNode
8
- end
9
-
10
- # A filter is the core object of the lexer: an indentifier, an operator and a data
11
- class Filter < Treetop::Runtime::SyntaxNode
12
- # The identifier element
13
- #
14
- # Of type FilterLexer::Identifier
15
- def identifier
16
- return elements[0]
17
- end
18
-
19
- # The operator element
20
- #
21
- # Subclass of FilterLexer::Operator
22
- def operator
23
- return elements[1]
24
- end
25
-
26
- # The value element
27
- #
28
- # Subclass of FilterLexer::Value
29
- def data
30
- return elements[2]
31
- end
32
- end
33
-
34
- # An logic operator is the glue between filters
35
- class LogicOperator < Treetop::Runtime::SyntaxNode
36
- end
37
-
38
- class OrOperator < LogicOperator
39
- end
40
-
41
- class AndOperator < LogicOperator
42
- end
43
-
44
- # An identifier is the target (variable) of the filter
45
- class Identifier < Treetop::Runtime::SyntaxNode
46
- end
47
-
48
- # An operator is the type (function) of the filter
49
- class Operator < Treetop::Runtime::SyntaxNode
50
- end
51
-
52
- class EQOperator < Operator
53
- end
54
-
55
- class NEQOperator < Operator
56
- end
57
-
58
- class LTOperator < Operator
59
- end
60
-
61
- class LEOperator < Operator
62
- end
63
-
64
- class GTOperator < Operator
65
- end
66
-
67
- class GEOperator < Operator
68
- end
69
-
70
- class NotLikeOperator < Operator
71
- end
72
-
73
- class LikeOperator < Operator
74
- end
75
-
76
- # A value is the data of the filter
77
- class Value < Treetop::Runtime::SyntaxNode
78
- end
79
-
80
- class ValueSpecial < Value
81
- end
82
-
83
- class ValueScalar < Value
84
- end
85
-
86
- class BooleanLiteralFalse < ValueSpecial
87
- end
88
-
89
- class BooleanLiteralTrue < ValueSpecial
90
- end
91
-
92
- class NullLiteral < ValueSpecial
93
- end
94
-
95
- class StringLiteral < ValueScalar
96
- end
97
-
98
- class NumberLiteral < ValueScalar
99
- end
100
- end
1
+ require 'filter_lexer/nodes/collections'
2
+ require 'filter_lexer/nodes/filter'
3
+ require 'filter_lexer/nodes/identifier'
4
+ require 'filter_lexer/nodes/literals'
5
+ require 'filter_lexer/nodes/logical_operators'
6
+ require 'filter_lexer/nodes/relational_operators'
@@ -28,11 +28,11 @@ grammar FilterLexer
28
28
  end
29
29
 
30
30
  rule filter_comparison
31
- identifier space? comparison_operator space? number <Filter>
31
+ identifier space? comparison_operator space? (number / datetime) <Filter>
32
32
  end
33
33
 
34
34
  rule filter_like
35
- identifier space like_operator space string <Filter>
35
+ identifier space? like_operator space? string <Filter>
36
36
  end
37
37
 
38
38
  # Logic
@@ -64,45 +64,41 @@ grammar FilterLexer
64
64
  end
65
65
 
66
66
  rule eq_operator
67
- '==' <EQOperator>
67
+ '' ('==' / 'eq' / 'EQ' / 'is' / 'IS') <EQOperator>
68
68
  end
69
69
 
70
70
  rule neq_operator
71
- '' ('!=' / '<>') <NEQOperator>
71
+ '' ('!=' / '<>' / 'neq' / 'NEQ' / 'not is' / 'NOT IS' / 'is not' / 'IS NOT') <NEQOperator>
72
72
  end
73
73
 
74
74
  rule lt_operator
75
- '<' <LTOperator>
75
+ '' ('<' / 'lt' / 'LT') <LTOperator>
76
76
  end
77
77
 
78
78
  rule le_operator
79
- '<=' <LEOperator>
79
+ '' ('<=' / 'le' / 'LE') <LEOperator>
80
80
  end
81
81
 
82
82
  rule gt_operator
83
- '>' <GTOperator>
83
+ '' ('>' / 'gt' / 'GT') <GTOperator>
84
84
  end
85
85
 
86
86
  rule ge_operator
87
- '>=' <GEOperator>
87
+ '' ('>=' / 'ge' / 'GE') <GEOperator>
88
88
  end
89
89
 
90
90
  rule yes_like_operator
91
- '' ('like' / 'LIKE' / '~=') <LikeOperator>
91
+ '' ('=~' / 'like' / 'LIKE') <LikeOperator>
92
92
  end
93
93
 
94
94
  rule not_like_operator
95
- '' ('!~=' / 'NOT LIKE' / 'not like') <NotLikeOperator>
95
+ '' ('!=~' / 'not like' / 'NOT LIKE') <NotLikeOperator>
96
96
  end
97
97
 
98
98
  # Literals
99
99
 
100
100
  rule value
101
- value_special / number / string
102
- end
103
-
104
- rule value_special
105
- null / boolean
101
+ null / boolean / number / datetime / string
106
102
  end
107
103
 
108
104
  rule number
@@ -134,27 +130,46 @@ grammar FilterLexer
134
130
  end
135
131
 
136
132
  rule boolean_true
137
- '' ('true' / 'TRUE' / 'on' / 'ON' / 'yes' / 'YES') <BooleanLiteralTrue>
133
+ '' ('true' / 'TRUE' / 'on' / 'ON' / 'yes' / 'YES') <BooleanLiteral> {
134
+ def data
135
+ return true
136
+ end
137
+ }
138
138
  end
139
139
 
140
140
  rule boolean_false
141
- '' ('false' / 'FALSE' / 'off' / 'OFF' / 'no' / 'NO') <BooleanLiteralFalse>
141
+ '' ('false' / 'FALSE' / 'off' / 'OFF' / 'no' / 'NO') <BooleanLiteral> {
142
+ def data
143
+ return false
144
+ end
145
+ }
142
146
  end
143
147
 
144
148
  rule null
145
149
  '' ('null' / 'NULL' / 'nil' / 'NIL' / 'nul' / 'NUL') <NullLiteral>
146
150
  end
147
151
 
152
+ rule datetime
153
+ string &{ |s|
154
+ begin
155
+ DateTime.parse(s.first.data)
156
+ return true
157
+ rescue
158
+ return false
159
+ end
160
+ } <DatetimeLiteral>
161
+ end
162
+
148
163
  rule string
149
- string_single / string_double
164
+ '' (string_single / string_double) <StringLiteral>
150
165
  end
151
166
 
152
167
  rule string_single
153
- "'" ([^'\\] / "\\" . )* "'" <StringLiteral>
168
+ "'" ([^'\\] / "\\" . )* "'"
154
169
  end
155
170
 
156
171
  rule string_double
157
- '"' ([^"\\] / "\\" . )* '"' <StringLiteral>
172
+ '"' ([^"\\] / "\\" . )* '"'
158
173
  end
159
174
 
160
175
  rule identifier
@@ -1,3 +1,3 @@
1
1
  module FilterLexer
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filter_lexer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michon van Dooren
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-26 00:00:00.000000000 Z
11
+ date: 2015-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -118,6 +118,12 @@ files:
118
118
  - lib/filter_lexer/exceptions.rb
119
119
  - lib/filter_lexer/formatters/sql.rb
120
120
  - lib/filter_lexer/nodes.rb
121
+ - lib/filter_lexer/nodes/collections.rb
122
+ - lib/filter_lexer/nodes/filter.rb
123
+ - lib/filter_lexer/nodes/identifier.rb
124
+ - lib/filter_lexer/nodes/literals.rb
125
+ - lib/filter_lexer/nodes/logical_operators.rb
126
+ - lib/filter_lexer/nodes/relational_operators.rb
121
127
  - lib/filter_lexer/syntax.treetop
122
128
  - lib/filter_lexer/version.rb
123
129
  homepage: http://github.com/MaienM/FilterLexer