Mercurial > hg > soundsoftware-site
diff vendor/gems/coderay-0.9.7/lib/coderay/scanners/.svn/text-base/json.rb.svn-base @ 210:0579821a129a
Update to Redmine trunk rev 4802
author | Chris Cannam |
---|---|
date | Tue, 08 Feb 2011 13:51:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/gems/coderay-0.9.7/lib/coderay/scanners/.svn/text-base/json.rb.svn-base Tue Feb 08 13:51:46 2011 +0000 @@ -0,0 +1,108 @@ +module CodeRay +module Scanners + + class JSON < Scanner + + include Streamable + + register_for :json + file_extension 'json' + + KINDS_NOT_LOC = [ + :float, :char, :content, :delimiter, + :error, :integer, :operator, :value, + ] + + ESCAPE = / [bfnrt\\"\/] /x + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x + + def scan_tokens tokens, options + + state = :initial + stack = [] + key_expected = false + + until eos? + + kind = nil + match = nil + + case state + + when :initial + if match = scan(/ \s+ | \\\n /x) + tokens << [match, :space] + next + elsif match = scan(/ [:,\[{\]}] /x) + kind = :operator + case match + when '{' then stack << :object; key_expected = true + when '[' then stack << :array + when ':' then key_expected = false + when ',' then key_expected = true if stack.last == :object + when '}', ']' then stack.pop # no error recovery, but works for valid JSON + end + elsif match = scan(/ true | false | null /x) + kind = :value + elsif match = scan(/-?(?:0|[1-9]\d*)/) + kind = :integer + if scan(/\.\d+(?:[eE][-+]?\d+)?|[eE][-+]?\d+/) + match << matched + kind = :float + end + elsif match = scan(/"/) + state = key_expected ? :key : :string + tokens << [:open, state] + kind = :delimiter + else + getch + kind = :error + end + + when :string, :key + if scan(/[^\\"]+/) + kind = :content + elsif scan(/"/) + tokens << ['"', :delimiter] + tokens << [:close, state] + state = :initial + next + elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + kind = :char + elsif scan(/\\./m) + kind = :content + elsif scan(/ \\ | $ /x) + tokens << [:close, state] + kind = :error + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), tokens + end + + else + raise_inspect 'Unknown state', tokens + + end + + match ||= matched + if $CODERAY_DEBUG and not kind + raise_inspect 'Error token %p in line %d' % + [[match, kind], line], tokens + end + raise_inspect 'Empty token', tokens unless match + + tokens << [match, kind] + + end + + if [:string, :key].include? state + tokens << [:close, state] + end + + tokens + end + + end + +end +end