tomlrb 0.1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 964937589a25e9d489b243ba7f3edcab01457109
4
- data.tar.gz: d08b833542655d0a081ef58d0dc806d1de26d0c8
3
+ metadata.gz: 0fb32099921d6d4cabb4f18af23ced18a1549769
4
+ data.tar.gz: 08adb1404068e0d263cfd71e4381306b6c74bbfd
5
5
  SHA512:
6
- metadata.gz: cfc1badba22d110b9f11d03900bff83b0e65adbba81c8242d714a26649caefdae7719fe10e086f7aa7c96283f493a56675363678c94d278bef8547b3fd23c70a
7
- data.tar.gz: 4e8b36708b34f8781aab4d70aab87d4642ae553b6e430b7f35ac193b9cdc2a409e2f83d5bf45e6a99634c0cadfb3c02bb1d5c5c1d1180c2af337fccc7436ef14
6
+ metadata.gz: 8241b67862dac85836e6b4502c5acc143bc735ae0a4bc8921c51f77817494a9f62e2bba5b2b9be564d0a3dcca29e2099062fbd03b36a3148aa661e127c6dbdc9
7
+ data.tar.gz: 1aa537c52381ee9bdca4ccfa7b4be8ec364e2483b8f1c355cc73b7eccabb75e14547b4e1b95d51e268c0c9c9cc84e7d435093bc7d10dfca59c67087cf934f9ec
data/.travis.yml CHANGED
@@ -1,3 +1,5 @@
1
1
  language: ruby
2
+ before_install:
3
+ - gem install bundler
2
4
  rvm:
3
5
  - 2.2.1
data/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Tomlrb
2
2
 
3
- A racc based [toml](https://github.com/toml-lang/toml) parser. It's still a work in progress so it doesn't support the full spec yet.
3
+ [![Code Climate](https://codeclimate.com/github/fbernier/tomlrb/badges/gpa.svg)](https://codeclimate.com/github/fbernier/tomlrb) [![Build Status](https://travis-ci.org/fbernier/tomlrb.svg)](https://travis-ci.org/fbernier/tomlrb)
4
+
5
+ A Racc based [TOML](https://github.com/toml-lang/toml) parser supporting the 0.4.0 version of the spec.
6
+
7
+
8
+ ## TODO
9
+
10
+ * Better tests
11
+ * Dumper
4
12
 
5
13
  ## Installation
6
14
 
@@ -24,6 +32,12 @@ Or install it yourself as:
24
32
  Tomlrb.parse("[toml]\na = [\"array\", 123]")
25
33
  ```
26
34
 
35
+ or
36
+
37
+ ```ruby
38
+ Tomlrb.load_file('my_file')
39
+ ```
40
+
27
41
  ## Development
28
42
 
29
43
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -37,3 +51,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
37
51
  3. Commit your changes (`git commit -am 'Add some feature'`)
38
52
  4. Push to the branch (`git push origin my-new-feature`)
39
53
  5. Create a new Pull Request
54
+
55
+ ### Thanks
56
+
57
+ Thanks to [@jpbougie](https://github.com/jpbougie) for the crash course on the Chomsky hierarchy and general tips.
@@ -10,91 +10,148 @@ module Tomlrb
10
10
  ##### State transition tables begin ###
11
11
 
12
12
  racc_action_table = [
13
- 8, 7, 7, 30, 31, 7, 11, 5, 5, 25,
14
- 24, 21, 22, 23, 15, 27, 25, 24, 21, 22,
15
- 23, 15, 27, 25, 24, 21, 22, 23, 15, 12,
16
- 13 ]
13
+ 12, 19, 10, 23, 11, 23, 29, 30, 10, 17,
14
+ 11, 18, 7, 54, 55, 9, 24, 21, 7, 21,
15
+ 15, 9, 46, 47, 48, 49, 45, 42, 41, 43,
16
+ 44, 35, 25, 26, 9, 46, 47, 48, 49, 45,
17
+ 42, 41, 43, 44, 35, 27, 32, 9, 46, 47,
18
+ 48, 49, 45, 42, 41, 43, 44, 35, 51, nil,
19
+ 9, 46, 47, 48, 49, 45, 42, 41, 43, 44,
20
+ 35, 58, nil, 9, 46, 47, 48, 49, 45, 42,
21
+ 41, 43, 44, 35, 58, 17, 9, 18, 62, nil,
22
+ nil, nil, 63, nil, nil, nil, 15 ]
17
23
 
18
24
  racc_action_check = [
19
- 1, 0, 1, 28, 28, 5, 6, 0, 1, 14,
20
- 14, 14, 14, 14, 14, 14, 31, 31, 31, 31,
21
- 31, 31, 31, 11, 11, 11, 11, 11, 11, 8,
22
- 10 ]
25
+ 1, 7, 1, 8, 1, 55, 16, 16, 0, 6,
26
+ 0, 6, 1, 31, 31, 1, 10, 8, 0, 55,
27
+ 6, 0, 24, 24, 24, 24, 24, 24, 24, 24,
28
+ 24, 24, 11, 12, 24, 25, 25, 25, 25, 25,
29
+ 25, 25, 25, 25, 25, 15, 22, 25, 32, 32,
30
+ 32, 32, 32, 32, 32, 32, 32, 32, 29, nil,
31
+ 32, 34, 34, 34, 34, 34, 34, 34, 34, 34,
32
+ 34, 34, nil, 34, 63, 63, 63, 63, 63, 63,
33
+ 63, 63, 63, 63, 63, 30, 63, 30, 59, nil,
34
+ nil, nil, 59, nil, nil, nil, 30 ]
23
35
 
24
36
  racc_action_pointer = [
25
- -1, 0, nil, nil, nil, 3, -5, nil, 29, nil,
26
- 21, 20, nil, nil, 6, nil, nil, nil, nil, nil,
27
- nil, nil, nil, nil, nil, nil, nil, nil, -6, nil,
28
- nil, 13, nil ]
37
+ 6, 0, nil, nil, nil, nil, 7, -11, 1, nil,
38
+ -2, 14, 33, nil, nil, 32, -7, nil, nil, nil,
39
+ nil, nil, 28, nil, 19, 32, nil, nil, nil, 45,
40
+ 83, -3, 45, nil, 58, nil, nil, nil, nil, nil,
41
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
42
+ nil, nil, nil, nil, nil, 3, nil, nil, nil, 75,
43
+ nil, nil, nil, 71, nil ]
29
44
 
30
45
  racc_action_default = [
31
- -25, -25, -2, -3, -4, -25, -25, -24, -25, -1,
32
- -25, -18, 33, -5, -18, -11, -13, -14, -15, -16,
33
- -17, -19, -20, -21, -22, -23, -6, -7, -25, -8,
34
- -9, -18, -10 ]
46
+ -49, -49, -2, -3, -4, -5, -49, -8, -49, -18,
47
+ -49, -49, -49, -1, -6, -10, -49, -15, -16, -7,
48
+ -17, -19, -49, -23, -39, -39, 65, -9, -11, -13,
49
+ -49, -49, -39, -25, -39, -32, -34, -35, -36, -37,
50
+ -38, -40, -41, -42, -43, -44, -45, -46, -47, -48,
51
+ -26, -12, -14, -20, -21, -49, -24, -27, -28, -49,
52
+ -22, -29, -30, -39, -31 ]
35
53
 
36
54
  racc_goto_table = [
37
- 26, 2, 9, 1, 10, 16, 29, nil, nil, nil,
38
- nil, nil, nil, nil, nil, nil, nil, 32 ]
55
+ 20, 57, 14, 33, 50, 2, 13, 5, 5, 1,
56
+ 28, 56, 31, 53, 61, nil, nil, nil, nil, nil,
57
+ nil, nil, nil, nil, nil, nil, 52, nil, nil, nil,
58
+ 64, nil, nil, nil, nil, nil, nil, nil, nil, nil,
59
+ nil, nil, nil, nil, nil, nil, nil, 60 ]
39
60
 
40
61
  racc_goto_check = [
41
- 8, 2, 2, 1, 5, 9, 10, nil, nil, nil,
42
- nil, nil, nil, nil, nil, nil, nil, 8 ]
62
+ 11, 18, 7, 15, 15, 2, 2, 5, 5, 1,
63
+ 9, 15, 13, 14, 19, nil, nil, nil, nil, nil,
64
+ nil, nil, nil, nil, nil, nil, 7, nil, nil, nil,
65
+ 18, nil, nil, nil, nil, nil, nil, nil, nil, nil,
66
+ nil, nil, nil, nil, nil, nil, nil, 11 ]
43
67
 
44
68
  racc_goto_pointer = [
45
- nil, 3, 1, nil, nil, -1, nil, nil, -14, -6,
46
- -22, nil, nil, nil, nil ]
69
+ nil, 9, 5, nil, nil, 7, nil, -4, nil, -6,
70
+ nil, -8, nil, -10, -18, -21, nil, nil, -33, -45,
71
+ nil, nil, nil, nil ]
47
72
 
48
73
  racc_goto_default = [
49
- nil, nil, nil, 3, 4, 6, 18, 14, nil, 28,
50
- nil, nil, 17, 19, 20 ]
74
+ nil, nil, nil, 3, 4, 38, 6, nil, 16, nil,
75
+ 8, nil, 22, nil, nil, 59, 37, 34, nil, nil,
76
+ nil, 36, 39, 40 ]
51
77
 
52
78
  racc_reduce_table = [
53
79
  0, 0, :racc_error,
54
- 2, 13, :_reduce_none,
55
- 1, 13, :_reduce_none,
56
- 1, 14, :_reduce_none,
57
- 1, 14, :_reduce_none,
58
- 3, 15, :_reduce_5,
59
- 2, 18, :_reduce_none,
60
- 1, 20, :_reduce_7,
61
80
  2, 20, :_reduce_none,
62
- 1, 22, :_reduce_9,
63
- 2, 22, :_reduce_none,
64
- 1, 19, :_reduce_11,
65
- 1, 23, :_reduce_none,
66
- 3, 16, :_reduce_13,
67
- 1, 21, :_reduce_14,
81
+ 1, 20, :_reduce_none,
68
82
  1, 21, :_reduce_none,
69
- 1, 24, :_reduce_none,
70
- 1, 24, :_reduce_none,
71
- 0, 26, :_reduce_none,
72
- 1, 26, :_reduce_19,
73
- 1, 26, :_reduce_20,
74
- 1, 26, :_reduce_21,
75
- 1, 26, :_reduce_none,
76
- 1, 25, :_reduce_none,
77
- 1, 17, :_reduce_none ]
78
-
79
- racc_reduce_n = 25
80
-
81
- racc_shift_n = 33
83
+ 1, 21, :_reduce_none,
84
+ 1, 21, :_reduce_none,
85
+ 2, 22, :_reduce_none,
86
+ 2, 25, :_reduce_7,
87
+ 1, 25, :_reduce_8,
88
+ 2, 26, :_reduce_9,
89
+ 1, 26, :_reduce_10,
90
+ 2, 26, :_reduce_none,
91
+ 2, 28, :_reduce_12,
92
+ 1, 28, :_reduce_13,
93
+ 2, 28, :_reduce_none,
94
+ 1, 27, :_reduce_15,
95
+ 1, 27, :_reduce_16,
96
+ 2, 24, :_reduce_none,
97
+ 1, 29, :_reduce_18,
98
+ 1, 30, :_reduce_19,
99
+ 3, 30, :_reduce_none,
100
+ 1, 33, :_reduce_21,
101
+ 2, 33, :_reduce_none,
102
+ 1, 31, :_reduce_23,
103
+ 2, 32, :_reduce_none,
104
+ 3, 23, :_reduce_25,
105
+ 3, 23, :_reduce_26,
106
+ 2, 35, :_reduce_none,
107
+ 1, 37, :_reduce_28,
108
+ 2, 37, :_reduce_none,
109
+ 1, 38, :_reduce_30,
110
+ 2, 38, :_reduce_none,
111
+ 1, 36, :_reduce_32,
112
+ 1, 39, :_reduce_none,
113
+ 1, 34, :_reduce_34,
114
+ 1, 34, :_reduce_none,
115
+ 1, 34, :_reduce_none,
116
+ 1, 40, :_reduce_none,
117
+ 1, 40, :_reduce_none,
118
+ 0, 42, :_reduce_none,
119
+ 1, 42, :_reduce_40,
120
+ 1, 42, :_reduce_41,
121
+ 1, 42, :_reduce_42,
122
+ 1, 42, :_reduce_43,
123
+ 1, 42, :_reduce_44,
124
+ 1, 41, :_reduce_45,
125
+ 1, 41, :_reduce_46,
126
+ 1, 41, :_reduce_47,
127
+ 1, 41, :_reduce_48 ]
128
+
129
+ racc_reduce_n = 49
130
+
131
+ racc_shift_n = 65
82
132
 
83
133
  racc_token_table = {
84
134
  false => 0,
85
135
  :error => 1,
86
136
  :IDENTIFIER => 2,
87
- :STRING => 3,
88
- :DATETIME => 4,
89
- :NUMBER => 5,
90
- :TRUE => 6,
91
- :FALSE => 7,
92
- "[" => 8,
93
- "]" => 9,
94
- "," => 10,
95
- "=" => 11 }
96
-
97
- racc_nt_base = 12
137
+ :STRING_MULTI => 3,
138
+ :STRING_BASIC => 4,
139
+ :STRING_LITERAL_MULTI => 5,
140
+ :STRING_LITERAL => 6,
141
+ :DATETIME => 7,
142
+ :INTEGER => 8,
143
+ :FLOAT => 9,
144
+ :TRUE => 10,
145
+ :FALSE => 11,
146
+ "[" => 12,
147
+ "]" => 13,
148
+ "." => 14,
149
+ "{" => 15,
150
+ "}" => 16,
151
+ "," => 17,
152
+ "=" => 18 }
153
+
154
+ racc_nt_base = 19
98
155
 
99
156
  racc_use_result_var = true
100
157
 
@@ -118,13 +175,20 @@ Racc_token_to_s_table = [
118
175
  "$end",
119
176
  "error",
120
177
  "IDENTIFIER",
121
- "STRING",
178
+ "STRING_MULTI",
179
+ "STRING_BASIC",
180
+ "STRING_LITERAL_MULTI",
181
+ "STRING_LITERAL",
122
182
  "DATETIME",
123
- "NUMBER",
183
+ "INTEGER",
184
+ "FLOAT",
124
185
  "TRUE",
125
186
  "FALSE",
126
187
  "\"[\"",
127
188
  "\"]\"",
189
+ "\".\"",
190
+ "\"{\"",
191
+ "\"}\"",
128
192
  "\",\"",
129
193
  "\"=\"",
130
194
  "$start",
@@ -132,11 +196,20 @@ Racc_token_to_s_table = [
132
196
  "expression",
133
197
  "table",
134
198
  "assignment",
135
- "identifier",
199
+ "inline_table",
200
+ "table_start",
201
+ "table_continued",
202
+ "table_identifier",
203
+ "table_next",
204
+ "inline_table_start",
205
+ "inline_continued",
206
+ "inline_assignment_key",
207
+ "inline_assignment_value",
208
+ "inline_next",
209
+ "value",
136
210
  "array",
137
211
  "start_array",
138
212
  "array_continued",
139
- "value",
140
213
  "array_next",
141
214
  "end_array",
142
215
  "scalar",
@@ -157,90 +230,228 @@ Racc_debug_parser = false
157
230
 
158
231
  # reduce 4 omitted
159
232
 
160
- module_eval(<<'.,.,', 'parser.y', 14)
161
- def _reduce_5(val, _values, result)
162
- @handler.set_context(val[1])
163
- result
164
- end
165
- .,.,
233
+ # reduce 5 omitted
166
234
 
167
235
  # reduce 6 omitted
168
236
 
169
- module_eval(<<'.,.,', 'parser.y', 21)
237
+ module_eval(<<'.,.,', 'parser.y', 16)
170
238
  def _reduce_7(val, _values, result)
171
- @handler.end_array
239
+ @handler.start_(:array_of_tables)
172
240
  result
173
241
  end
174
242
  .,.,
175
243
 
176
- # reduce 8 omitted
244
+ module_eval(<<'.,.,', 'parser.y', 17)
245
+ def _reduce_8(val, _values, result)
246
+ @handler.start_(:table)
247
+ result
248
+ end
249
+ .,.,
177
250
 
178
- module_eval(<<'.,.,', 'parser.y', 23)
251
+ module_eval(<<'.,.,', 'parser.y', 20)
179
252
  def _reduce_9(val, _values, result)
180
- @handler.end_array
253
+ array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true)
181
254
  result
182
255
  end
183
256
  .,.,
184
257
 
185
- # reduce 10 omitted
258
+ module_eval(<<'.,.,', 'parser.y', 21)
259
+ def _reduce_10(val, _values, result)
260
+ array = @handler.end_(:table); @handler.set_context(array)
261
+ result
262
+ end
263
+ .,.,
264
+
265
+ # reduce 11 omitted
266
+
267
+ module_eval(<<'.,.,', 'parser.y', 25)
268
+ def _reduce_12(val, _values, result)
269
+ array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true)
270
+ result
271
+ end
272
+ .,.,
186
273
 
187
274
  module_eval(<<'.,.,', 'parser.y', 26)
188
- def _reduce_11(val, _values, result)
189
- @handler.start_array
275
+ def _reduce_13(val, _values, result)
276
+ array = @handler.end_(:table); @handler.set_context(array)
190
277
  result
191
278
  end
192
279
  .,.,
193
280
 
194
- # reduce 12 omitted
281
+ # reduce 14 omitted
195
282
 
196
283
  module_eval(<<'.,.,', 'parser.y', 30)
197
- def _reduce_13(val, _values, result)
198
- @handler.assign(val[0])
284
+ def _reduce_15(val, _values, result)
285
+ @handler.push(val[0])
199
286
  result
200
287
  end
201
288
  .,.,
202
289
 
203
- module_eval(<<'.,.,', 'parser.y', 34)
204
- def _reduce_14(val, _values, result)
290
+ module_eval(<<'.,.,', 'parser.y', 31)
291
+ def _reduce_16(val, _values, result)
205
292
  @handler.push(val[0])
206
293
  result
207
294
  end
208
295
  .,.,
209
296
 
210
- # reduce 15 omitted
297
+ # reduce 17 omitted
211
298
 
212
- # reduce 16 omitted
299
+ module_eval(<<'.,.,', 'parser.y', 37)
300
+ def _reduce_18(val, _values, result)
301
+ @handler.start_(:inline)
302
+ result
303
+ end
304
+ .,.,
213
305
 
214
- # reduce 17 omitted
306
+ module_eval(<<'.,.,', 'parser.y', 40)
307
+ def _reduce_19(val, _values, result)
308
+ array = @handler.end_(:inline); @handler.push(Hash[*array])
309
+ result
310
+ end
311
+ .,.,
215
312
 
216
- # reduce 18 omitted
313
+ # reduce 20 omitted
217
314
 
218
315
  module_eval(<<'.,.,', 'parser.y', 44)
219
- def _reduce_19(val, _values, result)
220
- n = val[0]; result = n.count('.') > 0 ? n.to_f : n.to_i
316
+ def _reduce_21(val, _values, result)
317
+ array = @handler.end_(:inline); @handler.push(Hash[*array])
318
+ result
319
+ end
320
+ .,.,
321
+
322
+ # reduce 22 omitted
323
+
324
+ module_eval(<<'.,.,', 'parser.y', 48)
325
+ def _reduce_23(val, _values, result)
326
+ @handler.push(val[0])
327
+ result
328
+ end
329
+ .,.,
330
+
331
+ # reduce 24 omitted
332
+
333
+ module_eval(<<'.,.,', 'parser.y', 54)
334
+ def _reduce_25(val, _values, result)
335
+ @handler.assign(val[0])
336
+ result
337
+ end
338
+ .,.,
339
+
340
+ module_eval(<<'.,.,', 'parser.y', 55)
341
+ def _reduce_26(val, _values, result)
342
+ @handler.assign(val[0])
343
+ result
344
+ end
345
+ .,.,
346
+
347
+ # reduce 27 omitted
348
+
349
+ module_eval(<<'.,.,', 'parser.y', 61)
350
+ def _reduce_28(val, _values, result)
351
+ array = @handler.end_(:array); @handler.push(array)
352
+ result
353
+ end
354
+ .,.,
355
+
356
+ # reduce 29 omitted
357
+
358
+ module_eval(<<'.,.,', 'parser.y', 65)
359
+ def _reduce_30(val, _values, result)
360
+ array = @handler.end_(:array); @handler.push(array)
361
+ result
362
+ end
363
+ .,.,
364
+
365
+ # reduce 31 omitted
366
+
367
+ module_eval(<<'.,.,', 'parser.y', 69)
368
+ def _reduce_32(val, _values, result)
369
+ @handler.start_(:array)
370
+ result
371
+ end
372
+ .,.,
373
+
374
+ # reduce 33 omitted
375
+
376
+ module_eval(<<'.,.,', 'parser.y', 75)
377
+ def _reduce_34(val, _values, result)
378
+ @handler.push(val[0])
379
+ result
380
+ end
381
+ .,.,
382
+
383
+ # reduce 35 omitted
384
+
385
+ # reduce 36 omitted
386
+
387
+ # reduce 37 omitted
388
+
389
+ # reduce 38 omitted
390
+
391
+ # reduce 39 omitted
392
+
393
+ module_eval(<<'.,.,', 'parser.y', 84)
394
+ def _reduce_40(val, _values, result)
395
+ result = val[0].to_f
396
+ result
397
+ end
398
+ .,.,
399
+
400
+ module_eval(<<'.,.,', 'parser.y', 85)
401
+ def _reduce_41(val, _values, result)
402
+ result = val[0].to_i
221
403
  result
222
404
  end
223
405
  .,.,
224
406
 
225
- module_eval(<<'.,.,', 'parser.y', 45)
226
- def _reduce_20(val, _values, result)
407
+ module_eval(<<'.,.,', 'parser.y', 86)
408
+ def _reduce_42(val, _values, result)
227
409
  result = true
228
410
  result
229
411
  end
230
412
  .,.,
231
413
 
232
- module_eval(<<'.,.,', 'parser.y', 46)
233
- def _reduce_21(val, _values, result)
414
+ module_eval(<<'.,.,', 'parser.y', 87)
415
+ def _reduce_43(val, _values, result)
234
416
  result = false
235
417
  result
236
418
  end
237
419
  .,.,
238
420
 
239
- # reduce 22 omitted
421
+ module_eval(<<'.,.,', 'parser.y', 88)
422
+ def _reduce_44(val, _values, result)
423
+ result = Time.parse(val[0])
424
+ result
425
+ end
426
+ .,.,
427
+
428
+ module_eval(<<'.,.,', 'parser.y', 91)
429
+ def _reduce_45(val, _values, result)
430
+ result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0]))
431
+ result
432
+ end
433
+ .,.,
240
434
 
241
- # reduce 23 omitted
435
+ module_eval(<<'.,.,', 'parser.y', 92)
436
+ def _reduce_46(val, _values, result)
437
+ result = StringUtils.replace_escaped_chars(val[0])
438
+ result
439
+ end
440
+ .,.,
242
441
 
243
- # reduce 24 omitted
442
+ module_eval(<<'.,.,', 'parser.y', 93)
443
+ def _reduce_47(val, _values, result)
444
+ result = StringUtils.replace_escaped_chars(StringUtils.strip_spaces(val[0]))
445
+ result
446
+ end
447
+ .,.,
448
+
449
+ module_eval(<<'.,.,', 'parser.y', 94)
450
+ def _reduce_48(val, _values, result)
451
+ result = StringUtils.strip_spaces(val[0])
452
+ result
453
+ end
454
+ .,.,
244
455
 
245
456
  def _reduce_none(val, _values, result)
246
457
  val[0]
@@ -1,42 +1,61 @@
1
1
  module Tomlrb
2
2
  class Handler
3
- attr_reader :stack
3
+ attr_reader :output
4
4
 
5
5
  def initialize
6
- @output = Hash.new {|h, k| h[k] = {} }
6
+ @output = {}
7
7
  @current = @output
8
8
  @stack = []
9
9
  end
10
10
 
11
- def set_context(name)
12
- @current = @output[name]
13
- @context = name
14
- end
11
+ def set_context(identifierz, is_array_of_tables: false)
12
+ @current = @output
15
13
 
16
- def assign(k)
17
- @current[k] = @stack.pop
14
+ deal_with_array_of_table(identifierz, is_array_of_tables) do |identifiers|
15
+ identifiers.each do |k|
16
+ if @current[k].is_a?(Array)
17
+ @current[k] << {} if @current[k].empty?
18
+ @current = @current[k].last
19
+ else
20
+ @current[k] ||= {}
21
+ @current = @current[k]
22
+ end
23
+ end
24
+ end
18
25
  end
19
26
 
20
- def start_array
21
- push [:array]
22
- end
27
+ def deal_with_array_of_table(identifiers, is_array_of_tables)
28
+ identifiers.map!{|n| n.gsub("\"", '')}
29
+ last_identifier = identifiers.pop if is_array_of_tables
23
30
 
24
- def end_array
25
- array = []
26
- while (value = @stack.pop) != [:array]
27
- raise if value.nil?
28
- array.unshift(value)
31
+ yield(identifiers)
32
+
33
+ if is_array_of_tables
34
+ @current[last_identifier] ||= []
35
+ @current[last_identifier] << {}
36
+ @current = @current[last_identifier].last
29
37
  end
30
- push(array)
38
+ end
39
+
40
+ def assign(k)
41
+ @current[k] = @stack.pop
31
42
  end
32
43
 
33
44
  def push(o)
34
45
  @stack << o
35
46
  end
36
47
 
37
- def result
38
- @output
48
+ def start_(type)
49
+ push([type])
39
50
  end
40
51
 
52
+ def end_(type)
53
+ array = []
54
+ while (value = @stack.pop) != [type]
55
+ raise if value.nil?
56
+ array.unshift(value)
57
+ end
58
+ array
59
+ end
41
60
  end
42
61
  end
data/lib/tomlrb/parser.rb CHANGED
@@ -1,10 +1,10 @@
1
+ require "tomlrb/generated_parser"
2
+
1
3
  class Tomlrb::Parser < Tomlrb::GeneratedParser
2
- attr_reader :handler
3
4
 
4
5
  def initialize(tokenizer, handler = Tomlrb::Handler.new)
5
6
  @tokenizer = tokenizer
6
7
  @handler = handler
7
- @yydebug = true
8
8
  super()
9
9
  end
10
10
 
@@ -14,6 +14,6 @@ class Tomlrb::Parser < Tomlrb::GeneratedParser
14
14
 
15
15
  def parse
16
16
  do_parse
17
- handler
17
+ @handler
18
18
  end
19
19
  end
data/lib/tomlrb/parser.y CHANGED
@@ -1,57 +1,96 @@
1
1
  class Tomlrb::GeneratedParser
2
- token IDENTIFIER STRING DATETIME NUMBER TRUE FALSE
2
+ token IDENTIFIER STRING_MULTI STRING_BASIC STRING_LITERAL_MULTI STRING_LITERAL DATETIME INTEGER FLOAT TRUE FALSE
3
3
  rule
4
4
  expressions
5
5
  : expressions expression
6
6
  | expression
7
7
  ;
8
-
9
8
  expression
10
9
  : table
11
10
  | assignment
11
+ | inline_table
12
12
  ;
13
-
14
13
  table
15
- : '[' identifier ']' { @handler.set_context(val[1]) }
14
+ : table_start table_continued
15
+ ;
16
+ table_start
17
+ : '[' '[' { @handler.start_(:array_of_tables) }
18
+ | '[' { @handler.start_(:table) }
19
+ ;
20
+ table_continued
21
+ : ']' ']' { array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) }
22
+ | ']' { array = @handler.end_(:table); @handler.set_context(array) }
23
+ | table_identifier table_next
24
+ ;
25
+ table_next
26
+ : ']' ']' { array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) }
27
+ | ']' { array = @handler.end_(:table); @handler.set_context(array) }
28
+ | '.' table_continued
29
+ ;
30
+ table_identifier
31
+ : IDENTIFIER { @handler.push(val[0]) }
32
+ | STRING_BASIC { @handler.push(val[0]) }
33
+ ;
34
+ inline_table
35
+ : inline_table_start inline_continued
36
+ ;
37
+ inline_table_start
38
+ : '{' { @handler.start_(:inline) }
39
+ ;
40
+ inline_continued
41
+ : '}' { array = @handler.end_(:inline); @handler.push(Hash[*array]) }
42
+ | inline_assignment_key inline_assignment_value inline_next
43
+ ;
44
+ inline_next
45
+ : '}' { array = @handler.end_(:inline); @handler.push(Hash[*array]) }
46
+ | ',' inline_continued
47
+ ;
48
+ inline_assignment_key
49
+ : IDENTIFIER { @handler.push(val[0]) }
50
+ ;
51
+ inline_assignment_value
52
+ : '=' value
53
+ ;
54
+ assignment
55
+ : IDENTIFIER '=' value { @handler.assign(val[0]) }
56
+ | STRING_BASIC '=' value { @handler.assign(val[0]) }
16
57
  ;
17
-
18
58
  array
19
59
  : start_array array_continued
20
60
  ;
21
-
22
- array_continued : ']' { @handler.end_array }
23
- | value array_next;
24
- array_next : ']' { @handler.end_array }
25
- | ',' array_continued;
26
-
27
- start_array : '[' { @handler.start_array }
28
- end_array : ']'
29
-
30
- assignment
31
- : identifier '=' value { @handler.assign(val[0]) }
61
+ array_continued
62
+ : ']' { array = @handler.end_(:array); @handler.push(array) }
63
+ | value array_next
64
+ ;
65
+ array_next
66
+ : ']' { array = @handler.end_(:array); @handler.push(array) }
67
+ | ',' array_continued
68
+ ;
69
+ start_array
70
+ : '[' { @handler.start_(:array) }
71
+ ;
72
+ end_array
73
+ : ']'
32
74
  ;
33
-
34
75
  value
35
76
  : scalar { @handler.push(val[0]) }
36
77
  | array
78
+ | inline_table
37
79
  ;
38
-
39
80
  scalar
40
81
  : string
41
82
  | literal
42
83
  ;
43
-
44
84
  literal
45
- | NUMBER { n = val[0]; result = n.count('.') > 0 ? n.to_f : n.to_i }
85
+ | FLOAT { result = val[0].to_f }
86
+ | INTEGER { result = val[0].to_i }
46
87
  | TRUE { result = true }
47
88
  | FALSE { result = false }
48
- | DATETIME
89
+ | DATETIME { result = Time.parse(val[0]) }
49
90
  ;
50
-
51
91
  string
52
- : STRING
53
- ;
54
-
55
- identifier:
56
- : IDENTIFIER
92
+ : STRING_MULTI { result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) }
93
+ | STRING_BASIC { result = StringUtils.replace_escaped_chars(val[0]) }
94
+ | STRING_LITERAL_MULTI { result = StringUtils.replace_escaped_chars(StringUtils.strip_spaces(val[0])) }
95
+ | STRING_LITERAL { result = StringUtils.strip_spaces(val[0]) }
57
96
  ;
@@ -2,12 +2,16 @@ require 'strscan'
2
2
 
3
3
  module Tomlrb
4
4
  class Scanner
5
- IDENTIFIER = /\w+/
6
- SPACES = /\A\s+/
7
- STRING_SINGLE = /"[^"]*"/
8
- STRING_MULTI = /"[^"]*"/
5
+ COMMENT = /#.+/
6
+ IDENTIFIER = /[A-Za-z0-9_-]+/
7
+ SPACE = /[ \t\r\n]/
8
+ STRING_BASIC = /(["])(?:\\?.)*?\1/
9
+ STRING_MULTI = /"{3}([\s\S]*?"{3})/m
10
+ STRING_LITERAL = /(['])(?:\\?.)*?\1/
11
+ STRING_LITERAL_MULTI = /'{3}([\s\S]*?'{3})/m
9
12
  DATETIME = /(-?\d{4})-(\d{2})-(\d{2})(?:t|\s)(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(z|[-+]\d{2}:\d{2})/i
10
- NUMBER = /[0-9]+(?:\.[0-9]+)?/
13
+ FLOAT = /[+-]?(?:[0-9_]+\.[0-9_]*|\.[0-9_]+|\d+(?=[eE]))(?:[eE][+-]?[0-9_]+)?/
14
+ INTEGER = /[+-]?\d(_?\d)*/
11
15
  TRUE = /true/
12
16
  FALSE = /false/
13
17
 
@@ -19,10 +23,15 @@ module Tomlrb
19
23
  return if @ss.eos?
20
24
 
21
25
  case
22
- when @ss.scan(SPACES) then next_token
26
+ when @ss.scan(SPACE) then next_token
27
+ when @ss.scan(COMMENT) then next_token
23
28
  when text = @ss.scan(DATETIME) then [:DATETIME, text]
24
- when text = @ss.scan(STRING_SINGLE) then [:STRING, text[1..-2]]
25
- when text = @ss.scan(NUMBER) then [:NUMBER, text]
29
+ when text = @ss.scan(STRING_MULTI) then [:STRING_MULTI, text[3..-4]]
30
+ when text = @ss.scan(STRING_BASIC) then [:STRING_BASIC, text[1..-2]]
31
+ when text = @ss.scan(STRING_LITERAL_MULTI) then [:STRING_LITERAL_MULTI, text[3..-4]]
32
+ when text = @ss.scan(STRING_LITERAL) then [:STRING_LITERAL, text[1..-2]]
33
+ when text = @ss.scan(FLOAT) then [:FLOAT, text]
34
+ when text = @ss.scan(INTEGER) then [:INTEGER, text]
26
35
  when text = @ss.scan(TRUE) then [:TRUE, text]
27
36
  when text = @ss.scan(FALSE) then [:FALSE, text]
28
37
  when text = @ss.scan(IDENTIFIER) then [:IDENTIFIER, text]
@@ -0,0 +1,23 @@
1
+ module Tomlrb
2
+ class StringUtils
3
+
4
+ def self.multiline_replacements(str)
5
+ strip_spaces(str).gsub(/\\\n\s+/, '')
6
+ end
7
+
8
+ def self.replace_escaped_chars(str)
9
+ str
10
+ .gsub(/\\n/, "\n")
11
+ .gsub(/\\0/, "\0")
12
+ .gsub(/\\t/, "\t")
13
+ .gsub(/\\r/, "\r")
14
+ .gsub(/\\\"/, '"')
15
+ .gsub(/\\\\/, '\\')
16
+ end
17
+
18
+ def self.strip_spaces(str)
19
+ str[0] = '' if str[0] == "\n"
20
+ str
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Tomlrb
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.1"
3
3
  end
data/lib/tomlrb.rb CHANGED
@@ -1,15 +1,21 @@
1
+ require 'time'
2
+ require 'stringio'
1
3
  require "tomlrb/version"
2
- require "tomlrb/generated_parser"
4
+ require 'tomlrb/string_utils'
3
5
  require "tomlrb/scanner"
4
6
  require "tomlrb/parser"
5
7
  require "tomlrb/handler"
6
8
 
7
9
  module Tomlrb
8
- def self.parse(string_or_io)
10
+ def self.parse(string_or_io, **options)
9
11
  io = string_or_io.is_a?(String) ? StringIO.new(string_or_io) : string_or_io
10
12
  scanner = Scanner.new(io)
11
13
  parser = Parser.new(scanner)
12
14
  handler = parser.parse
13
- handler.result
15
+ handler.output
16
+ end
17
+
18
+ def self.load_file(path, **options)
19
+ Tomlrb.parse(File.read(path), options)
14
20
  end
15
21
  end
data/tomlrb.gemspec CHANGED
@@ -24,4 +24,6 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "pry"
25
25
  spec.add_development_dependency "pry-byebug"
26
26
  spec.add_development_dependency "racc"
27
+ spec.add_development_dependency "minitest"
28
+ spec.add_development_dependency "minitest-reporters"
27
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tomlrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francois Bernier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-04-09 00:00:00.000000000 Z
11
+ date: 2015-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-reporters
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: A racc based toml parser
84
112
  email:
85
113
  - frankbernier@gmail.com
@@ -101,8 +129,8 @@ files:
101
129
  - lib/tomlrb/parser.rb
102
130
  - lib/tomlrb/parser.y
103
131
  - lib/tomlrb/scanner.rb
132
+ - lib/tomlrb/string_utils.rb
104
133
  - lib/tomlrb/version.rb
105
- - sample.toml
106
134
  - tomlrb.gemspec
107
135
  homepage: ''
108
136
  licenses:
data/sample.toml DELETED
@@ -1,47 +0,0 @@
1
- # This is a TOML document. Boom.
2
-
3
- title = "TOML Example"
4
-
5
- [owner]
6
- name = "Tom Preston-Werner"
7
- organization = "GitHub"
8
- bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
9
- dob = 1979-05-27T07:32:00Z # First class dates? Why not?
10
-
11
- [database]
12
- server = "192.168.1.1"
13
- ports = [ 8001, 8001, 8002 ]
14
- connection_max = 5000
15
- enabled = true
16
-
17
- [servers]
18
-
19
- # You can indent as you please. Tabs or spaces. TOML don't care.
20
- [servers.alpha]
21
- ip = "10.0.0.1"
22
- dc = "eqdc10"
23
-
24
- [servers.beta]
25
- ip = "10.0.0.2"
26
- dc = "eqdc10"
27
- country = "中国" # This should be parsed as UTF-8
28
-
29
- [clients]
30
- data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
31
-
32
- # Line breaks are OK when inside arrays
33
- hosts = [
34
- "alpha",
35
- "omega"
36
- ]
37
-
38
- # Products
39
-
40
- [[products]]
41
- name = "Hammer"
42
- sku = 738594937
43
-
44
- [[products]]
45
- name = "Nail"
46
- sku = 284758393
47
- color = "gray"