class CodeRay::Scanners::SQL
by Josh Goebel
def scan_tokens encoder, options
def scan_tokens encoder, options state = :initial string_type = nil string_content = '' name_expected = false until eos? if state == :initial if match = scan(/ \s+ | \\\n /x) encoder.text_token match, :space elsif match = scan(/(?:--\s?|#).*/) encoder.text_token match, :comment elsif match = scan(%r( /\* (!)? (?: .*? \*/ | .* ) )mx) encoder.text_token match, self[1] ? :directive : :comment elsif match = scan(/ [*\/=<>:;,!&^|()\[\]{}~%] | [-+\.](?!\d) /x) name_expected = true if match == '.' && check(/[A-Za-z_]/) encoder.text_token match, :operator elsif match = scan(/(#{STRING_PREFIXES})?([`"'])/o) prefix = self[1] string_type = self[2] encoder.begin_group :string encoder.text_token prefix, :modifier if prefix match = string_type state = :string encoder.text_token match, :delimiter elsif match = scan(/ @? [A-Za-z_][A-Za-z_0-9]* /x) encoder.text_token match, name_expected ? :ident : (match[0] == ?@ ? :variable : IDENT_KIND[match]) name_expected = false elsif match = scan(/0[xX][0-9A-Fa-f]+/) encoder.text_token match, :hex elsif match = scan(/0[0-7]+(?![89.eEfF])/) encoder.text_token match, :octal elsif match = scan(/[-+]?(?>\d+)(?![.eEfF])/) encoder.text_token match, :integer elsif match = scan(/[-+]?(?:\d[fF]|\d*\.\d+(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+)/) encoder.text_token match, :float elsif match = scan(/\\N/) encoder.text_token match, :predefined_constant else encoder.text_token getch, :error end elsif state == :string if match = scan(/[^\\"'`]+/) string_content << match next elsif match = scan(/["'`]/) if string_type == match if peek(1) == string_type # doubling means escape string_content << string_type << getch next end unless string_content.empty? encoder.text_token string_content, :content string_content = '' end encoder.text_token match, :delimiter encoder.end_group :string state = :initial string_type = nil else string_content << match end elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) unless string_content.empty? encoder.text_token string_content, :content string_content = '' end encoder.text_token match, :char elsif match = scan(/ \\ . /mox) string_content << match next elsif match = scan(/ \\ | $ /x) unless string_content.empty? encoder.text_token string_content, :content string_content = '' end encoder.text_token match, :error state = :initial else raise "else case \" reached; %p not handled." % peek(1), encoder end else raise 'else-case reached', encoder end end if state == :string encoder.end_group state end encoder end