rison 1.0.0

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.
data/COPYING.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2007 Tim Fletcher <tfletcher.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.html ADDED
@@ -0,0 +1,43 @@
1
+ <html>
2
+ <head>
3
+ <title>rison.rubyforge.org</title>
4
+ <style type="text/css" media="screen">
5
+ html {
6
+ height: 100%; margin-bottom: 1px;
7
+ }
8
+ body {
9
+ margin: 0; padding: 30px;
10
+ }
11
+ h1, h2 {
12
+ font-family: garamond;
13
+ }
14
+ code {
15
+ font-family: "Panic Sans", "Bitstream Vera Sans Mono", Consolas, Monaco, monospace;
16
+ }
17
+ </style>
18
+ </head>
19
+ <body>
20
+
21
+
22
+ <h1>rison<span style="color:#F99">.rb</span></h1>
23
+
24
+ <h2>Examples</h2>
25
+
26
+ <pre><code> require 'rison'
27
+
28
+ Rison.load('!t') # => true
29
+
30
+ Rison.load('!(1,2,3)') # => [1, 2, 3]
31
+
32
+ Rison.load('(a:0)') # => {'a' => 0}
33
+ </code></pre>
34
+
35
+ <h2>Links</h2>
36
+
37
+ <p><a href="http://mjtemplate.org/examples/rison.html">Rison - Compact Data in URIs</a></p>
38
+
39
+ <p><a href="http://dhaka.rubyforge.org/">Dhaka</a></p>
40
+
41
+
42
+ </body>
43
+ </html>
data/Rakefile.rb ADDED
@@ -0,0 +1,73 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/gempackagetask'
4
+
5
+
6
+ GEMSPEC = Gem::Specification.new do |s|
7
+ s.name = 'rison'
8
+ s.version = '1.0.0'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.has_rdoc = false
11
+ s.summary = 'Pure Ruby parser for Rison (http://mjtemplate.org/examples/rison.html)'
12
+ s.description = s.summary
13
+ s.author = 'Tim Fletcher'
14
+ s.email = 'twoggle@gmail.com'
15
+ s.homepage = 'http://rison.rubyforge.org/'
16
+ s.files = Dir.glob('{lib,test}/**/*') + %w( COPYING.txt Rakefile.rb README.html )
17
+ s.require_paths = ['lib']
18
+ s.add_dependency 'dhaka'
19
+ end
20
+
21
+
22
+ Rake::GemPackageTask.new(GEMSPEC) { }
23
+
24
+
25
+ Rake::PackageTask.new(GEMSPEC.name, GEMSPEC.version) do |p|
26
+ p.need_tar_gz = true
27
+ p.package_files.include GEMSPEC.files
28
+ end
29
+
30
+
31
+ desc 'Run all the tests'
32
+ Rake::TestTask.new do |t|
33
+ t.verbose = true
34
+ t.ruby_opts = ['-rubygems']
35
+ end
36
+
37
+
38
+ task :parse_stdin do
39
+ $:.unshift 'lib'
40
+
41
+ require 'rison'
42
+ require 'pp'
43
+
44
+ pp Rison.load($stdin.read.chomp)
45
+ end
46
+
47
+
48
+ task :reinstall do
49
+ sh 'sudo gem uninstall rison dhaka'
50
+ sh 'sudo gem install pkg/rison-%s.gem' % GEMSPEC.version
51
+ end
52
+
53
+
54
+ desc 'Regenerate the compiled parser'
55
+ task :regen do
56
+ $:.unshift 'lib'
57
+
58
+ require 'rison/grammar'
59
+ require 'dhaka'
60
+
61
+ parser = Dhaka::Parser.new(Rison::Grammar)
62
+
63
+ source = [
64
+ "require 'dhaka'",
65
+ "require 'rison/grammar'",
66
+ '',
67
+ 'module Rison',
68
+ parser.compile_to_ruby_source_as(:Parser).gsub(/^/, ' '),
69
+ 'end'
70
+ ]
71
+
72
+ File.open('lib/rison/parser.rb', 'w+') { |f| f.puts source * "\n" }
73
+ end
@@ -0,0 +1,169 @@
1
+ require 'dhaka'
2
+ require 'rison/grammar'
3
+
4
+ module Rison
5
+ class Evaluator < Dhaka::Evaluator
6
+
7
+ self.grammar = Grammar
8
+
9
+ define_evaluation_rules do
10
+
11
+ for_empty_object do
12
+ {}
13
+ end
14
+
15
+ for_non_empty_object do
16
+ evaluate(child_nodes[1])
17
+ end
18
+
19
+ for_member_pair do
20
+ evaluate(child_nodes[0])
21
+ end
22
+
23
+ for_member_pairs do
24
+ evaluate(child_nodes[2]).merge(evaluate(child_nodes[0]))
25
+ end
26
+
27
+ for_pair_key_value do
28
+ { evaluate(child_nodes[0]) => evaluate(child_nodes[2]) }
29
+ end
30
+
31
+ for_empty_array do
32
+ []
33
+ end
34
+
35
+ for_non_empty_array do
36
+ evaluate(child_nodes[2])
37
+ end
38
+
39
+ for_element_value do
40
+ [ evaluate(child_nodes[0]) ]
41
+ end
42
+
43
+ for_element_values do
44
+ [ evaluate(child_nodes[0]) ] + evaluate(child_nodes[2])
45
+ end
46
+
47
+ # for_key_id do
48
+
49
+ # for_key_string do
50
+
51
+ # for_value_id do
52
+
53
+ # for_value_string
54
+
55
+ # for_value_number do
56
+
57
+ # for_value_object do
58
+
59
+ # for_value_array do
60
+
61
+ for_value_true do
62
+ true
63
+ end
64
+
65
+ for_value_false do
66
+ false
67
+ end
68
+
69
+ for_value_null do
70
+ nil
71
+ end
72
+
73
+ # for_id_idstart
74
+
75
+ for_id_idstart_idchars do
76
+ evaluate(child_nodes[0]) + evaluate(child_nodes[1])
77
+ end
78
+
79
+ # for_idchars_idchar
80
+
81
+ for_idchars_idchars do
82
+ evaluate(child_nodes[0]) + evaluate(child_nodes[1])
83
+ end
84
+
85
+ for_idchars_int do
86
+ evaluate(child_nodes[0]).to_s
87
+ end
88
+
89
+ for_idchar_char do
90
+ child_nodes[0].token.value
91
+ end
92
+
93
+ for_idstart_char do
94
+ child_nodes[0].token.value
95
+ end
96
+
97
+ for_empty_string do
98
+ ''
99
+ end
100
+
101
+ for_non_empty_string do
102
+ evaluate(child_nodes[1]).inject { |s, c| s + c }
103
+ end
104
+
105
+ for_strchars_char do
106
+ [ evaluate(child_nodes[0]) ]
107
+ end
108
+
109
+ for_strchars_chars do
110
+ [ evaluate(child_nodes[0]) ] + evaluate(child_nodes[1])
111
+ end
112
+
113
+ for_strchar_char do
114
+ child_nodes[0].token.value
115
+ end
116
+
117
+ for_strchar_quoted_exclamation do
118
+ '!'
119
+ end
120
+
121
+ for_strchar_quoted_single_quote do
122
+ "'"
123
+ end
124
+
125
+ for_strchar_num do
126
+ evaluate(child_nodes[0]).to_s
127
+ end
128
+
129
+ for_number_int do
130
+ evaluate(child_nodes[0])
131
+ end
132
+
133
+ for_number_int_frac do
134
+ evaluate(child_nodes[0]) + evaluate(child_nodes[1])
135
+ end
136
+
137
+ for_number_int_exp do
138
+ evaluate(child_nodes[0]) * evaluate(child_nodes[1])
139
+ end
140
+
141
+ for_number_int_frac_exp do
142
+ (evaluate(child_nodes[0]) + evaluate(child_nodes[1])) * evaluate(child_nodes[2])
143
+ end
144
+
145
+ for_integer_literal do
146
+ token = child_nodes[0].token.value
147
+ token =~ /^(-?)(\d+?)$/
148
+
149
+ $1.empty?? $2.to_i : - $2.to_i
150
+ end
151
+
152
+ for_frac_literal do
153
+ token = child_nodes[0].token.value
154
+ token =~ /^\.(\d+?)$/
155
+
156
+ Rational($1.to_i, 10 ** $1.length)
157
+ end
158
+
159
+ for_exponent_literal do
160
+ token = child_nodes[0].token.value
161
+ token =~ /^e(-?)(\d+?)$/
162
+
163
+ 10 ** ($1.empty?? $2.to_i : - $2.to_i)
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+ end
@@ -0,0 +1,112 @@
1
+ require 'dhaka'
2
+
3
+ module Rison
4
+ class Grammar < Dhaka::Grammar
5
+
6
+ for_symbol(Dhaka::START_SYMBOL_NAME) do
7
+ start %w| value |
8
+ end
9
+
10
+ for_symbol 'object' do
11
+ empty_object %w| ( ) |
12
+ non_empty_object %w| ( members ) |
13
+ end
14
+
15
+ for_symbol 'members' do
16
+ member_pair %w| pair |
17
+ member_pairs %w| pair , members |
18
+ end
19
+
20
+ for_symbol 'pair' do
21
+ pair_key_value %w| key : value |
22
+ end
23
+
24
+ for_symbol 'array' do
25
+ empty_array %w| ! ( ) |
26
+ non_empty_array %w| ! ( elements ) |
27
+ end
28
+
29
+ for_symbol 'elements' do
30
+ element_value %w| value |
31
+ element_values %w| value , elements |
32
+ end
33
+
34
+ for_symbol 'key' do
35
+ key_id %w| id |
36
+ key_string %w| string |
37
+ end
38
+
39
+ for_symbol 'value' do
40
+ value_id %w| id |
41
+ value_string %w| string |
42
+ value_number %w| number |
43
+ value_object %w| object |
44
+ value_array %w| array |
45
+ value_true %w| !t |
46
+ value_false %w| !f |
47
+ value_null %w| !n |
48
+ end
49
+
50
+ for_symbol 'id' do
51
+ id_idstart %w| idstart |
52
+ id_idstart_idchars %w| idstart idchars |
53
+ end
54
+
55
+ for_symbol 'idchars' do
56
+ idchars_idchar %w| idchar |
57
+ idchars_idchars %w| idchar idchars |
58
+ idchars_int %w| int |
59
+ end
60
+
61
+ for_symbol 'idchar' do
62
+ # any Unicode character not in '!:(),*@$
63
+ idchar_char %w| char_token |
64
+ end
65
+
66
+ for_symbol 'idstart' do
67
+ # any Unicode character not in -, digit, or idchar
68
+ idstart_char %w| char_token |
69
+ end
70
+
71
+ for_symbol 'string' do
72
+ empty_string %w| ' ' |
73
+ non_empty_string %w| ' strchars ' |
74
+ end
75
+
76
+ for_symbol 'strchars' do
77
+ strchars_char %w| strchar |
78
+ strchars_chars %w| strchar strchars |
79
+ end
80
+
81
+ for_symbol 'strchar' do
82
+ # any Unicode character not in ' or !
83
+ # !!
84
+ # !'
85
+ strchar_char %w| char_token |
86
+ strchar_quoted_exclamation %w| !! |
87
+ strchar_quoted_single_quote %w| !' |
88
+ strchar_num %w| number |
89
+ end
90
+
91
+ for_symbol 'number' do
92
+ number_int %w| int |
93
+ number_int_frac %w| int frac |
94
+ number_int_exp %w| int exp |
95
+ number_int_frac_exp %w| int frac exp |
96
+ end
97
+
98
+ for_symbol 'int' do
99
+ integer_literal %w| integer_token |
100
+ end
101
+
102
+ for_symbol 'frac' do
103
+ frac_literal %w| frac_token |
104
+ end
105
+
106
+ for_symbol 'exp' do
107
+ exponent_literal %w| exponent_token |
108
+ end
109
+
110
+ end
111
+ end
112
+
@@ -0,0 +1,30 @@
1
+ require 'dhaka'
2
+
3
+ module Rison
4
+ class LexerSpec < Dhaka::LexerSpecification
5
+
6
+ [ ['!!', nil],
7
+ ["!'", nil],
8
+ ['!t', nil],
9
+ ['!f', nil],
10
+ ['!n', nil],
11
+
12
+ ['\(', '('],
13
+ ['\)', ')'],
14
+ ['!', '!'],
15
+
16
+ [',', nil],
17
+ [':', nil],
18
+ ["'", nil],
19
+
20
+ ['e-?\d+', 'exponent_token'],
21
+ ['\.\d+', 'frac_token'],
22
+ ['-?\d+', 'integer_token'],
23
+ ['.', 'char_token']
24
+
25
+ ].each do |(pattern, token)|
26
+ for_pattern(pattern) { create_token(token || pattern) }
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,340 @@
1
+ require 'dhaka'
2
+ require 'rison/grammar'
3
+
4
+ module Rison
5
+ class Parser < Dhaka::CompiledParser
6
+
7
+ self.grammar = Rison::Grammar
8
+
9
+ start_with 0
10
+
11
+ at_state(44) {
12
+ for_symbols(",", "_End_", ")") { reduce_with "value_false" }
13
+ }
14
+
15
+ at_state(31) {
16
+ for_symbols("integer_token") { shift_to 6 }
17
+ for_symbols("!") { shift_to 11 }
18
+ for_symbols("!t") { shift_to 33 }
19
+ for_symbols("array") { shift_to 10 }
20
+ for_symbols("number") { shift_to 45 }
21
+ for_symbols("'") { shift_to 34 }
22
+ for_symbols("string") { shift_to 9 }
23
+ for_symbols("object") { shift_to 46 }
24
+ for_symbols("id") { shift_to 15 }
25
+ for_symbols("!f") { shift_to 44 }
26
+ for_symbols("!n") { shift_to 1 }
27
+ for_symbols("char_token") { shift_to 16 }
28
+ for_symbols("idstart") { shift_to 2 }
29
+ for_symbols("int") { shift_to 18 }
30
+ for_symbols("value") { shift_to 32 }
31
+ for_symbols("(") { shift_to 24 }
32
+ }
33
+
34
+ at_state(19) {
35
+ for_symbols("!!", ",", "integer_token", "!'", "'", "_End_", ")", "char_token") { reduce_with "exponent_literal" }
36
+ }
37
+
38
+ at_state(7) {
39
+ for_symbols(",", ":", "_End_", ")") { reduce_with "idchars_idchars" }
40
+ }
41
+
42
+ at_state(3) {
43
+ for_symbols("idchar") { shift_to 3 }
44
+ for_symbols("integer_token") { shift_to 6 }
45
+ for_symbols("idchars") { shift_to 7 }
46
+ for_symbols("int") { shift_to 5 }
47
+ for_symbols("char_token") { shift_to 4 }
48
+ for_symbols(",", ":", "_End_", ")") { reduce_with "idchars_idchar" }
49
+ }
50
+
51
+ at_state(50) {
52
+ for_symbols(",", "_End_", ")") { reduce_with "empty_array" }
53
+ }
54
+
55
+ at_state(49) {
56
+ for_symbols(",", "_End_", ")") { reduce_with "empty_object" }
57
+ }
58
+
59
+ at_state(48) {
60
+ for_symbols(",", "_End_", ")") { reduce_with "non_empty_object" }
61
+ }
62
+
63
+ at_state(45) {
64
+ for_symbols(",", "_End_", ")") { reduce_with "value_number" }
65
+ }
66
+
67
+ at_state(40) {
68
+ for_symbols("!!", "integer_token", "!'", "'", "char_token") { reduce_with "strchar_num" }
69
+ }
70
+
71
+ at_state(27) {
72
+ for_symbols("id") { shift_to 29 }
73
+ for_symbols("key") { shift_to 30 }
74
+ for_symbols("'") { shift_to 34 }
75
+ for_symbols("members") { shift_to 28 }
76
+ for_symbols("char_token") { shift_to 16 }
77
+ for_symbols("pair") { shift_to 26 }
78
+ for_symbols("idstart") { shift_to 2 }
79
+ for_symbols("string") { shift_to 25 }
80
+ }
81
+
82
+ at_state(24) {
83
+ for_symbols(")") { shift_to 49 }
84
+ for_symbols("id") { shift_to 29 }
85
+ for_symbols("members") { shift_to 47 }
86
+ for_symbols("key") { shift_to 30 }
87
+ for_symbols("'") { shift_to 34 }
88
+ for_symbols("char_token") { shift_to 16 }
89
+ for_symbols("pair") { shift_to 26 }
90
+ for_symbols("idstart") { shift_to 2 }
91
+ for_symbols("string") { shift_to 25 }
92
+ }
93
+
94
+ at_state(18) {
95
+ for_symbols("exponent_token") { shift_to 19 }
96
+ for_symbols("exp") { shift_to 23 }
97
+ for_symbols("frac") { shift_to 21 }
98
+ for_symbols("!!", ",", "integer_token", "!'", "'", "_End_", "char_token", ")") { reduce_with "number_int" }
99
+ for_symbols("frac_token") { shift_to 20 }
100
+ }
101
+
102
+ at_state(8) {
103
+ for_symbols(",", ":", "_End_", ")") { reduce_with "id_idstart_idchars" }
104
+ }
105
+
106
+ at_state(4) {
107
+ for_symbols(",", "integer_token", ":", "_End_", "char_token", ")") { reduce_with "idchar_char" }
108
+ }
109
+
110
+ at_state(32) {
111
+ for_symbols(",", ")") { reduce_with "pair_key_value" }
112
+ }
113
+
114
+ at_state(14) {
115
+ for_symbols("value") { shift_to 13 }
116
+ for_symbols("integer_token") { shift_to 6 }
117
+ for_symbols("!") { shift_to 11 }
118
+ for_symbols("!t") { shift_to 33 }
119
+ for_symbols("array") { shift_to 10 }
120
+ for_symbols("number") { shift_to 45 }
121
+ for_symbols("'") { shift_to 34 }
122
+ for_symbols("string") { shift_to 9 }
123
+ for_symbols("object") { shift_to 46 }
124
+ for_symbols("id") { shift_to 15 }
125
+ for_symbols("!f") { shift_to 44 }
126
+ for_symbols("!n") { shift_to 1 }
127
+ for_symbols("char_token") { shift_to 16 }
128
+ for_symbols("idstart") { shift_to 2 }
129
+ for_symbols("int") { shift_to 18 }
130
+ for_symbols("elements") { shift_to 17 }
131
+ for_symbols("(") { shift_to 24 }
132
+ }
133
+
134
+ at_state(2) {
135
+ for_symbols("idchar") { shift_to 3 }
136
+ for_symbols("integer_token") { shift_to 6 }
137
+ for_symbols("int") { shift_to 5 }
138
+ for_symbols(",", ":", "_End_", ")") { reduce_with "id_idstart" }
139
+ for_symbols("char_token") { shift_to 4 }
140
+ for_symbols("idchars") { shift_to 8 }
141
+ }
142
+
143
+ at_state(47) {
144
+ for_symbols(")") { shift_to 48 }
145
+ }
146
+
147
+ at_state(35) {
148
+ for_symbols("!!", "integer_token", "!'", "'", "char_token") { reduce_with "strchar_quoted_single_quote" }
149
+ }
150
+
151
+ at_state(29) {
152
+ for_symbols(":") { reduce_with "key_id" }
153
+ }
154
+
155
+ at_state(21) {
156
+ for_symbols("exp") { shift_to 22 }
157
+ for_symbols("exponent_token") { shift_to 19 }
158
+ for_symbols("!!", ",", "integer_token", "!'", "'", "_End_", "char_token", ")") { reduce_with "number_int_frac" }
159
+ }
160
+
161
+ at_state(16) {
162
+ for_symbols(",", "integer_token", ":", "_End_", "char_token", ")") { reduce_with "idstart_char" }
163
+ }
164
+
165
+ at_state(10) {
166
+ for_symbols(",", "_End_", ")") { reduce_with "value_array" }
167
+ }
168
+
169
+ at_state(9) {
170
+ for_symbols(",", "_End_", ")") { reduce_with "value_string" }
171
+ }
172
+
173
+ at_state(17) {
174
+ for_symbols(")") { reduce_with "element_values" }
175
+ }
176
+
177
+ at_state(0) {
178
+ for_symbols("integer_token") { shift_to 6 }
179
+ for_symbols("!") { shift_to 11 }
180
+ for_symbols("!t") { shift_to 33 }
181
+ for_symbols("array") { shift_to 10 }
182
+ for_symbols("number") { shift_to 45 }
183
+ for_symbols("'") { shift_to 34 }
184
+ for_symbols("string") { shift_to 9 }
185
+ for_symbols("object") { shift_to 46 }
186
+ for_symbols("id") { shift_to 15 }
187
+ for_symbols("!f") { shift_to 44 }
188
+ for_symbols("!n") { shift_to 1 }
189
+ for_symbols("char_token") { shift_to 16 }
190
+ for_symbols("idstart") { shift_to 2 }
191
+ for_symbols("int") { shift_to 18 }
192
+ for_symbols("(") { shift_to 24 }
193
+ for_symbols("value") { shift_to 53 }
194
+ }
195
+
196
+ at_state(38) {
197
+ for_symbols("'") { reduce_with "strchars_chars" }
198
+ }
199
+
200
+ at_state(34) {
201
+ for_symbols("integer_token") { shift_to 6 }
202
+ for_symbols("char_token") { shift_to 39 }
203
+ for_symbols("strchar") { shift_to 36 }
204
+ for_symbols("number") { shift_to 40 }
205
+ for_symbols("!'") { shift_to 35 }
206
+ for_symbols("'") { shift_to 43 }
207
+ for_symbols("int") { shift_to 18 }
208
+ for_symbols("!!") { shift_to 37 }
209
+ for_symbols("strchars") { shift_to 41 }
210
+ }
211
+
212
+ at_state(26) {
213
+ for_symbols(")") { reduce_with "member_pair" }
214
+ for_symbols(",") { shift_to 27 }
215
+ }
216
+
217
+ at_state(5) {
218
+ for_symbols(",", ":", "_End_", ")") { reduce_with "idchars_int" }
219
+ }
220
+
221
+ at_state(53) {
222
+ for_symbols("_End_") { reduce_with "start" }
223
+ }
224
+
225
+ at_state(52) {
226
+ for_symbols(",", "_End_", ")") { reduce_with "non_empty_array" }
227
+ }
228
+
229
+ at_state(46) {
230
+ for_symbols(",", "_End_", ")") { reduce_with "value_object" }
231
+ }
232
+
233
+ at_state(41) {
234
+ for_symbols("'") { shift_to 42 }
235
+ }
236
+
237
+ at_state(37) {
238
+ for_symbols("!!", "integer_token", "!'", "'", "char_token") { reduce_with "strchar_quoted_exclamation" }
239
+ }
240
+
241
+ at_state(25) {
242
+ for_symbols(":") { reduce_with "key_string" }
243
+ }
244
+
245
+ at_state(22) {
246
+ for_symbols("!!", ",", "integer_token", "!'", "'", "_End_", "char_token", ")") { reduce_with "number_int_frac_exp" }
247
+ }
248
+
249
+ at_state(13) {
250
+ for_symbols(")") { reduce_with "element_value" }
251
+ for_symbols(",") { shift_to 14 }
252
+ }
253
+
254
+ at_state(51) {
255
+ for_symbols(")") { shift_to 52 }
256
+ }
257
+
258
+ at_state(43) {
259
+ for_symbols(",", ":", "_End_", ")") { reduce_with "empty_string" }
260
+ }
261
+
262
+ at_state(42) {
263
+ for_symbols(",", ":", "_End_", ")") { reduce_with "non_empty_string" }
264
+ }
265
+
266
+ at_state(39) {
267
+ for_symbols("!!", "integer_token", "!'", "'", "char_token") { reduce_with "strchar_char" }
268
+ }
269
+
270
+ at_state(33) {
271
+ for_symbols(",", "_End_", ")") { reduce_with "value_true" }
272
+ }
273
+
274
+ at_state(36) {
275
+ for_symbols("integer_token") { shift_to 6 }
276
+ for_symbols("char_token") { shift_to 39 }
277
+ for_symbols("'") { reduce_with "strchars_char" }
278
+ for_symbols("strchar") { shift_to 36 }
279
+ for_symbols("number") { shift_to 40 }
280
+ for_symbols("!'") { shift_to 35 }
281
+ for_symbols("int") { shift_to 18 }
282
+ for_symbols("!!") { shift_to 37 }
283
+ for_symbols("strchars") { shift_to 38 }
284
+ }
285
+
286
+ at_state(30) {
287
+ for_symbols(":") { shift_to 31 }
288
+ }
289
+
290
+ at_state(12) {
291
+ for_symbols("value") { shift_to 13 }
292
+ for_symbols("elements") { shift_to 51 }
293
+ for_symbols("integer_token") { shift_to 6 }
294
+ for_symbols("!") { shift_to 11 }
295
+ for_symbols("!t") { shift_to 33 }
296
+ for_symbols("array") { shift_to 10 }
297
+ for_symbols("number") { shift_to 45 }
298
+ for_symbols("'") { shift_to 34 }
299
+ for_symbols("string") { shift_to 9 }
300
+ for_symbols("object") { shift_to 46 }
301
+ for_symbols("id") { shift_to 15 }
302
+ for_symbols("!f") { shift_to 44 }
303
+ for_symbols("!n") { shift_to 1 }
304
+ for_symbols("char_token") { shift_to 16 }
305
+ for_symbols("idstart") { shift_to 2 }
306
+ for_symbols("int") { shift_to 18 }
307
+ for_symbols(")") { shift_to 50 }
308
+ for_symbols("(") { shift_to 24 }
309
+ }
310
+
311
+ at_state(11) {
312
+ for_symbols("(") { shift_to 12 }
313
+ }
314
+
315
+ at_state(6) {
316
+ for_symbols("!!", "frac_token", ",", "integer_token", ":", "!'", "'", "_End_", "char_token", ")", "exponent_token") { reduce_with "integer_literal" }
317
+ }
318
+
319
+ at_state(1) {
320
+ for_symbols(",", "_End_", ")") { reduce_with "value_null" }
321
+ }
322
+
323
+ at_state(28) {
324
+ for_symbols(")") { reduce_with "member_pairs" }
325
+ }
326
+
327
+ at_state(23) {
328
+ for_symbols("!!", ",", "integer_token", "!'", "'", "_End_", ")", "char_token") { reduce_with "number_int_exp" }
329
+ }
330
+
331
+ at_state(20) {
332
+ for_symbols("!!", ",", "integer_token", "!'", "'", "_End_", "char_token", ")", "exponent_token") { reduce_with "frac_literal" }
333
+ }
334
+
335
+ at_state(15) {
336
+ for_symbols(",", "_End_", ")") { reduce_with "value_id" }
337
+ }
338
+
339
+ end
340
+ end
data/lib/rison.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'dhaka'
2
+ require 'rison/lexer'
3
+ require 'rison/parser'
4
+ require 'rison/evaluator'
5
+
6
+ module Rison
7
+
8
+ def self.load(data)
9
+ evaluate(parse(lex(data)))
10
+ end
11
+
12
+
13
+ LEXER = Dhaka::Lexer.new(LexerSpec)
14
+
15
+ EVALUATOR = Evaluator.new
16
+
17
+ def self.lex(data)
18
+ LEXER.lex(data.to_s)
19
+ end
20
+
21
+ def self.parse(lexed)
22
+ Parser.parse(lexed)
23
+ end
24
+
25
+ def self.evaluate(parsed)
26
+ EVALUATOR.evaluate(parsed)
27
+ end
28
+
29
+ end
@@ -0,0 +1,122 @@
1
+ require 'test/unit'
2
+ require 'rison'
3
+
4
+ class RisonTests < Test::Unit::TestCase
5
+
6
+ def rison(string)
7
+ parsed = Rison.parse(Rison.lex(string))
8
+
9
+ if parsed.has_error?
10
+ p parsed
11
+ end
12
+
13
+ Rison.evaluate(parsed)
14
+ end
15
+
16
+ # cf. http://mjtemplate.org/examples/rison.html
17
+
18
+ def test_true
19
+ assert_equal true, rison('!t')
20
+ end
21
+
22
+ def test_false
23
+ assert_equal false, rison('!f')
24
+ end
25
+
26
+ def test_null
27
+ assert_equal nil, rison('!n')
28
+ end
29
+
30
+ def test_empty_string
31
+ assert_equal '', rison(%{''})
32
+ end
33
+
34
+ def test_zero
35
+ assert_equal 0, rison('0')
36
+ end
37
+
38
+ def test_positive_integer
39
+ assert_equal 1, rison('1')
40
+ assert_equal 12, rison('12')
41
+ end
42
+
43
+ def test_negative_integer
44
+ assert_equal -3, rison('-3')
45
+ assert_equal -33, rison('-33')
46
+ end
47
+
48
+ def test_rational
49
+ assert_equal Rational(3, 2), rison('1.5')
50
+ assert_equal Rational(9999, 100), rison('99.99')
51
+ end
52
+
53
+ def test_positive_exponent
54
+ assert_equal 10**30, rison('1e30')
55
+ end
56
+
57
+ def test_negative_exponent
58
+ assert_equal 10**-30, rison('1e-30')
59
+ end
60
+
61
+ def test_fraction_and_exponent
62
+ assert_equal 150, rison('1.5e2')
63
+ end
64
+
65
+ def test_single_character
66
+ assert_equal 'a', rison('a')
67
+ end
68
+
69
+ def test_string_with_leading_digit
70
+ assert_equal '0a', rison("'0a'")
71
+ end
72
+
73
+ def test_unquoted_string
74
+ assert_equal 'abc def', rison('abc def')
75
+ end
76
+
77
+ def test_empty_object
78
+ assert_equal Hash.new, rison('()')
79
+ end
80
+
81
+ def test_non_empty_objects
82
+ expected = {'a' => 0}
83
+ assert_equal expected, rison('(a:0)')
84
+
85
+ expected = {'id' => nil, 'type' => '/common/document'}
86
+ assert_equal expected, rison('(id:!n,type:/common/document)')
87
+ end
88
+
89
+ def test_empty_array
90
+ assert_equal [], rison('!()')
91
+ end
92
+
93
+ def test_array
94
+ assert_equal [ true, false, nil, '' ], rison(%{!(!t,!f,!n,'')})
95
+ end
96
+
97
+ def test_unquoted_string_with_leading_minus
98
+ assert_equal '-h', rison('-h')
99
+ end
100
+
101
+ def test_unquoted_string_with_minus
102
+ assert_equal 'a-z', rison('a-z')
103
+ end
104
+
105
+ def test_domain_name
106
+ assert_equal 'domain.com', rison('domain.com')
107
+ end
108
+
109
+ def test_email
110
+ assert_equal 'user@domain.com', rison('user@domain.com')
111
+ end
112
+
113
+ def test_money
114
+ assert_equal 'US $10', rison('US $10')
115
+ end
116
+
117
+ def test_quoting
118
+ assert_equal "can't", rison("'can!'t'")
119
+ assert_equal 'wow!', rison("'wow!!'")
120
+ end
121
+
122
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4.7
3
+ specification_version: 2
4
+ name: rison
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-11-18 00:00:00 +00:00
8
+ summary: Pure Ruby parser for Rison (http://mjtemplate.org/examples/rison.html)
9
+ require_paths:
10
+ - lib
11
+ email: twoggle@gmail.com
12
+ homepage: http://rison.rubyforge.org/
13
+ rubyforge_project:
14
+ description: Pure Ruby parser for Rison (http://mjtemplate.org/examples/rison.html)
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ required_rubygems_version: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: "0"
30
+ version:
31
+ platform: ruby
32
+ signing_key:
33
+ cert_chain: []
34
+
35
+ post_install_message:
36
+ authors:
37
+ - Tim Fletcher
38
+ files:
39
+ - lib/rison
40
+ - lib/rison/evaluator.rb
41
+ - lib/rison/grammar.rb
42
+ - lib/rison/lexer.rb
43
+ - lib/rison/parser.rb
44
+ - lib/rison.rb
45
+ - test/test_rison.rb
46
+ - COPYING.txt
47
+ - Rakefile.rb
48
+ - README.html
49
+ test_files: []
50
+
51
+ rdoc_options: []
52
+
53
+ extra_rdoc_files: []
54
+
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ requirements: []
60
+
61
+ dependencies:
62
+ - !ruby/object:Gem::Dependency
63
+ name: dhaka
64
+ version_requirement:
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version: