Mercurial > hg > soundsoftware-site
comparison 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 |
comparison
equal
deleted
inserted
replaced
128:07fa8a8b56a8 | 210:0579821a129a |
---|---|
1 module CodeRay | |
2 module Scanners | |
3 | |
4 class JSON < Scanner | |
5 | |
6 include Streamable | |
7 | |
8 register_for :json | |
9 file_extension 'json' | |
10 | |
11 KINDS_NOT_LOC = [ | |
12 :float, :char, :content, :delimiter, | |
13 :error, :integer, :operator, :value, | |
14 ] | |
15 | |
16 ESCAPE = / [bfnrt\\"\/] /x | |
17 UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x | |
18 | |
19 def scan_tokens tokens, options | |
20 | |
21 state = :initial | |
22 stack = [] | |
23 key_expected = false | |
24 | |
25 until eos? | |
26 | |
27 kind = nil | |
28 match = nil | |
29 | |
30 case state | |
31 | |
32 when :initial | |
33 if match = scan(/ \s+ | \\\n /x) | |
34 tokens << [match, :space] | |
35 next | |
36 elsif match = scan(/ [:,\[{\]}] /x) | |
37 kind = :operator | |
38 case match | |
39 when '{' then stack << :object; key_expected = true | |
40 when '[' then stack << :array | |
41 when ':' then key_expected = false | |
42 when ',' then key_expected = true if stack.last == :object | |
43 when '}', ']' then stack.pop # no error recovery, but works for valid JSON | |
44 end | |
45 elsif match = scan(/ true | false | null /x) | |
46 kind = :value | |
47 elsif match = scan(/-?(?:0|[1-9]\d*)/) | |
48 kind = :integer | |
49 if scan(/\.\d+(?:[eE][-+]?\d+)?|[eE][-+]?\d+/) | |
50 match << matched | |
51 kind = :float | |
52 end | |
53 elsif match = scan(/"/) | |
54 state = key_expected ? :key : :string | |
55 tokens << [:open, state] | |
56 kind = :delimiter | |
57 else | |
58 getch | |
59 kind = :error | |
60 end | |
61 | |
62 when :string, :key | |
63 if scan(/[^\\"]+/) | |
64 kind = :content | |
65 elsif scan(/"/) | |
66 tokens << ['"', :delimiter] | |
67 tokens << [:close, state] | |
68 state = :initial | |
69 next | |
70 elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) | |
71 kind = :char | |
72 elsif scan(/\\./m) | |
73 kind = :content | |
74 elsif scan(/ \\ | $ /x) | |
75 tokens << [:close, state] | |
76 kind = :error | |
77 state = :initial | |
78 else | |
79 raise_inspect "else case \" reached; %p not handled." % peek(1), tokens | |
80 end | |
81 | |
82 else | |
83 raise_inspect 'Unknown state', tokens | |
84 | |
85 end | |
86 | |
87 match ||= matched | |
88 if $CODERAY_DEBUG and not kind | |
89 raise_inspect 'Error token %p in line %d' % | |
90 [[match, kind], line], tokens | |
91 end | |
92 raise_inspect 'Empty token', tokens unless match | |
93 | |
94 tokens << [match, kind] | |
95 | |
96 end | |
97 | |
98 if [:string, :key].include? state | |
99 tokens << [:close, state] | |
100 end | |
101 | |
102 tokens | |
103 end | |
104 | |
105 end | |
106 | |
107 end | |
108 end |