sql-parser-vlad 0.0.3

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.
@@ -0,0 +1,106 @@
1
+ class SQLParser::Parser
2
+
3
+ option
4
+ ignorecase
5
+
6
+ macro
7
+ DIGIT [0-9]
8
+ UINT {DIGIT}+
9
+ BLANK \s+
10
+
11
+ YEARS {UINT}
12
+ MONTHS {UINT}
13
+ DAYS {UINT}
14
+ DATE {YEARS}-{MONTHS}-{DAYS}
15
+
16
+ IDENT \w+
17
+
18
+ rule
19
+ # [:state] pattern [actions]
20
+
21
+ # literals
22
+ \"{DATE}\" { [:date_string, Date.parse(text)] }
23
+ \'{DATE}\' { [:date_string, Date.parse(text)] }
24
+
25
+ \' { @state = :STRS; [:quote, text] }
26
+ :STRS \' { @state = nil; [:quote, text] }
27
+ :STRS .*(?=\') { [:character_string_literal, text.gsub("''", "'")] }
28
+
29
+ \" { @state = :STRD; [:quote, text] }
30
+ :STRD \" { @state = nil; [:quote, text] }
31
+ :STRD .*(?=\") { [:character_string_literal, text.gsub('""', '"')] }
32
+
33
+ {UINT} { [:unsigned_integer, text.to_i] }
34
+
35
+ # skip
36
+ {BLANK} # no action
37
+
38
+ # keywords
39
+ SELECT { [:SELECT, text] }
40
+ DISTINCTROW { [:DISTINCTROW, text] }
41
+ DISTINCT { [:DISTINCT, text] }
42
+ ALL { [:ALL, text] }
43
+ DATE { [:DATE, text] }
44
+ ASC { [:ASC, text] }
45
+ AS { [:AS, text] }
46
+ FROM { [:FROM, text] }
47
+ WHERE { [:WHERE, text] }
48
+ BETWEEN { [:BETWEEN, text] }
49
+ AND { [:AND, text] }
50
+ NOT { [:NOT, text] }
51
+ INNER { [:INNER, text] }
52
+ INSERT { [:INSERT, text] }
53
+ INTO { [:INTO, text] }
54
+ IN { [:IN, text] }
55
+ ORDER { [:ORDER, text] }
56
+ OR { [:OR, text] }
57
+ LIKE { [:LIKE, text] }
58
+ IS { [:IS, text] }
59
+ NULL { [:NULL, text] }
60
+ COUNT { [:COUNT, text] }
61
+ AVG { [:AVG, text] }
62
+ MAX { [:MAX, text] }
63
+ MIN { [:MIN, text] }
64
+ SUM { [:SUM, text] }
65
+ GROUP { [:GROUP, text] }
66
+ BY { [:BY, text] }
67
+ HAVING { [:HAVING, text] }
68
+ CROSS { [:CROSS, text] }
69
+ JOIN { [:JOIN, text] }
70
+ ON { [:ON, text] }
71
+ LEFT { [:LEFT, text] }
72
+ OUTER { [:OUTER, text] }
73
+ RIGHT { [:RIGHT, text] }
74
+ FULL { [:FULL, text] }
75
+ USING { [:USING, text] }
76
+ EXISTS { [:EXISTS, text] }
77
+ DESC { [:DESC, text] }
78
+ CURRENT_USER { [:CURRENT_USER, text] }
79
+ VALUES { [:VALUES, text] }
80
+
81
+ # tokens
82
+ E { [:E, text] }
83
+
84
+ <> { [:not_equals_operator, text] }
85
+ != { [:not_equals_operator, text] }
86
+ = { [:equals_operator, text] }
87
+ <= { [:less_than_or_equals_operator, text] }
88
+ < { [:less_than_operator, text] }
89
+ >= { [:greater_than_or_equals_operator, text] }
90
+ > { [:greater_than_operator, text] }
91
+
92
+ \( { [:left_paren, text] }
93
+ \) { [:right_paren, text] }
94
+ \* { [:asterisk, text] }
95
+ \/ { [:solidus, text] }
96
+ \+ { [:plus_sign, text] }
97
+ \- { [:minus_sign, text] }
98
+ \. { [:period, text] }
99
+ , { [:comma, text] }
100
+
101
+ # identifier
102
+ `{IDENT}` { [:identifier, text[1..-2]] }
103
+ {IDENT} { [:identifier, text] }
104
+
105
+ ---- header ----
106
+ require 'date'
@@ -0,0 +1,298 @@
1
+ #--
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by rex 1.0.5
4
+ # from lexical definition file "lib/sql-parser/parser.rex".
5
+ #++
6
+
7
+ require 'racc/parser'
8
+ class SQLParser::Parser < Racc::Parser
9
+ require 'strscan'
10
+
11
+ class ScanError < StandardError ; end
12
+
13
+ attr_reader :lineno
14
+ attr_reader :filename
15
+ attr_accessor :state
16
+
17
+ def scan_setup(str)
18
+ @ss = StringScanner.new(str)
19
+ @lineno = 1
20
+ @state = nil
21
+ end
22
+
23
+ def action
24
+ yield
25
+ end
26
+
27
+ def scan_str(str)
28
+ scan_setup(str)
29
+ do_parse
30
+ end
31
+ alias :scan :scan_str
32
+
33
+ def load_file( filename )
34
+ @filename = filename
35
+ open(filename, "r") do |f|
36
+ scan_setup(f.read)
37
+ end
38
+ end
39
+
40
+ def scan_file( filename )
41
+ load_file(filename)
42
+ do_parse
43
+ end
44
+
45
+
46
+ def next_token
47
+ return if @ss.eos?
48
+
49
+ # skips empty actions
50
+ until token = _next_token or @ss.eos?; end
51
+ token
52
+ end
53
+
54
+ def _next_token
55
+ text = @ss.peek(1)
56
+ @lineno += 1 if text == "\n"
57
+ token = case @state
58
+ when nil
59
+ case
60
+ when (text = @ss.scan(/\"[0-9]+-[0-9]+-[0-9]+\"/i))
61
+ action { [:date_string, Date.parse(text)] }
62
+
63
+ when (text = @ss.scan(/\'[0-9]+-[0-9]+-[0-9]+\'/i))
64
+ action { [:date_string, Date.parse(text)] }
65
+
66
+ when (text = @ss.scan(/\'/i))
67
+ action { @state = :STRS; [:quote, text] }
68
+
69
+ when (text = @ss.scan(/\"/i))
70
+ action { @state = :STRD; [:quote, text] }
71
+
72
+ when (text = @ss.scan(/[0-9]+/i))
73
+ action { [:unsigned_integer, text.to_i] }
74
+
75
+ when (text = @ss.scan(/\s+/i))
76
+ ;
77
+
78
+ when (text = @ss.scan(/SELECT/i))
79
+ action { [:SELECT, text] }
80
+
81
+ when (text = @ss.scan(/DISTINCTROW/i))
82
+ action { [:DISTINCTROW, text] }
83
+
84
+ when (text = @ss.scan(/DISTINCT/i))
85
+ action { [:DISTINCT, text] }
86
+
87
+ when (text = @ss.scan(/ALL/i))
88
+ action { [:ALL, text] }
89
+
90
+ when (text = @ss.scan(/DATE/i))
91
+ action { [:DATE, text] }
92
+
93
+ when (text = @ss.scan(/ASC/i))
94
+ action { [:ASC, text] }
95
+
96
+ when (text = @ss.scan(/AS/i))
97
+ action { [:AS, text] }
98
+
99
+ when (text = @ss.scan(/FROM/i))
100
+ action { [:FROM, text] }
101
+
102
+ when (text = @ss.scan(/WHERE/i))
103
+ action { [:WHERE, text] }
104
+
105
+ when (text = @ss.scan(/BETWEEN/i))
106
+ action { [:BETWEEN, text] }
107
+
108
+ when (text = @ss.scan(/AND/i))
109
+ action { [:AND, text] }
110
+
111
+ when (text = @ss.scan(/NOT/i))
112
+ action { [:NOT, text] }
113
+
114
+ when (text = @ss.scan(/INNER/i))
115
+ action { [:INNER, text] }
116
+
117
+ when (text = @ss.scan(/INSERT/i))
118
+ action { [:INSERT, text] }
119
+
120
+ when (text = @ss.scan(/INTO/i))
121
+ action { [:INTO, text] }
122
+
123
+ when (text = @ss.scan(/IN/i))
124
+ action { [:IN, text] }
125
+
126
+ when (text = @ss.scan(/ORDER/i))
127
+ action { [:ORDER, text] }
128
+
129
+ when (text = @ss.scan(/OR/i))
130
+ action { [:OR, text] }
131
+
132
+ when (text = @ss.scan(/LIKE/i))
133
+ action { [:LIKE, text] }
134
+
135
+ when (text = @ss.scan(/IS/i))
136
+ action { [:IS, text] }
137
+
138
+ when (text = @ss.scan(/NULL/i))
139
+ action { [:NULL, text] }
140
+
141
+ when (text = @ss.scan(/COUNT/i))
142
+ action { [:COUNT, text] }
143
+
144
+ when (text = @ss.scan(/AVG/i))
145
+ action { [:AVG, text] }
146
+
147
+ when (text = @ss.scan(/MAX/i))
148
+ action { [:MAX, text] }
149
+
150
+ when (text = @ss.scan(/MIN/i))
151
+ action { [:MIN, text] }
152
+
153
+ when (text = @ss.scan(/SUM/i))
154
+ action { [:SUM, text] }
155
+
156
+ when (text = @ss.scan(/GROUP/i))
157
+ action { [:GROUP, text] }
158
+
159
+ when (text = @ss.scan(/BY/i))
160
+ action { [:BY, text] }
161
+
162
+ when (text = @ss.scan(/HAVING/i))
163
+ action { [:HAVING, text] }
164
+
165
+ when (text = @ss.scan(/CROSS/i))
166
+ action { [:CROSS, text] }
167
+
168
+ when (text = @ss.scan(/JOIN/i))
169
+ action { [:JOIN, text] }
170
+
171
+ when (text = @ss.scan(/ON/i))
172
+ action { [:ON, text] }
173
+
174
+ when (text = @ss.scan(/LEFT/i))
175
+ action { [:LEFT, text] }
176
+
177
+ when (text = @ss.scan(/OUTER/i))
178
+ action { [:OUTER, text] }
179
+
180
+ when (text = @ss.scan(/RIGHT/i))
181
+ action { [:RIGHT, text] }
182
+
183
+ when (text = @ss.scan(/FULL/i))
184
+ action { [:FULL, text] }
185
+
186
+ when (text = @ss.scan(/USING/i))
187
+ action { [:USING, text] }
188
+
189
+ when (text = @ss.scan(/EXISTS/i))
190
+ action { [:EXISTS, text] }
191
+
192
+ when (text = @ss.scan(/DESC/i))
193
+ action { [:DESC, text] }
194
+
195
+ when (text = @ss.scan(/CURRENT_USER/i))
196
+ action { [:CURRENT_USER, text] }
197
+
198
+ when (text = @ss.scan(/VALUES/i))
199
+ action { [:VALUES, text] }
200
+
201
+ when (text = @ss.scan(/E/i))
202
+ action { [:E, text] }
203
+
204
+ when (text = @ss.scan(/<>/i))
205
+ action { [:not_equals_operator, text] }
206
+
207
+ when (text = @ss.scan(/!=/i))
208
+ action { [:not_equals_operator, text] }
209
+
210
+ when (text = @ss.scan(/=/i))
211
+ action { [:equals_operator, text] }
212
+
213
+ when (text = @ss.scan(/<=/i))
214
+ action { [:less_than_or_equals_operator, text] }
215
+
216
+ when (text = @ss.scan(/</i))
217
+ action { [:less_than_operator, text] }
218
+
219
+ when (text = @ss.scan(/>=/i))
220
+ action { [:greater_than_or_equals_operator, text] }
221
+
222
+ when (text = @ss.scan(/>/i))
223
+ action { [:greater_than_operator, text] }
224
+
225
+ when (text = @ss.scan(/\(/i))
226
+ action { [:left_paren, text] }
227
+
228
+ when (text = @ss.scan(/\)/i))
229
+ action { [:right_paren, text] }
230
+
231
+ when (text = @ss.scan(/\*/i))
232
+ action { [:asterisk, text] }
233
+
234
+ when (text = @ss.scan(/\//i))
235
+ action { [:solidus, text] }
236
+
237
+ when (text = @ss.scan(/\+/i))
238
+ action { [:plus_sign, text] }
239
+
240
+ when (text = @ss.scan(/\-/i))
241
+ action { [:minus_sign, text] }
242
+
243
+ when (text = @ss.scan(/\./i))
244
+ action { [:period, text] }
245
+
246
+ when (text = @ss.scan(/,/i))
247
+ action { [:comma, text] }
248
+
249
+ when (text = @ss.scan(/`\w+`/i))
250
+ action { [:identifier, text[1..-2]] }
251
+
252
+ when (text = @ss.scan(/\w+/i))
253
+ action { [:identifier, text] }
254
+
255
+ when (text = @ss.scan(/----/i))
256
+ ;
257
+
258
+ when (text = @ss.scan(/require/i))
259
+ ;
260
+
261
+ else
262
+ text = @ss.string[@ss.pos .. -1]
263
+ raise ScanError, "can not match: '" + text + "'"
264
+ end # if
265
+
266
+ when :STRS
267
+ case
268
+ when (text = @ss.scan(/\'/i))
269
+ action { @state = nil; [:quote, text] }
270
+
271
+ when (text = @ss.scan(/.*(?=\')/i))
272
+ action { [:character_string_literal, text.gsub("''", "'")] }
273
+
274
+ else
275
+ text = @ss.string[@ss.pos .. -1]
276
+ raise ScanError, "can not match: '" + text + "'"
277
+ end # if
278
+
279
+ when :STRD
280
+ case
281
+ when (text = @ss.scan(/\"/i))
282
+ action { @state = nil; [:quote, text] }
283
+
284
+ when (text = @ss.scan(/.*(?=\")/i))
285
+ action { [:character_string_literal, text.gsub('""', '"')] }
286
+
287
+ else
288
+ text = @ss.string[@ss.pos .. -1]
289
+ raise ScanError, "can not match: '" + text + "'"
290
+ end # if
291
+
292
+ else
293
+ raise ScanError, "undefined state: '" + state.to_s + "'"
294
+ end # case state
295
+ token
296
+ end # def _next_token
297
+
298
+ end # class