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