tomlrb 0.1.0 → 1.0.1

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.
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"