hcl-checker 1.0.6 → 1.4.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.
- checksums.yaml +5 -5
- data/Gemfile +10 -0
- data/Gemfile.lock +28 -27
- data/README.md +6 -8
- data/assets/lexer.rex +1 -1
- data/assets/parse.y +10 -2
- data/hcl-checker.gemspec +29 -5
- data/lib/hcl/checker/version.rb +1 -1
- data/lib/hcl/lexer.rb +87 -86
- data/lib/hcl/parser.rb +123 -89
- data/lib/hcl1/checker.rb +21 -0
- data/lib/hcl1/checker/version.rb +5 -0
- data/lib/hcl1/lexer.rb +175 -0
- data/lib/hcl1/parser.rb +456 -0
- metadata +42 -16
data/lib/hcl/parser.rb
CHANGED
@@ -10,7 +10,7 @@ require_relative './lexer'
|
|
10
10
|
|
11
11
|
class HCLParser < Racc::Parser
|
12
12
|
|
13
|
-
module_eval(<<'...end parse.y/module_eval...', 'parse.y',
|
13
|
+
module_eval(<<'...end parse.y/module_eval...', 'parse.y', 123)
|
14
14
|
#//
|
15
15
|
#// HCL is unclear on what one should do when duplicate
|
16
16
|
#// keys are encountered.
|
@@ -21,7 +21,7 @@ module_eval(<<'...end parse.y/module_eval...', 'parse.y', 115)
|
|
21
21
|
#// from object.go: there is a flattened list structure
|
22
22
|
#//
|
23
23
|
def flatten_objectlist(list)
|
24
|
-
list.each_with_object({}) do |a, h|
|
24
|
+
(list || {}).each_with_object({}) do |a, h|
|
25
25
|
h[a.first] =
|
26
26
|
case a.last
|
27
27
|
when Hash
|
@@ -69,45 +69,47 @@ module_eval(<<'...end parse.y/module_eval...', 'parse.y', 115)
|
|
69
69
|
##### State transition tables begin ###
|
70
70
|
|
71
71
|
racc_action_table = [
|
72
|
-
|
73
|
-
|
74
|
-
5,
|
75
|
-
|
72
|
+
22, 28, 27, 10, 28, 27, 5, 23, 6, 14,
|
73
|
+
35, 26, 14, 12, 26, 32, 28, 27, 40, 5,
|
74
|
+
-10, 6, 35, 5, 14, 6, 26, 39, 30, 5,
|
75
|
+
-11, 6, 13, 17, 38, 18, 19, 14, 20 ]
|
76
76
|
|
77
77
|
racc_action_check = [
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
6,
|
78
|
+
13, 13, 13, 1, 26, 26, 0, 13, 0, 13,
|
79
|
+
26, 13, 26, 4, 26, 26, 40, 40, 31, 3,
|
80
|
+
5, 3, 40, 14, 40, 14, 40, 31, 14, 29,
|
81
|
+
6, 29, 7, 9, 29, 9, 10, 9, 11 ]
|
82
82
|
|
83
83
|
racc_action_pointer = [
|
84
|
-
-1,
|
85
|
-
|
86
|
-
nil, nil, nil, nil,
|
87
|
-
nil, nil, nil, nil, nil, nil,
|
84
|
+
-1, 3, nil, 12, 8, 12, 22, 24, nil, 26,
|
85
|
+
36, 33, nil, -2, 16, nil, nil, nil, nil, nil,
|
86
|
+
nil, nil, nil, nil, nil, nil, 1, nil, nil, 22,
|
87
|
+
nil, 13, nil, nil, nil, nil, nil, nil, nil, nil,
|
88
|
+
13, nil ]
|
88
89
|
|
89
90
|
racc_action_default = [
|
90
|
-
-2, -
|
91
|
-
-
|
92
|
-
|
93
|
-
-
|
91
|
+
-2, -33, -1, -3, -5, -20, -21, -33, -17, -33,
|
92
|
+
-33, -7, -4, -33, -33, -18, -19, -20, -21, 42,
|
93
|
+
-6, -12, -13, -14, -15, -16, -33, -31, -32, -33,
|
94
|
+
-9, -33, -23, -24, -27, -28, -29, -30, -8, -22,
|
95
|
+
-26, -25 ]
|
94
96
|
|
95
97
|
racc_goto_table = [
|
96
|
-
11, 3,
|
97
|
-
|
98
|
-
nil, nil, nil, nil, 11 ]
|
98
|
+
11, 3, 33, 15, 1, 2, 21, 24, 25, 16,
|
99
|
+
31, nil, nil, nil, nil, 29, 41, nil, nil, nil,
|
100
|
+
nil, nil, nil, nil, nil, nil, 11 ]
|
99
101
|
|
100
102
|
racc_goto_check = [
|
101
|
-
4, 3,
|
102
|
-
|
103
|
-
nil, nil, nil, nil, 4 ]
|
103
|
+
4, 3, 12, 5, 1, 2, 7, 5, 8, 9,
|
104
|
+
11, nil, nil, nil, nil, 3, 12, nil, nil, nil,
|
105
|
+
nil, nil, nil, nil, nil, nil, 4 ]
|
104
106
|
|
105
107
|
racc_goto_pointer = [
|
106
|
-
nil,
|
107
|
-
nil, -
|
108
|
+
nil, 4, 5, 1, -3, -6, nil, -7, -5, 0,
|
109
|
+
nil, -16, -24 ]
|
108
110
|
|
109
111
|
racc_goto_default = [
|
110
|
-
nil, nil, nil, nil, 4,
|
112
|
+
nil, nil, nil, nil, 4, 37, 7, 34, 36, 8,
|
111
113
|
9, nil, nil ]
|
112
114
|
|
113
115
|
racc_reduce_table = [
|
@@ -115,35 +117,39 @@ racc_reduce_table = [
|
|
115
117
|
1, 19, :_reduce_1,
|
116
118
|
0, 20, :_reduce_2,
|
117
119
|
1, 20, :_reduce_none,
|
118
|
-
|
119
|
-
|
120
|
-
3,
|
121
|
-
2,
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
120
|
+
2, 21, :_reduce_4,
|
121
|
+
1, 21, :_reduce_5,
|
122
|
+
3, 21, :_reduce_6,
|
123
|
+
2, 21, :_reduce_7,
|
124
|
+
3, 23, :_reduce_8,
|
125
|
+
2, 23, :_reduce_9,
|
126
|
+
1, 24, :_reduce_10,
|
127
|
+
1, 24, :_reduce_11,
|
126
128
|
3, 22, :_reduce_12,
|
127
129
|
3, 22, :_reduce_13,
|
128
130
|
3, 22, :_reduce_14,
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
1,
|
142
|
-
1,
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
131
|
+
3, 22, :_reduce_15,
|
132
|
+
3, 22, :_reduce_16,
|
133
|
+
1, 22, :_reduce_17,
|
134
|
+
2, 27, :_reduce_18,
|
135
|
+
2, 27, :_reduce_19,
|
136
|
+
1, 28, :_reduce_20,
|
137
|
+
1, 28, :_reduce_21,
|
138
|
+
3, 26, :_reduce_22,
|
139
|
+
2, 26, :_reduce_23,
|
140
|
+
1, 29, :_reduce_24,
|
141
|
+
3, 29, :_reduce_25,
|
142
|
+
2, 29, :_reduce_26,
|
143
|
+
1, 30, :_reduce_27,
|
144
|
+
1, 30, :_reduce_28,
|
145
|
+
1, 30, :_reduce_29,
|
146
|
+
1, 30, :_reduce_30,
|
147
|
+
1, 25, :_reduce_31,
|
148
|
+
1, 25, :_reduce_32 ]
|
149
|
+
|
150
|
+
racc_reduce_n = 33
|
151
|
+
|
152
|
+
racc_shift_n = 42
|
147
153
|
|
148
154
|
racc_token_table = {
|
149
155
|
false => 0,
|
@@ -249,49 +255,49 @@ module_eval(<<'.,.,', 'parse.y', 29)
|
|
249
255
|
|
250
256
|
module_eval(<<'.,.,', 'parse.y', 31)
|
251
257
|
def _reduce_5(val, _values, result)
|
252
|
-
result = val[0]
|
258
|
+
result = [val[0]]
|
253
259
|
result
|
254
260
|
end
|
255
261
|
.,.,
|
256
262
|
|
257
|
-
module_eval(<<'.,.,', 'parse.y',
|
263
|
+
module_eval(<<'.,.,', 'parse.y', 33)
|
258
264
|
def _reduce_6(val, _values, result)
|
259
|
-
result =
|
265
|
+
result = val[0] << val[1]
|
260
266
|
result
|
261
267
|
end
|
262
268
|
.,.,
|
263
269
|
|
264
|
-
module_eval(<<'.,.,', 'parse.y',
|
270
|
+
module_eval(<<'.,.,', 'parse.y', 35)
|
265
271
|
def _reduce_7(val, _values, result)
|
266
|
-
|
272
|
+
result = val[0] << val[1]
|
267
273
|
result
|
268
274
|
end
|
269
275
|
.,.,
|
270
276
|
|
271
|
-
module_eval(<<'.,.,', 'parse.y',
|
277
|
+
module_eval(<<'.,.,', 'parse.y', 40)
|
272
278
|
def _reduce_8(val, _values, result)
|
273
|
-
result = val[
|
279
|
+
result = flatten_objectlist(val[1])
|
274
280
|
result
|
275
281
|
end
|
276
282
|
.,.,
|
277
283
|
|
278
|
-
module_eval(<<'.,.,', 'parse.y',
|
284
|
+
module_eval(<<'.,.,', 'parse.y', 42)
|
279
285
|
def _reduce_9(val, _values, result)
|
280
|
-
|
286
|
+
return
|
281
287
|
result
|
282
288
|
end
|
283
289
|
.,.,
|
284
290
|
|
285
|
-
module_eval(<<'.,.,', 'parse.y',
|
291
|
+
module_eval(<<'.,.,', 'parse.y', 47)
|
286
292
|
def _reduce_10(val, _values, result)
|
287
|
-
result = val[0]
|
293
|
+
result = val[0]
|
288
294
|
result
|
289
295
|
end
|
290
296
|
.,.,
|
291
297
|
|
292
|
-
module_eval(<<'.,.,', 'parse.y',
|
298
|
+
module_eval(<<'.,.,', 'parse.y', 49)
|
293
299
|
def _reduce_11(val, _values, result)
|
294
|
-
result = val[0]
|
300
|
+
result = val[0]
|
295
301
|
result
|
296
302
|
end
|
297
303
|
.,.,
|
@@ -319,102 +325,130 @@ module_eval(<<'.,.,', 'parse.y', 58)
|
|
319
325
|
|
320
326
|
module_eval(<<'.,.,', 'parse.y', 60)
|
321
327
|
def _reduce_15(val, _values, result)
|
322
|
-
result = val[0]
|
328
|
+
result = val[0], val[2]
|
323
329
|
result
|
324
330
|
end
|
325
331
|
.,.,
|
326
332
|
|
327
|
-
module_eval(<<'.,.,', 'parse.y',
|
333
|
+
module_eval(<<'.,.,', 'parse.y', 62)
|
328
334
|
def _reduce_16(val, _values, result)
|
329
|
-
result = val[0], val[
|
335
|
+
result = val[0], val[2]
|
330
336
|
result
|
331
337
|
end
|
332
338
|
.,.,
|
333
339
|
|
334
|
-
module_eval(<<'.,.,', 'parse.y',
|
340
|
+
module_eval(<<'.,.,', 'parse.y', 64)
|
335
341
|
def _reduce_17(val, _values, result)
|
336
|
-
result = val[0]
|
342
|
+
result = val[0]
|
337
343
|
result
|
338
344
|
end
|
339
345
|
.,.,
|
340
346
|
|
341
|
-
module_eval(<<'.,.,', 'parse.y',
|
347
|
+
module_eval(<<'.,.,', 'parse.y', 69)
|
342
348
|
def _reduce_18(val, _values, result)
|
343
|
-
result = val[0]
|
349
|
+
result = val[0], val[1]
|
344
350
|
result
|
345
351
|
end
|
346
352
|
.,.,
|
347
353
|
|
348
|
-
module_eval(<<'.,.,', 'parse.y',
|
354
|
+
module_eval(<<'.,.,', 'parse.y', 71)
|
349
355
|
def _reduce_19(val, _values, result)
|
350
|
-
result = val[0]
|
356
|
+
result = val[0], {val[1][0] => val[1][1]}
|
351
357
|
result
|
352
358
|
end
|
353
359
|
.,.,
|
354
360
|
|
355
|
-
module_eval(<<'.,.,', 'parse.y',
|
361
|
+
module_eval(<<'.,.,', 'parse.y', 76)
|
356
362
|
def _reduce_20(val, _values, result)
|
357
|
-
result = val[
|
363
|
+
result = val[0]
|
358
364
|
result
|
359
365
|
end
|
360
366
|
.,.,
|
361
367
|
|
362
|
-
module_eval(<<'.,.,', 'parse.y',
|
368
|
+
module_eval(<<'.,.,', 'parse.y', 78)
|
363
369
|
def _reduce_21(val, _values, result)
|
364
|
-
|
370
|
+
result = val[0]
|
365
371
|
result
|
366
372
|
end
|
367
373
|
.,.,
|
368
374
|
|
369
|
-
module_eval(<<'.,.,', 'parse.y',
|
375
|
+
module_eval(<<'.,.,', 'parse.y', 83)
|
370
376
|
def _reduce_22(val, _values, result)
|
371
|
-
result =
|
377
|
+
result = val[1]
|
372
378
|
result
|
373
379
|
end
|
374
380
|
.,.,
|
375
381
|
|
376
|
-
module_eval(<<'.,.,', 'parse.y',
|
382
|
+
module_eval(<<'.,.,', 'parse.y', 85)
|
377
383
|
def _reduce_23(val, _values, result)
|
378
|
-
|
384
|
+
return
|
379
385
|
result
|
380
386
|
end
|
381
387
|
.,.,
|
382
388
|
|
383
389
|
module_eval(<<'.,.,', 'parse.y', 90)
|
384
390
|
def _reduce_24(val, _values, result)
|
385
|
-
result = val[0]
|
391
|
+
result = [val[0]]
|
386
392
|
result
|
387
393
|
end
|
388
394
|
.,.,
|
389
395
|
|
390
|
-
module_eval(<<'.,.,', 'parse.y',
|
396
|
+
module_eval(<<'.,.,', 'parse.y', 92)
|
391
397
|
def _reduce_25(val, _values, result)
|
392
|
-
result = val[0]
|
398
|
+
result = val[0] << val[2]
|
393
399
|
result
|
394
400
|
end
|
395
401
|
.,.,
|
396
402
|
|
397
|
-
module_eval(<<'.,.,', 'parse.y',
|
403
|
+
module_eval(<<'.,.,', 'parse.y', 94)
|
398
404
|
def _reduce_26(val, _values, result)
|
399
405
|
result = val[0]
|
400
406
|
result
|
401
407
|
end
|
402
408
|
.,.,
|
403
409
|
|
404
|
-
module_eval(<<'.,.,', 'parse.y',
|
410
|
+
module_eval(<<'.,.,', 'parse.y', 99)
|
405
411
|
def _reduce_27(val, _values, result)
|
406
412
|
result = val[0]
|
407
413
|
result
|
408
414
|
end
|
409
415
|
.,.,
|
410
416
|
|
411
|
-
module_eval(<<'.,.,', 'parse.y',
|
417
|
+
module_eval(<<'.,.,', 'parse.y', 101)
|
412
418
|
def _reduce_28(val, _values, result)
|
413
419
|
result = val[0]
|
414
420
|
result
|
415
421
|
end
|
416
422
|
.,.,
|
417
423
|
|
424
|
+
module_eval(<<'.,.,', 'parse.y', 103)
|
425
|
+
def _reduce_29(val, _values, result)
|
426
|
+
result = val[0]
|
427
|
+
result
|
428
|
+
end
|
429
|
+
.,.,
|
430
|
+
|
431
|
+
module_eval(<<'.,.,', 'parse.y', 105)
|
432
|
+
def _reduce_30(val, _values, result)
|
433
|
+
result = val[0]
|
434
|
+
result
|
435
|
+
end
|
436
|
+
.,.,
|
437
|
+
|
438
|
+
module_eval(<<'.,.,', 'parse.y', 110)
|
439
|
+
def _reduce_31(val, _values, result)
|
440
|
+
result = val[0]
|
441
|
+
result
|
442
|
+
end
|
443
|
+
.,.,
|
444
|
+
|
445
|
+
module_eval(<<'.,.,', 'parse.y', 112)
|
446
|
+
def _reduce_32(val, _values, result)
|
447
|
+
result = val[0]
|
448
|
+
result
|
449
|
+
end
|
450
|
+
.,.,
|
451
|
+
|
418
452
|
def _reduce_none(val, _values, result)
|
419
453
|
val[0]
|
420
454
|
end
|
data/lib/hcl1/checker.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'hcl/checker/version'
|
2
|
+
require_relative 'lexer'
|
3
|
+
require_relative 'parser'
|
4
|
+
|
5
|
+
module HCL1
|
6
|
+
module Checker
|
7
|
+
def self.valid?(value)
|
8
|
+
ret = HCLParser.new.parse(value)
|
9
|
+
return true if ret.is_a? Hash
|
10
|
+
false
|
11
|
+
rescue
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.parse(value)
|
16
|
+
HCLParser.new.parse(value)
|
17
|
+
rescue Racc::ParseError => e
|
18
|
+
return e.message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/hcl1/lexer.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
#--
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by rex 1.0.7
|
4
|
+
# from lexical definition file "./assets/lexer.rex".
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
class HCLLexer
|
9
|
+
require 'strscan'
|
10
|
+
|
11
|
+
class ScanError < StandardError ; end
|
12
|
+
|
13
|
+
attr_reader :lineno
|
14
|
+
attr_reader :filename
|
15
|
+
attr_accessor :state
|
16
|
+
|
17
|
+
def scan_setup(str)
|
18
|
+
@ss = StringScanner.new(str)
|
19
|
+
@lineno = 1
|
20
|
+
@state = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def action
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
|
27
|
+
def scan_str(str)
|
28
|
+
scan_setup(str)
|
29
|
+
do_parse
|
30
|
+
end
|
31
|
+
alias :scan :scan_str
|
32
|
+
|
33
|
+
def load_file( filename )
|
34
|
+
@filename = filename
|
35
|
+
File.open(filename, "r") do |f|
|
36
|
+
scan_setup(f.read)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def scan_file( filename )
|
41
|
+
load_file(filename)
|
42
|
+
do_parse
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def next_token
|
47
|
+
return if @ss.eos?
|
48
|
+
|
49
|
+
# skips empty actions
|
50
|
+
until token = _next_token or @ss.eos?; end
|
51
|
+
token
|
52
|
+
end
|
53
|
+
|
54
|
+
def _next_token
|
55
|
+
text = @ss.peek(1)
|
56
|
+
@lineno += 1 if text == "\n"
|
57
|
+
token = case @state
|
58
|
+
when nil
|
59
|
+
case
|
60
|
+
when (text = @ss.scan(/\s+/))
|
61
|
+
;
|
62
|
+
|
63
|
+
when (text = @ss.scan(/\#.*|\/\/.*$/))
|
64
|
+
;
|
65
|
+
|
66
|
+
when (text = @ss.scan(/\n|\r/))
|
67
|
+
;
|
68
|
+
|
69
|
+
when (text = @ss.scan(/\/\*/))
|
70
|
+
action { consume_comment(text) }
|
71
|
+
|
72
|
+
when (text = @ss.scan(/true|false/))
|
73
|
+
action { [:BOOL, to_boolean(text)]}
|
74
|
+
|
75
|
+
when (text = @ss.scan(/\-?\d+\.\d+/))
|
76
|
+
action { [:FLOAT, text.to_f] }
|
77
|
+
|
78
|
+
when (text = @ss.scan(/-?\d+/))
|
79
|
+
action { [:NUMBER, text.to_i] }
|
80
|
+
|
81
|
+
when (text = @ss.scan(/\"/))
|
82
|
+
action { [:STRING, consume_string(text)] }
|
83
|
+
|
84
|
+
when (text = @ss.scan(/\<<\-?/))
|
85
|
+
action { [:STRING, consume_heredoc] }
|
86
|
+
|
87
|
+
when (text = @ss.scan(/\{/))
|
88
|
+
action { [:LEFTBRACE, text]}
|
89
|
+
|
90
|
+
when (text = @ss.scan(/\}/))
|
91
|
+
action { [:RIGHTBRACE, text]}
|
92
|
+
|
93
|
+
when (text = @ss.scan(/\[/))
|
94
|
+
action { [:LEFTBRACKET, text]}
|
95
|
+
|
96
|
+
when (text = @ss.scan(/\]/))
|
97
|
+
action { [:RIGHTBRACKET, text]}
|
98
|
+
|
99
|
+
when (text = @ss.scan(/\,/))
|
100
|
+
action { [:COMMA, text]}
|
101
|
+
|
102
|
+
when (text = @ss.scan(/[a-zA-Z_][a-zA-Z0-9_\-\.]*/))
|
103
|
+
action { [:IDENTIFIER, text]}
|
104
|
+
|
105
|
+
when (text = @ss.scan(/\=/))
|
106
|
+
action { [:EQUAL, text]}
|
107
|
+
|
108
|
+
when (text = @ss.scan(/\-/))
|
109
|
+
action { [:MINUS, text]}
|
110
|
+
|
111
|
+
|
112
|
+
else
|
113
|
+
text = @ss.string[@ss.pos .. -1]
|
114
|
+
raise ScanError, "can not match: '" + text + "'"
|
115
|
+
end # if
|
116
|
+
|
117
|
+
else
|
118
|
+
raise ScanError, "undefined state: '" + state.to_s + "'"
|
119
|
+
end # case state
|
120
|
+
token
|
121
|
+
end # def _next_token
|
122
|
+
|
123
|
+
def lex(input)
|
124
|
+
scan_setup(input)
|
125
|
+
tokens = []
|
126
|
+
while token = next_token
|
127
|
+
tokens << token
|
128
|
+
end
|
129
|
+
tokens
|
130
|
+
end
|
131
|
+
def to_boolean(input)
|
132
|
+
input =
|
133
|
+
if input =~ /true/
|
134
|
+
true
|
135
|
+
elsif input =~ /false/
|
136
|
+
false
|
137
|
+
end
|
138
|
+
return input
|
139
|
+
end
|
140
|
+
def consume_comment(input)
|
141
|
+
nested = 1
|
142
|
+
until nested.zero?
|
143
|
+
case(text = @ss.scan_until(%r{/\*|\*/|\z}) )
|
144
|
+
when %r{/\*\z}
|
145
|
+
nested =+ 1
|
146
|
+
when %r{\*/\z}
|
147
|
+
nested -= 1
|
148
|
+
else
|
149
|
+
break
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
def consume_string(input)
|
154
|
+
result = ''
|
155
|
+
nested = 0
|
156
|
+
begin
|
157
|
+
case(text = @ss.scan_until(%r{\"|\$\{|\}|\\}))
|
158
|
+
when %r{\$\{\z}
|
159
|
+
nested += 1
|
160
|
+
when %r{\}\z}
|
161
|
+
nested -= 1 if nested > 0
|
162
|
+
when %r{\\\z}
|
163
|
+
result += text.chop + @ss.getch
|
164
|
+
next
|
165
|
+
end
|
166
|
+
result += text.to_s
|
167
|
+
end until nested == 0 && text =~ %r{\"\z}
|
168
|
+
result.chop
|
169
|
+
end
|
170
|
+
def consume_heredoc
|
171
|
+
token = Regexp.new @ss.scan_until(%r{\n})
|
172
|
+
document = @ss.scan_until(token)
|
173
|
+
document.chop
|
174
|
+
end
|
175
|
+
end # class
|