anbt-sql-formatter 0.0.1 → 0.0.2

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.
@@ -1,8 +1,6 @@
1
1
  #! /usr/bin/ruby1.8
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
- require "pp"
5
-
6
4
  begin
7
5
  require "anbt-sql-formatter/formatter"
8
6
  rescue LoadError
@@ -44,7 +42,6 @@ def main
44
42
  formatter = AnbtSql::Formatter.new(rule)
45
43
  result = formatter.format(src)
46
44
  puts result
47
- #pp result
48
45
  end
49
46
 
50
47
  main()
@@ -1,7 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- require "pp"
4
-
5
3
  =begin
6
4
  エスケープ文字
7
5
  =end
@@ -15,7 +13,7 @@ class CoarseToken
15
13
  end
16
14
 
17
15
  def to_s
18
- %Q!<#{@_type}>%s</>! % [@string.gsub("\n", "<br>")]
16
+ @string
19
17
  end
20
18
  end
21
19
 
@@ -12,8 +12,6 @@ BlancoSqlFormatterException : SQL整形ツールの例外を表します。
12
12
  @author sonota (2009-11-xx)
13
13
  =end
14
14
 
15
- require "pp"
16
-
17
15
 
18
16
  class AnbtSql
19
17
  class FormatterException < IOError
@@ -1,7 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- require "pp"
4
-
5
3
  require "anbt-sql-formatter/rule"
6
4
  require "anbt-sql-formatter/parser"
7
5
  require "anbt-sql-formatter/exception"
@@ -11,6 +9,8 @@ require "anbt-sql-formatter/helper" # Stack
11
9
  class AnbtSql
12
10
  class Formatter
13
11
 
12
+ include StringUtil
13
+
14
14
  @rule = nil
15
15
 
16
16
  def initialize(rule)
@@ -49,7 +49,7 @@ class AnbtSql
49
49
  @function_bracket.clear()
50
50
  begin
51
51
  isSqlEndsWithNewLine = false
52
- if sql_str.endsWith("\n")
52
+ if sql_str.end_with?("\n")
53
53
  isSqlEndsWithNewLine = true
54
54
  end
55
55
 
@@ -103,8 +103,8 @@ class AnbtSql
103
103
  tokens[index + 1].string == "+" &&
104
104
  tokens[index + 2].string == ")")
105
105
  tokens[index].string = "(+)"
106
- tokens.remove(index + 1)
107
- tokens.remove(index + 1)
106
+ ArrayUtil.remove(tokens, index + 1)
107
+ ArrayUtil.remove(tokens, index + 1)
108
108
  end
109
109
  index += 1
110
110
  end
@@ -115,17 +115,17 @@ class AnbtSql
115
115
  prevToken = nil
116
116
 
117
117
  (tokens.size - 1).downto(1){|index|
118
- token = tokens.get(index)
119
- prevToken = tokens.get(index - 1)
118
+ token = ArrayUtil.get(tokens, index)
119
+ prevToken = ArrayUtil.get(tokens, index - 1)
120
120
 
121
121
  if (token._type == AnbtSql::TokenConstants::SPACE &&
122
122
  (prevToken._type == AnbtSql::TokenConstants::SYMBOL ||
123
123
  prevToken._type == AnbtSql::TokenConstants::COMMENT))
124
- tokens.remove(index)
124
+ ArrayUtil.remove(tokens, index)
125
125
  elsif ((token._type == AnbtSql::TokenConstants::SYMBOL ||
126
126
  token._type == AnbtSql::TokenConstants::COMMENT) &&
127
127
  prevToken._type == AnbtSql::TokenConstants::SPACE)
128
- tokens.remove(index - 1)
128
+ ArrayUtil.remove(tokens, index - 1)
129
129
  elsif (token._type == AnbtSql::TokenConstants::SPACE)
130
130
  token.string = " "
131
131
  end
@@ -138,8 +138,8 @@ class AnbtSql
138
138
 
139
139
  # Length of tokens changes in loop!
140
140
  while index < tokens.size
141
- prev = tokens.get(index - 1)
142
- token = tokens.get(index )
141
+ prev = ArrayUtil.get(tokens, index - 1)
142
+ token = ArrayUtil.get(tokens, index )
143
143
 
144
144
  if (prev._type != AnbtSql::TokenConstants::SPACE &&
145
145
  token._type != AnbtSql::TokenConstants::SPACE)
@@ -153,11 +153,11 @@ class AnbtSql
153
153
  # 関数名の後ろにはスペースは入れない
154
154
  # no space after function name
155
155
  if (@rule.function?(prev.string) &&
156
- token.string.equals("("))
156
+ token.string == "(")
157
157
  index += 1 ; next
158
158
  end
159
159
 
160
- tokens.add(index,
160
+ ArrayUtil.add(tokens, index,
161
161
  AnbtSql::Token.new(AnbtSql::TokenConstants::SPACE, " ")
162
162
  )
163
163
  end
@@ -178,7 +178,7 @@ class AnbtSql
178
178
  index = 0
179
179
  # Length of tokens changes in loop!
180
180
  while index < tokens.size
181
- token = tokens.get(index)
181
+ token = ArrayUtil.get(tokens, index)
182
182
 
183
183
  if token._type == AnbtSql::TokenConstants::SYMBOL # ****
184
184
 
@@ -208,61 +208,61 @@ class AnbtSql
208
208
  elsif token._type == AnbtSql::TokenConstants::KEYWORD # ****
209
209
 
210
210
  # indentを2つ増やし、キーワードの後ろで改行
211
- if (token.string.equalsIgnoreCase("DELETE") ||
212
- token.string.equalsIgnoreCase("SELECT") ||
213
- token.string.equalsIgnoreCase("UPDATE") )
211
+ if (equals_ignore_case(token.string, "DELETE") ||
212
+ equals_ignore_case(token.string, "SELECT") ||
213
+ equals_ignore_case(token.string, "UPDATE") )
214
214
  indent += 2
215
215
  index += insert_return_and_indent(tokens, index + 1, indent, "+2")
216
216
  end
217
217
 
218
218
  # indentを1つ増やし、キーワードの後ろで改行
219
- if @rule.kw_plus1_indent_x_nl.any?{ |kw| token.string.equalsIgnoreCase(kw) }
219
+ if @rule.kw_plus1_indent_x_nl.any?{ |kw| equals_ignore_case(token.string, kw) }
220
220
  indent += 1
221
221
  index += insert_return_and_indent(tokens, index + 1, indent)
222
222
  end
223
223
 
224
224
  # キーワードの前でindentを1つ減らして改行、キーワードの後ろでindentを戻して改行。
225
- if @rule.kw_minus1_indent_nl_x_plus1_indent.any?{ |kw| token.string.equalsIgnoreCase(kw) }
225
+ if @rule.kw_minus1_indent_nl_x_plus1_indent.any?{ |kw| equals_ignore_case(token.string, kw) }
226
226
  index += insert_return_and_indent(tokens, index , indent - 1)
227
227
  index += insert_return_and_indent(tokens, index + 1, indent )
228
228
  end
229
229
 
230
230
  # キーワードの前でindentを1つ減らして改行、キーワードの後ろでindentを戻して改行。
231
- if (token.string.equalsIgnoreCase("VALUES"))
231
+ if (equals_ignore_case(token.string, "VALUES"))
232
232
  indent -= 1
233
233
  index += insert_return_and_indent(tokens, index, indent)
234
234
  end
235
235
 
236
236
  # キーワードの前でindentを1つ減らして改行
237
- if (token.string.equalsIgnoreCase("END"))
237
+ if (equals_ignore_case(token.string, "END"))
238
238
  indent -= 1
239
239
  index += insert_return_and_indent(tokens, index, indent)
240
240
  end
241
241
 
242
242
  # キーワードの前で改行
243
- if @rule.kw_nl_x.any?{ |kw| token.string.equalsIgnoreCase(kw) }
243
+ if @rule.kw_nl_x.any?{ |kw| equals_ignore_case(token.string, kw) }
244
244
  index += insert_return_and_indent(tokens, index, indent)
245
245
  end
246
246
 
247
247
  # キーワードの前で改行, インデント+1
248
- if @rule.kw_nl_x_plus1_indent.any?{ |kw| token.string.equalsIgnoreCase(kw) }
248
+ if @rule.kw_nl_x_plus1_indent.any?{ |kw| equals_ignore_case(token.string, kw) }
249
249
  index += insert_return_and_indent(tokens, index, indent + 1)
250
250
  end
251
251
 
252
252
  # キーワードの前で改行。indentを強制的に0にする。
253
- if (token.string.equalsIgnoreCase("UNION" ) ||
254
- token.string.equalsIgnoreCase("INTERSECT") ||
255
- token.string.equalsIgnoreCase("EXCEPT" ) )
253
+ if (equals_ignore_case(token.string, "UNION" ) ||
254
+ equals_ignore_case(token.string, "INTERSECT") ||
255
+ equals_ignore_case(token.string, "EXCEPT" ) )
256
256
  indent -= 2
257
257
  index += insert_return_and_indent(tokens, index , indent)
258
258
  index += insert_return_and_indent(tokens, index + 1, indent)
259
259
  end
260
260
 
261
- if token.string.equalsIgnoreCase("BETWEEN")
261
+ if equals_ignore_case(token.string, "BETWEEN")
262
262
  encounterBetween = true
263
263
  end
264
264
 
265
- if token.string.equalsIgnoreCase("AND")
265
+ if equals_ignore_case(token.string, "AND")
266
266
  # BETWEEN のあとのANDは改行しない。
267
267
  if not encounterBetween
268
268
  index += insert_return_and_indent(tokens, index, indent)
@@ -272,10 +272,10 @@ class AnbtSql
272
272
 
273
273
  elsif (token._type == AnbtSql::TokenConstants::COMMENT) # ****
274
274
 
275
- if token.string.startsWith("/*")
275
+ if token.string.start_with?("/*")
276
276
  # マルチラインコメントの後に改行を入れる。
277
277
  index += insert_return_and_indent(tokens, index + 1, indent)
278
- elsif /^--/ =~ token.string
278
+ elsif token.string.start_with?("--")
279
279
  index += insert_return_and_indent(tokens, index + 1, indent)
280
280
  end
281
281
  end
@@ -295,21 +295,21 @@ class AnbtSql
295
295
  (tokens.size - 1).downto(4).each{|index|
296
296
  next if (index >= tokens.size())
297
297
 
298
- t0 = tokens.get(index )
299
- t1 = tokens.get(index - 1)
300
- t2 = tokens.get(index - 2)
301
- t3 = tokens.get(index - 3)
302
- t4 = tokens.get(index - 4)
298
+ t0 = ArrayUtil.get(tokens, index )
299
+ t1 = ArrayUtil.get(tokens, index - 1)
300
+ t2 = ArrayUtil.get(tokens, index - 2)
301
+ t3 = ArrayUtil.get(tokens, index - 3)
302
+ t4 = ArrayUtil.get(tokens, index - 4)
303
303
 
304
- if (t4.string. equalsIgnoreCase("(") &&
305
- t3.string.trim.equalsIgnoreCase("" ) &&
306
- t1.string.trim.equalsIgnoreCase("" ) &&
307
- t0.string. equalsIgnoreCase(")") )
304
+ if (equals_ignore_case(t4.string , "(") &&
305
+ equals_ignore_case(t3.string.strip, "" ) &&
306
+ equals_ignore_case(t1.string.strip, "" ) &&
307
+ equals_ignore_case(t0.string , ")") )
308
308
  t4.string = t4.string + t2.string + t0.string
309
- tokens.remove(index )
310
- tokens.remove(index - 1)
311
- tokens.remove(index - 2)
312
- tokens.remove(index - 3)
309
+ ArrayUtil.remove(tokens, index )
310
+ ArrayUtil.remove(tokens, index - 1)
311
+ ArrayUtil.remove(tokens, index - 2)
312
+ ArrayUtil.remove(tokens, index - 3)
313
313
  end
314
314
  }
315
315
  end
@@ -321,15 +321,15 @@ class AnbtSql
321
321
  # SQLの前後に空白があったら削除する。
322
322
  # Delete space token at first and last of SQL tokens.
323
323
 
324
- token = tokens.get(0)
324
+ token = ArrayUtil.get(tokens, 0)
325
325
  if (token._type == AnbtSql::TokenConstants::SPACE)
326
- tokens.remove(0)
326
+ ArrayUtil.remove(tokens, 0)
327
327
  end
328
328
  return [] if tokens.empty?
329
329
 
330
- token = tokens.get(tokens.size() - 1)
330
+ token = ArrayUtil.get(tokens, tokens.size() - 1)
331
331
  if token._type == AnbtSql::TokenConstants::SPACE
332
- tokens.remove(tokens.size() - 1)
332
+ ArrayUtil.remove(tokens, tokens.size() - 1)
333
333
  end
334
334
  return [] if tokens.empty?
335
335
 
@@ -361,33 +361,26 @@ class AnbtSql
361
361
  begin
362
362
  # 挿入する文字列を作成する。
363
363
  s = "\n"
364
- # もし1つ前にシングルラインコメントがあるなら、改行は不要。
365
- prevToken = tokens.get(index - 1)
366
-
367
- if (prevToken._type == AnbtSql::TokenConstants::COMMENT &&
368
- prevToken.string.startsWith("--"))
369
- s = ""
370
- end
371
364
 
372
365
  # インデントをつける。
373
366
  indent = 0 if indent < 0 ## Java版と異なる
374
367
  s += @rule.indent_string * indent
375
368
 
376
369
  # 前後にすでにスペースがあれば、それを置き換える。
377
- token = tokens.get(index)
370
+ token = ArrayUtil.get(tokens, index)
378
371
  if token._type == AnbtSql::TokenConstants::SPACE
379
372
  token.string = s
380
373
  return 0
381
374
  end
382
375
 
383
- token = tokens.get(index - 1)
376
+ token = ArrayUtil.get(tokens, index - 1)
384
377
  if token._type == AnbtSql::TokenConstants::SPACE
385
378
  token.string = s
386
379
  return 0
387
380
  end
388
381
 
389
382
  # 前後になければ、新たにスペースを追加する。
390
- tokens.add(index,
383
+ ArrayUtil.add(tokens, index,
391
384
  AnbtSql::Token.new(AnbtSql::TokenConstants::SPACE, s)
392
385
  )
393
386
  return 1
@@ -1,73 +1,59 @@
1
- require "pp"
1
+ class AnbtSql
2
+ class Stack
3
+ include Enumerable
2
4
 
3
- class Stack
4
- include Enumerable
5
-
6
- def initialize
7
- @arr = []
8
- end
9
-
10
- def each
11
- @arr.each{|item|
12
- yield item
13
- }
14
- end
15
-
16
- def clear
17
- @arr.clear
18
- end
19
-
20
- def push(o)
21
- @arr.push o
22
- end
23
-
24
- def pop
25
- @arr.pop
26
- end
27
- end
5
+ def initialize
6
+ @arr = []
7
+ end
28
8
 
9
+ def each
10
+ @arr.each{|item|
11
+ yield item
12
+ }
13
+ end
29
14
 
30
- class String
31
- def endsWith(c)
32
- self[-1] == c ? true : false
33
- end
15
+ def clear
16
+ @arr.clear
17
+ end
34
18
 
35
- def startsWith(c)
36
- self[0] == c ? true : false
37
- end
19
+ def push(o)
20
+ @arr.push o
21
+ end
38
22
 
39
- def charAt(n)
40
- self[n..n]
23
+ def pop
24
+ @arr.pop
25
+ end
41
26
  end
42
27
 
43
- def equals(str)
44
- self == str
45
- end
28
+ module StringUtil
29
+ def char_at(str, n)
30
+ if n < 0 || str.size - 1 < n
31
+ raise IndexOutOfBoundsException
32
+ end
46
33
 
47
- def equalsIgnoreCase(other)
48
- self.upcase == other.upcase
49
- end
34
+ str.slice(n, 1)
35
+ end
50
36
 
51
- def trim
52
- self.strip
37
+ def equals_ignore_case(str_a, str_b)
38
+ str_a.casecmp(str_b) == 0
39
+ end
53
40
  end
54
- end
55
41
 
42
+ module ArrayUtil
43
+ def self.remove(ary, n)
44
+ ary.delete_at n
45
+ end
56
46
 
57
- class Array
58
- def remove(n)
59
- self.delete_at n
60
- end
47
+ def self.get(ary, n)
48
+ if n < 0 || ary.size - 1 < n
49
+ raise IndexOutOfBoundsException
50
+ end
61
51
 
62
- def get(n)
63
- if n >= self.size || n <= -1
64
- raise IndexOutOfBoundsException
52
+ ary[n]
65
53
  end
66
54
 
67
- self[n]
68
- end
69
-
70
- def add(n,o)
71
- self.insert(n,o)
55
+ def self.add(ary, n, o)
56
+ ary.insert(n, o)
57
+ end
72
58
  end
73
59
  end
@@ -10,6 +10,8 @@ require "anbt-sql-formatter/coarse-tokenizer"
10
10
  class AnbtSql
11
11
  class Parser
12
12
 
13
+ include ::AnbtSql::StringUtil
14
+
13
15
  def initialize(rule)
14
16
  @rule = rule
15
17
 
@@ -26,7 +28,7 @@ class AnbtSql
26
28
 
27
29
  # 2文字からなる記号。
28
30
  # なお、|| は文字列結合にあたります。
29
- @two_character_symbol = [ "<>", "<=", ">=", "||" ]
31
+ @two_character_symbol = [ "<>", "<=", ">=", "||", "!=" ]
30
32
  end
31
33
 
32
34
 
@@ -49,7 +51,7 @@ class AnbtSql
49
51
  return false if space?(c)
50
52
  return false if digit?(c)
51
53
  return false if symbol?(c)
52
-
54
+
53
55
  true
54
56
  end
55
57
 
@@ -64,7 +66,7 @@ class AnbtSql
64
66
  # アンダースコアは記号とは扱いません
65
67
  # これ以降の文字の扱いは保留
66
68
  def symbol?(c)
67
- %w(" ? % & ' \( \) | * + , - . / : ; < = > ).include? c
69
+ %w(" ? % & ' \( \) | * + , - . / : ; < = > !).include? c
68
70
  #"
69
71
  end
70
72
 
@@ -80,35 +82,36 @@ class AnbtSql
80
82
  $stderr.puts "next_token #{@pos} <#{@before}> #{@before.length}" if $DEBUG
81
83
 
82
84
  start_pos = @pos
83
-
85
+
84
86
  if @pos >= @before.length
85
87
  @pos += 1
86
88
  return nil
87
89
  end
88
-
89
- @char = @before.charAt(@pos)
90
+
91
+ @char = char_at(@before, @pos)
90
92
 
91
93
  if space?(@char)
92
94
  workString = ""
93
- loop {
95
+ loop {
94
96
  workString += @char
95
97
 
96
- @char = @before.charAt(@pos+1)
97
- if not space?(@char)
98
- @pos += 1
99
- return AnbtSql::Token.new(AnbtSql::TokenConstants::SPACE,
100
- workString, start_pos)
98
+ is_next_char_space = false
99
+ if @pos + 1 < @before.size &&
100
+ space?(char_at(@before, @pos+1))
101
+ is_next_char_space = true
101
102
  end
102
103
 
103
- @pos += 1
104
-
105
- if @pos >= @before.length()
104
+ if not is_next_char_space
105
+ @pos += 1
106
106
  return AnbtSql::Token.new(AnbtSql::TokenConstants::SPACE,
107
- workString, start_pos)
107
+ workString, start_pos)
108
+ else
109
+ @pos += 1
110
+ next
108
111
  end
109
112
  }
110
113
 
111
-
114
+
112
115
  elsif @char == ";"
113
116
  @pos += 1
114
117
  # 2005.07.26 Tosiki Iga セミコロンは終了扱いではないようにする。
@@ -116,66 +119,51 @@ class AnbtSql
116
119
  ";", start_pos)
117
120
 
118
121
  elsif digit?(@char)
119
- if /(0x[0-9a-fA-F]+)/ =~ @before[@pos..-1] || # hex
120
- /(\d+(\.\d+(e-?\d+)?)?)/ =~ @before[@pos..-1] # float or scientific
122
+ if /^(0x[0-9a-fA-F]+)/ =~ @before[@pos..-1] || # hex
123
+ /^(\d+(\.\d+(e-?\d+)?)?)/ =~ @before[@pos..-1] # integer, float or scientific
121
124
  num = $1
122
125
  @pos += num.length
123
126
  return AnbtSql::Token.new(AnbtSql::TokenConstants::VALUE,
124
127
  num, start_pos)
128
+ else
129
+ raise "must not happen"
125
130
  end
126
131
 
127
- s = ""
128
- while (digit?(@char) || @char == '.')
129
- # if (ch == '.') type = Token.REAL
130
- s += @char
131
- @pos += 1
132
-
133
- if (@pos >= @before.length)
134
- # 長さを超えている場合には処理中断します。
135
- break
136
- end
137
-
138
- @char = @before.charAt(@pos)
139
- end
140
- return AnbtSql::Token.new(AnbtSql::TokenConstants::VALUE,
141
- s, start_pos)
142
-
143
-
144
132
  elsif letter?(@char)
145
133
  s = ""
146
134
  # 文字列中のドットについては、文字列と一体として考える。
147
- while (letter?(@char) || digit?(@char) || @char == '.')
135
+ while (letter?(@char) || digit?(@char) || @char == '.')
148
136
  s += @char
149
137
  @pos += 1
150
138
  if (@pos >= @before.length())
151
139
  break
152
140
  end
153
141
 
154
- @char = @before.charAt(@pos)
142
+ @char = char_at(@before, @pos)
155
143
  end
156
144
 
157
145
  if AnbtSql::Constants::SQL_RESERVED_WORDS.map{|w| w.upcase }.include?(s.upcase)
158
146
  return AnbtSql::Token.new(AnbtSql::TokenConstants::KEYWORD,
159
147
  s, start_pos)
160
148
  end
161
-
149
+
162
150
  return AnbtSql::Token.new(AnbtSql::TokenConstants::NAME,
163
151
  s, start_pos)
164
152
 
165
153
  elsif symbol?(@char)
166
154
  s = "" + @char
167
155
  @pos += 1
168
- if (@pos >= @before.length())
156
+ if (@pos >= @before.length())
169
157
  return AnbtSql::Token.new(AnbtSql::TokenConstants::SYMBOL,
170
158
  s, start_pos)
171
159
  end
172
160
 
173
161
  # 2文字の記号かどうか調べる
174
- ch2 = @before.charAt(@pos)
162
+ ch2 = char_at(@before, @pos)
175
163
  #for (int i = 0; i < two_character_symbol.length; i++) {
176
164
  for i in 0...@two_character_symbol.length
177
- if (@two_character_symbol[i].charAt(0) == @char &&
178
- @two_character_symbol[i].charAt(1) == ch2)
165
+ if (char_at(@two_character_symbol[i], 0) == @char &&
166
+ char_at(@two_character_symbol[i], 1) == ch2)
179
167
  @pos += 1
180
168
  s += ch2
181
169
  break
@@ -209,7 +197,7 @@ class AnbtSql
209
197
  pos = 0
210
198
  while pos < coarse_tokens.size
211
199
  coarse_token = coarse_tokens[pos]
212
-
200
+
213
201
  case coarse_token._type
214
202
 
215
203
  when :quote_single
@@ -255,10 +243,10 @@ class AnbtSql
255
243
  ##
256
244
  # 2つ以上並んだキーワードは1つのキーワードとみなします。
257
245
  # ["a", " ", "group", " ", "by", " ", "b"]
258
- # => ["a", " ", "group by", " ", "b"]
246
+ # => ["a", " ", "group by", " ", "b"]
259
247
  def concat_multiwords_keyword(tokens)
260
248
  temp_kw_list = @rule.kw_multi_words.map{|kw| kw.split(" ") }
261
-
249
+
262
250
  # ワード数が多い順から
263
251
  temp_kw_list.sort{ |a, b|
264
252
  b.size <=> a.size
@@ -270,7 +258,7 @@ class AnbtSql
270
258
  temp_tokens = tokens[index, target_tokens_size].map {|x|
271
259
  x.string.sub(/\s+/, " ")
272
260
  }
273
-
261
+
274
262
  if /#{kw.join(" ")}/i =~ temp_tokens.join
275
263
  tokens[index].string = temp_tokens.join
276
264
  (target_tokens_size-1).downto(1).each{|c|
@@ -297,28 +285,28 @@ class AnbtSql
297
285
  coarse_tokens = CoarseTokenizer.new.tokenize(sql_str)
298
286
 
299
287
  prepare_tokens(coarse_tokens)
300
-
288
+
301
289
  tokens = []
302
290
  count = 0
303
291
  @token_pos = 0
304
292
  loop {
305
293
  token = next_token()
306
-
294
+
307
295
  if $DEBUG
308
296
  pp "=" * 64, count, token, token.class
309
297
  end
310
-
298
+
311
299
  if token._type == AnbtSql::TokenConstants::END_OF_SQL
312
300
  break
313
301
  else
314
302
  ;
315
303
  end
316
-
304
+
317
305
  tokens.push token
318
306
  count += 1
319
307
  @token_pos += 1
320
308
  }
321
-
309
+
322
310
  concat_multiwords_keyword(tokens)
323
311
 
324
312
  tokens