marshal-parser 0.1.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +202 -0
- data/bin/console +15 -0
- data/bin/marshal-cli +6 -0
- data/bin/setup +8 -0
- data/lib/marshal-parser/assertable.rb +9 -0
- data/lib/marshal-parser/cli/commands.rb +108 -0
- data/lib/marshal-parser/formatters/ast/only_tokens.rb +60 -0
- data/lib/marshal-parser/formatters/ast/renderers/entries_block.rb +17 -0
- data/lib/marshal-parser/formatters/ast/renderers/line.rb +17 -0
- data/lib/marshal-parser/formatters/ast/renderers/line_with_annotation.rb +18 -0
- data/lib/marshal-parser/formatters/ast/renderers/renderer.rb +38 -0
- data/lib/marshal-parser/formatters/ast/renderers/renderer_with_annotations.rb +52 -0
- data/lib/marshal-parser/formatters/ast/sexpression.rb +82 -0
- data/lib/marshal-parser/formatters/ast/sexpression_compact.rb +90 -0
- data/lib/marshal-parser/formatters/symbols/table.rb +19 -0
- data/lib/marshal-parser/formatters/tokens/one_line.rb +21 -0
- data/lib/marshal-parser/formatters/tokens/with_description.rb +61 -0
- data/lib/marshal-parser/lexer.rb +331 -0
- data/lib/marshal-parser/parser.rb +880 -0
- data/lib/marshal-parser/version.rb +5 -0
- data/lib/marshal-parser.rb +22 -0
- metadata +85 -0
@@ -0,0 +1,880 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lexer"
|
4
|
+
require_relative "assertable"
|
5
|
+
|
6
|
+
module MarshalParser
|
7
|
+
class Parser
|
8
|
+
include Assertable
|
9
|
+
|
10
|
+
attr_reader :symbols
|
11
|
+
|
12
|
+
def initialize(lexer)
|
13
|
+
@lexer = lexer
|
14
|
+
@index = 0
|
15
|
+
@symbols = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse
|
19
|
+
version_node = build_ast_node
|
20
|
+
build_ast_node
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def build_ast_node
|
26
|
+
token = next_token
|
27
|
+
|
28
|
+
case token.id
|
29
|
+
when Lexer::VERSION
|
30
|
+
VersionNode.new(token)
|
31
|
+
|
32
|
+
when Lexer::ARRAY_PREFIX
|
33
|
+
length = next_token
|
34
|
+
elements = []
|
35
|
+
|
36
|
+
length.value.times do
|
37
|
+
elements << build_ast_node
|
38
|
+
end
|
39
|
+
|
40
|
+
ArrayNode.new(token, length, elements)
|
41
|
+
|
42
|
+
when Lexer::STRING_PREFIX
|
43
|
+
length = next_token
|
44
|
+
content = next_token
|
45
|
+
|
46
|
+
StringNode.new(token, length, content)
|
47
|
+
|
48
|
+
when Lexer::OBJECT_WITH_IVARS_PREFIX
|
49
|
+
child = build_ast_node
|
50
|
+
|
51
|
+
count = next_token
|
52
|
+
assert_token_type(count, Lexer::INTEGER)
|
53
|
+
|
54
|
+
ivars = []
|
55
|
+
|
56
|
+
count.value.times do
|
57
|
+
name = build_ast_node
|
58
|
+
value = build_ast_node
|
59
|
+
ivars << name << value
|
60
|
+
|
61
|
+
assert_node_type(name, SymbolNode, SymbolLinkNode)
|
62
|
+
end
|
63
|
+
|
64
|
+
ObjectWithIVarsNode.new(token, child, count, ivars)
|
65
|
+
|
66
|
+
when Lexer::SYMBOL_PREFIX
|
67
|
+
length = next_token
|
68
|
+
content = next_token
|
69
|
+
@symbols << @lexer.source_string[content.index, content.length]
|
70
|
+
|
71
|
+
SymbolNode.new(token, length, content, @symbols.size - 1)
|
72
|
+
|
73
|
+
when Lexer::TRUE
|
74
|
+
TrueNode.new(token)
|
75
|
+
|
76
|
+
when Lexer::FALSE
|
77
|
+
FalseNode.new(token)
|
78
|
+
|
79
|
+
when Lexer::NIL
|
80
|
+
NilNode.new(token)
|
81
|
+
|
82
|
+
when Lexer::INTEGER_PREFIX
|
83
|
+
value = next_token
|
84
|
+
IntegerNode.new(token, value)
|
85
|
+
|
86
|
+
when Lexer::BIG_INTEGER_PREFIX
|
87
|
+
sign = next_token
|
88
|
+
length = next_token
|
89
|
+
value = next_token
|
90
|
+
BigIntegerNode.new(token, sign, length, value)
|
91
|
+
|
92
|
+
when Lexer::FLOAT_PREFIX
|
93
|
+
length = next_token
|
94
|
+
value = next_token
|
95
|
+
FloatNode.new(token, length, value)
|
96
|
+
|
97
|
+
when Lexer::SYMBOL_LINK_PREFIX
|
98
|
+
index = next_token
|
99
|
+
|
100
|
+
SymbolLinkNode.new(token, index)
|
101
|
+
|
102
|
+
when Lexer::HASH_PREFIX
|
103
|
+
size = next_token
|
104
|
+
assert_token_type size, Lexer::INTEGER
|
105
|
+
|
106
|
+
key_and_value_nodes = []
|
107
|
+
|
108
|
+
size.value.times do
|
109
|
+
key = build_ast_node
|
110
|
+
assert_node_type key, SymbolNode, SymbolLinkNode
|
111
|
+
|
112
|
+
value = build_ast_node
|
113
|
+
key_and_value_nodes << key << value
|
114
|
+
end
|
115
|
+
|
116
|
+
HashNode.new(token, size, key_and_value_nodes)
|
117
|
+
|
118
|
+
when Lexer::HASH_WITH_DEFAULT_VALUE_PREFIX
|
119
|
+
size = next_token
|
120
|
+
assert_token_type size, Lexer::INTEGER
|
121
|
+
|
122
|
+
key_and_value_nodes = []
|
123
|
+
|
124
|
+
size.value.times do
|
125
|
+
key = build_ast_node
|
126
|
+
assert_node_type key, SymbolNode, SymbolLinkNode
|
127
|
+
|
128
|
+
value = build_ast_node
|
129
|
+
key_and_value_nodes << key << value
|
130
|
+
end
|
131
|
+
|
132
|
+
default_value_node = build_ast_node
|
133
|
+
assert_node_type default_value_node, IntegerNode
|
134
|
+
|
135
|
+
HashWithDefaultValueNode.new(token, size, key_and_value_nodes, default_value_node)
|
136
|
+
|
137
|
+
when Lexer::REGEXP_PREFIX
|
138
|
+
string_length = next_token
|
139
|
+
string = next_token
|
140
|
+
options = next_token
|
141
|
+
|
142
|
+
RegexpNode.new(token, string_length, string, options)
|
143
|
+
|
144
|
+
when Lexer::CLASS_PREFIX
|
145
|
+
length = next_token
|
146
|
+
string = next_token
|
147
|
+
|
148
|
+
ClassNode.new(token, length, string)
|
149
|
+
|
150
|
+
when Lexer::MODULE_PREFIX
|
151
|
+
length = next_token
|
152
|
+
string = next_token
|
153
|
+
|
154
|
+
ModuleNode.new(token, length, string)
|
155
|
+
|
156
|
+
when Lexer::SUBCLASS_OF_CORE_LIBRARY_CLASS_PREFIX
|
157
|
+
class_name_node = build_ast_node
|
158
|
+
assert_node_type class_name_node, SymbolNode, SymbolLinkNode
|
159
|
+
|
160
|
+
object_node = build_ast_node
|
161
|
+
|
162
|
+
SubclassNode.new(token, class_name_node, object_node)
|
163
|
+
|
164
|
+
when Lexer::STRUCT_PREFIX
|
165
|
+
class_name_node = build_ast_node
|
166
|
+
assert_node_type class_name_node, SymbolNode, SymbolLinkNode
|
167
|
+
|
168
|
+
members_count = next_token
|
169
|
+
|
170
|
+
member_nodes = []
|
171
|
+
|
172
|
+
members_count.value.times do
|
173
|
+
name = build_ast_node
|
174
|
+
value = build_ast_node
|
175
|
+
|
176
|
+
assert_node_type name, SymbolNode, SymbolLinkNode
|
177
|
+
|
178
|
+
member_nodes << name << value
|
179
|
+
end
|
180
|
+
|
181
|
+
StructNode.new(token, class_name_node, members_count, member_nodes)
|
182
|
+
|
183
|
+
when Lexer::OBJECT_PREFIX
|
184
|
+
class_name_node = build_ast_node
|
185
|
+
assert_node_type class_name_node, SymbolNode, SymbolLinkNode
|
186
|
+
|
187
|
+
ivars_count = next_token
|
188
|
+
assert_token_type(ivars_count, Lexer::INTEGER)
|
189
|
+
|
190
|
+
ivars_nodes = []
|
191
|
+
|
192
|
+
ivars_count.value.times do
|
193
|
+
name = build_ast_node
|
194
|
+
value = build_ast_node
|
195
|
+
|
196
|
+
ivars_nodes << name << value
|
197
|
+
end
|
198
|
+
|
199
|
+
ObjectNode.new(token, class_name_node, ivars_count, ivars_nodes)
|
200
|
+
|
201
|
+
when Lexer::OBJECT_LINK_PREFIX
|
202
|
+
index = next_token
|
203
|
+
|
204
|
+
ObjectLinkNode.new(token, index)
|
205
|
+
|
206
|
+
when Lexer::OBJECT_WITH_DUMP_PREFIX
|
207
|
+
class_name_node = build_ast_node
|
208
|
+
assert_node_type class_name_node, SymbolNode, SymbolLinkNode
|
209
|
+
|
210
|
+
length = next_token
|
211
|
+
user_dump = next_token
|
212
|
+
|
213
|
+
ObjectWithDumpMethodNode.new(token, class_name_node, length, user_dump)
|
214
|
+
|
215
|
+
when Lexer::OBJECT_WITH_MARSHAL_DUMP_PREFIX
|
216
|
+
class_name_node = build_ast_node
|
217
|
+
assert_node_type class_name_node, SymbolNode, SymbolLinkNode
|
218
|
+
|
219
|
+
child_node = build_ast_node
|
220
|
+
|
221
|
+
ObjectWithMarshalDumpMethod.new(token, class_name_node, child_node)
|
222
|
+
|
223
|
+
when Lexer::OBJECT_EXTENDED_PREFIX
|
224
|
+
module_name_node = build_ast_node
|
225
|
+
object_node = build_ast_node
|
226
|
+
|
227
|
+
ObjectExtendedNode.new(token, module_name_node, object_node)
|
228
|
+
|
229
|
+
else
|
230
|
+
raise "Not supported token id #{token.id}"
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def next_token
|
235
|
+
raise "No next token" if @index >= @lexer.tokens.size
|
236
|
+
|
237
|
+
@index += 1
|
238
|
+
@lexer.tokens[@index - 1]
|
239
|
+
end
|
240
|
+
|
241
|
+
def assert_node_type(node, *allowed_classes)
|
242
|
+
assert(
|
243
|
+
allowed_classes.any? { |node_class| node.instance_of?(node_class) },
|
244
|
+
"Node #{node} should be a #{allowed_classes.map(&:name).join(" or ")}"
|
245
|
+
)
|
246
|
+
end
|
247
|
+
|
248
|
+
def assert_token_type(token, *token_ids)
|
249
|
+
assert(
|
250
|
+
token_ids.include?(token.id),
|
251
|
+
"Token #{token} should have type #{token_ids.join(" or ")}"
|
252
|
+
)
|
253
|
+
end
|
254
|
+
|
255
|
+
module Annotatable
|
256
|
+
def annotation
|
257
|
+
raise "Not implemented"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
class Node
|
262
|
+
include Assertable
|
263
|
+
|
264
|
+
def child_entities
|
265
|
+
raise "Not implemented"
|
266
|
+
end
|
267
|
+
|
268
|
+
def tokens
|
269
|
+
child_entities.grep(Lexer::Token)
|
270
|
+
end
|
271
|
+
|
272
|
+
def children
|
273
|
+
child_entities.grep(Node)
|
274
|
+
end
|
275
|
+
|
276
|
+
def decoded_value
|
277
|
+
nil
|
278
|
+
end
|
279
|
+
|
280
|
+
def literal_token
|
281
|
+
nil
|
282
|
+
end
|
283
|
+
|
284
|
+
def attributes
|
285
|
+
{}
|
286
|
+
end
|
287
|
+
|
288
|
+
def always_leaf?
|
289
|
+
false
|
290
|
+
end
|
291
|
+
|
292
|
+
private
|
293
|
+
|
294
|
+
def assert_token_type(token, *token_ids)
|
295
|
+
assert(
|
296
|
+
token_ids.include?(token.id),
|
297
|
+
"Token #{token} should have type #{token_ids.join(" or ")}"
|
298
|
+
)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
class VersionNode < Node
|
303
|
+
def initialize(version_token)
|
304
|
+
super()
|
305
|
+
assert_token_type version_token, Lexer::VERSION
|
306
|
+
@version_token = version_token
|
307
|
+
end
|
308
|
+
|
309
|
+
def child_entities
|
310
|
+
[@version_token]
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
class ArrayNode < Node
|
315
|
+
def initialize(marker_token, length_token, elements_nodes)
|
316
|
+
super()
|
317
|
+
assert_token_type marker_token, Lexer::ARRAY_PREFIX
|
318
|
+
assert_token_type length_token, Lexer::INTEGER
|
319
|
+
|
320
|
+
@marker_token = marker_token
|
321
|
+
@length_token = length_token
|
322
|
+
@elements_nodes = elements_nodes
|
323
|
+
end
|
324
|
+
|
325
|
+
def child_entities
|
326
|
+
[@marker_token, @length_token] + @elements_nodes
|
327
|
+
end
|
328
|
+
|
329
|
+
def attributes
|
330
|
+
{
|
331
|
+
@length_token => { name: :length, value: @length_token.value }
|
332
|
+
}
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
class StringNode < Node
|
337
|
+
def initialize(marker_token, length_token, content_token)
|
338
|
+
super()
|
339
|
+
assert_token_type marker_token, Lexer::STRING_PREFIX
|
340
|
+
assert_token_type length_token, Lexer::INTEGER
|
341
|
+
assert_token_type content_token, Lexer::STRING
|
342
|
+
|
343
|
+
@marker_token = marker_token
|
344
|
+
@length_token = length_token
|
345
|
+
@content_token = content_token
|
346
|
+
end
|
347
|
+
|
348
|
+
def child_entities
|
349
|
+
[@marker_token, @length_token, @content_token]
|
350
|
+
end
|
351
|
+
|
352
|
+
def literal_token
|
353
|
+
@content_token
|
354
|
+
end
|
355
|
+
|
356
|
+
def attributes
|
357
|
+
{
|
358
|
+
@length_token => { name: :length, value: @length_token.value },
|
359
|
+
@content_token => { name: :content, value: @content_token }
|
360
|
+
}
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
class ObjectWithIVarsNode < Node
|
365
|
+
def initialize(marker_token, child, count_token, ivars_nodes)
|
366
|
+
super()
|
367
|
+
assert_token_type marker_token, Lexer::OBJECT_WITH_IVARS_PREFIX
|
368
|
+
# child - any Node
|
369
|
+
assert_token_type count_token, Lexer::INTEGER
|
370
|
+
# ivars nodes - any nodes
|
371
|
+
|
372
|
+
@marker_token = marker_token
|
373
|
+
@child = child
|
374
|
+
@count_token = count_token
|
375
|
+
@ivars_nodes = ivars_nodes
|
376
|
+
end
|
377
|
+
|
378
|
+
def child_entities
|
379
|
+
[@marker_token, @child, @count_token] + @ivars_nodes
|
380
|
+
end
|
381
|
+
|
382
|
+
def attributes
|
383
|
+
{
|
384
|
+
@count_token => { name: :ivars_count, value: @count_token.value }
|
385
|
+
}
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
class SymbolNode < Node
|
390
|
+
include Annotatable
|
391
|
+
|
392
|
+
def initialize(marker_token, length_token, content_token, link_to_symbol)
|
393
|
+
super()
|
394
|
+
assert_token_type marker_token, Lexer::SYMBOL_PREFIX
|
395
|
+
assert_token_type length_token, Lexer::INTEGER
|
396
|
+
assert_token_type content_token, Lexer::SYMBOL
|
397
|
+
|
398
|
+
@marker_token = marker_token
|
399
|
+
@length_token = length_token
|
400
|
+
@content_token = content_token
|
401
|
+
@link_to_symbol = link_to_symbol # just Integer, index in the Symbols table
|
402
|
+
end
|
403
|
+
|
404
|
+
def child_entities
|
405
|
+
[@marker_token, @length_token, @content_token]
|
406
|
+
end
|
407
|
+
|
408
|
+
def annotation
|
409
|
+
"symbol ##{@link_to_symbol}"
|
410
|
+
end
|
411
|
+
|
412
|
+
def literal_token
|
413
|
+
@content_token
|
414
|
+
end
|
415
|
+
|
416
|
+
def attributes
|
417
|
+
{
|
418
|
+
@length_token => { name: :length, value: @length_token.value },
|
419
|
+
@content_token => { name: :content, value: @content_token }
|
420
|
+
}
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
class TrueNode < Node
|
425
|
+
def initialize(token)
|
426
|
+
super()
|
427
|
+
assert_token_type(token, Lexer::TRUE)
|
428
|
+
@token = token
|
429
|
+
end
|
430
|
+
|
431
|
+
def child_entities
|
432
|
+
[@token]
|
433
|
+
end
|
434
|
+
|
435
|
+
def always_leaf?
|
436
|
+
true
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
class FalseNode < Node
|
441
|
+
def initialize(token)
|
442
|
+
super()
|
443
|
+
assert_token_type token, Lexer::FALSE
|
444
|
+
@token = token
|
445
|
+
end
|
446
|
+
|
447
|
+
def child_entities
|
448
|
+
[@token]
|
449
|
+
end
|
450
|
+
|
451
|
+
def always_leaf?
|
452
|
+
true
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
class NilNode < Node
|
457
|
+
def initialize(token)
|
458
|
+
super()
|
459
|
+
assert_token_type token, Lexer::NIL
|
460
|
+
@token = token
|
461
|
+
end
|
462
|
+
|
463
|
+
def child_entities
|
464
|
+
[@token]
|
465
|
+
end
|
466
|
+
|
467
|
+
def always_leaf?
|
468
|
+
true
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
class IntegerNode < Node
|
473
|
+
def initialize(prefix, value)
|
474
|
+
super()
|
475
|
+
assert_token_type prefix, Lexer::INTEGER_PREFIX
|
476
|
+
assert_token_type value, Lexer::INTEGER
|
477
|
+
|
478
|
+
@prefix = prefix
|
479
|
+
@value = value
|
480
|
+
end
|
481
|
+
|
482
|
+
def child_entities
|
483
|
+
[@prefix, @value]
|
484
|
+
end
|
485
|
+
|
486
|
+
def decoded_value
|
487
|
+
@value.value
|
488
|
+
end
|
489
|
+
|
490
|
+
def literal_token
|
491
|
+
@value
|
492
|
+
end
|
493
|
+
|
494
|
+
def attributes
|
495
|
+
{
|
496
|
+
@value => { name: :value, value: @value.value }
|
497
|
+
}
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
class BigIntegerNode < Node
|
502
|
+
def initialize(prefix, sign, length, value)
|
503
|
+
super()
|
504
|
+
assert_token_type prefix, Lexer::BIG_INTEGER_PREFIX
|
505
|
+
assert_token_type sign, Lexer::PLUS_SIGN, Lexer::MINUS_SIGN
|
506
|
+
assert_token_type length, Lexer::INTEGER
|
507
|
+
assert_token_type value, Lexer::BIG_INTEGER
|
508
|
+
|
509
|
+
@prefix = prefix
|
510
|
+
@sign = sign
|
511
|
+
@length = length
|
512
|
+
@value = value
|
513
|
+
end
|
514
|
+
|
515
|
+
def child_entities
|
516
|
+
[@prefix, @sign, @length, @value]
|
517
|
+
end
|
518
|
+
|
519
|
+
def decoded_value
|
520
|
+
@value.value
|
521
|
+
end
|
522
|
+
|
523
|
+
def literal_token
|
524
|
+
@value
|
525
|
+
end
|
526
|
+
|
527
|
+
def attributes
|
528
|
+
{
|
529
|
+
@value => { name: :value, value: @value.value }
|
530
|
+
}
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
class FloatNode < Node
|
535
|
+
def initialize(prefix, length, value)
|
536
|
+
super()
|
537
|
+
assert_token_type prefix, Lexer::FLOAT_PREFIX
|
538
|
+
assert_token_type length, Lexer::INTEGER
|
539
|
+
assert_token_type value, Lexer::FLOAT
|
540
|
+
|
541
|
+
@prefix = prefix
|
542
|
+
@length = length
|
543
|
+
@value = value
|
544
|
+
end
|
545
|
+
|
546
|
+
def child_entities
|
547
|
+
[@prefix, @length, @value]
|
548
|
+
end
|
549
|
+
|
550
|
+
def decoded_value
|
551
|
+
@value.value
|
552
|
+
end
|
553
|
+
|
554
|
+
def literal_token
|
555
|
+
@value
|
556
|
+
end
|
557
|
+
|
558
|
+
def attributes
|
559
|
+
{
|
560
|
+
@length => { name: :length, value: @length.value },
|
561
|
+
@value => { name: :value, value: @value.value }
|
562
|
+
}
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
class SymbolLinkNode < Node
|
567
|
+
include Annotatable
|
568
|
+
|
569
|
+
def initialize(marker_token, index_token)
|
570
|
+
super()
|
571
|
+
assert_token_type marker_token, Lexer::SYMBOL_LINK_PREFIX
|
572
|
+
assert_token_type index_token, Lexer::INTEGER
|
573
|
+
|
574
|
+
@marker_token = marker_token
|
575
|
+
@index_token = index_token
|
576
|
+
end
|
577
|
+
|
578
|
+
def child_entities
|
579
|
+
[@marker_token, @index_token]
|
580
|
+
end
|
581
|
+
|
582
|
+
def annotation
|
583
|
+
"link to symbol ##{@index_token.value}"
|
584
|
+
end
|
585
|
+
|
586
|
+
def decoded_value
|
587
|
+
@index_token.value
|
588
|
+
end
|
589
|
+
|
590
|
+
def literal_token
|
591
|
+
@index_token
|
592
|
+
end
|
593
|
+
|
594
|
+
def attributes
|
595
|
+
{
|
596
|
+
@index_token => { name: :index, value: @index_token.value }
|
597
|
+
}
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
class HashNode < Node
|
602
|
+
def initialize(prefix, size, key_and_value_nodes)
|
603
|
+
super()
|
604
|
+
assert_token_type prefix, Lexer::HASH_PREFIX
|
605
|
+
assert_token_type size, Lexer::INTEGER
|
606
|
+
|
607
|
+
@prefix = prefix
|
608
|
+
@size = size
|
609
|
+
@key_and_value_nodes = key_and_value_nodes
|
610
|
+
end
|
611
|
+
|
612
|
+
def child_entities
|
613
|
+
[@prefix, @size] + @key_and_value_nodes
|
614
|
+
end
|
615
|
+
|
616
|
+
def attributes
|
617
|
+
{
|
618
|
+
@size => { name: :size, value: @size.value }
|
619
|
+
}
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
class HashWithDefaultValueNode < Node
|
624
|
+
def initialize(prefix, size, key_and_value_nodes, default_value_node)
|
625
|
+
super()
|
626
|
+
assert_token_type prefix, Lexer::HASH_WITH_DEFAULT_VALUE_PREFIX
|
627
|
+
assert_token_type size, Lexer::INTEGER
|
628
|
+
|
629
|
+
@prefix = prefix
|
630
|
+
@size = size
|
631
|
+
@key_and_value_nodes = key_and_value_nodes
|
632
|
+
@default_value_node = default_value_node
|
633
|
+
end
|
634
|
+
|
635
|
+
def child_entities
|
636
|
+
[@prefix, @size] + @key_and_value_nodes + [@default_value_node]
|
637
|
+
end
|
638
|
+
|
639
|
+
def attributes
|
640
|
+
{
|
641
|
+
@size => { name: :size, value: @size.value }
|
642
|
+
}
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
class RegexpNode < Node
|
647
|
+
def initialize(prefix, string_length, string, options)
|
648
|
+
super()
|
649
|
+
assert_token_type prefix, Lexer::REGEXP_PREFIX
|
650
|
+
assert_token_type string_length, Lexer::INTEGER
|
651
|
+
assert_token_type string, Lexer::STRING
|
652
|
+
assert_token_type options, Lexer::INTEGER
|
653
|
+
|
654
|
+
@prefix = prefix
|
655
|
+
@string_length = string_length
|
656
|
+
@string = string
|
657
|
+
@options = options
|
658
|
+
end
|
659
|
+
|
660
|
+
def child_entities
|
661
|
+
[@prefix, @string_length, @string, @options]
|
662
|
+
end
|
663
|
+
|
664
|
+
def literal_token
|
665
|
+
@string
|
666
|
+
end
|
667
|
+
|
668
|
+
def attributes
|
669
|
+
{
|
670
|
+
@string_length => { name: :length, value: @string_length.value },
|
671
|
+
@string => { name: :source_string, value: @string },
|
672
|
+
@options => { name: :options, value: @options.value }
|
673
|
+
}
|
674
|
+
end
|
675
|
+
end
|
676
|
+
|
677
|
+
class ClassNode < Node
|
678
|
+
def initialize(prefix, length, name)
|
679
|
+
super()
|
680
|
+
assert_token_type prefix, Lexer::CLASS_PREFIX
|
681
|
+
assert_token_type length, Lexer::INTEGER
|
682
|
+
assert_token_type name, Lexer::STRING
|
683
|
+
|
684
|
+
@prefix = prefix
|
685
|
+
@length = length
|
686
|
+
@name = name
|
687
|
+
end
|
688
|
+
|
689
|
+
def child_entities
|
690
|
+
[@prefix, @length, @name]
|
691
|
+
end
|
692
|
+
|
693
|
+
def literal_token
|
694
|
+
@name
|
695
|
+
end
|
696
|
+
|
697
|
+
def attributes
|
698
|
+
{
|
699
|
+
@length => { name: :length, value: @length.value },
|
700
|
+
@name => { name: :name, value: @name }
|
701
|
+
}
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
class ModuleNode < Node
|
706
|
+
def initialize(prefix, length, name)
|
707
|
+
super()
|
708
|
+
assert_token_type prefix, Lexer::MODULE_PREFIX
|
709
|
+
assert_token_type length, Lexer::INTEGER
|
710
|
+
assert_token_type name, Lexer::STRING
|
711
|
+
|
712
|
+
@prefix = prefix
|
713
|
+
@length = length
|
714
|
+
@name = name
|
715
|
+
end
|
716
|
+
|
717
|
+
def child_entities
|
718
|
+
[@prefix, @length, @name]
|
719
|
+
end
|
720
|
+
|
721
|
+
def literal_token
|
722
|
+
@name
|
723
|
+
end
|
724
|
+
|
725
|
+
def attributes
|
726
|
+
{
|
727
|
+
@length => { name: :length, value: @length.value },
|
728
|
+
@name => { name: :name, value: @name }
|
729
|
+
}
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
class SubclassNode < Node
|
734
|
+
def initialize(prefix, class_name_node, object_node)
|
735
|
+
super()
|
736
|
+
assert_token_type prefix, Lexer::SUBCLASS_OF_CORE_LIBRARY_CLASS_PREFIX
|
737
|
+
|
738
|
+
@prefix = prefix
|
739
|
+
@class_name_node = class_name_node
|
740
|
+
@object_node = object_node
|
741
|
+
end
|
742
|
+
|
743
|
+
def child_entities
|
744
|
+
[@prefix, @class_name_node, @object_node]
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
748
|
+
class StructNode < Node
|
749
|
+
def initialize(prefix, class_name_node, members_count, member_nodes)
|
750
|
+
super()
|
751
|
+
assert_token_type prefix, Lexer::STRUCT_PREFIX
|
752
|
+
assert_token_type members_count, Lexer::INTEGER
|
753
|
+
|
754
|
+
@prefix = prefix
|
755
|
+
@class_name_node = class_name_node
|
756
|
+
@members_count = members_count
|
757
|
+
@member_nodes = member_nodes
|
758
|
+
end
|
759
|
+
|
760
|
+
def child_entities
|
761
|
+
[@prefix, @class_name_node, @members_count] + @member_nodes
|
762
|
+
end
|
763
|
+
|
764
|
+
def attributes
|
765
|
+
{
|
766
|
+
@members_count => { name: :count, value: @members_count.value }
|
767
|
+
}
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
class ObjectNode < Node
|
772
|
+
def initialize(prefix, class_name_node, ivars_count, ivars_nodes)
|
773
|
+
super()
|
774
|
+
assert_token_type prefix, Lexer::OBJECT_PREFIX
|
775
|
+
assert_token_type ivars_count, Lexer::INTEGER
|
776
|
+
|
777
|
+
@prefix = prefix
|
778
|
+
@class_name_node = class_name_node
|
779
|
+
@ivars_count = ivars_count
|
780
|
+
@ivars_nodes = ivars_nodes
|
781
|
+
end
|
782
|
+
|
783
|
+
def child_entities
|
784
|
+
[@prefix, @class_name_node, @ivars_count] + @ivars_nodes
|
785
|
+
end
|
786
|
+
|
787
|
+
def attributes
|
788
|
+
{
|
789
|
+
@ivars_count => { name: :ivars_count, value: @ivars_count.value }
|
790
|
+
}
|
791
|
+
end
|
792
|
+
end
|
793
|
+
|
794
|
+
class ObjectLinkNode < Node
|
795
|
+
def initialize(prefix, index)
|
796
|
+
super()
|
797
|
+
assert_token_type prefix, Lexer::OBJECT_LINK_PREFIX
|
798
|
+
assert_token_type index, Lexer::INTEGER
|
799
|
+
|
800
|
+
@prefix = prefix
|
801
|
+
@index = index
|
802
|
+
end
|
803
|
+
|
804
|
+
def child_entities
|
805
|
+
[@prefix, @index]
|
806
|
+
end
|
807
|
+
|
808
|
+
def decoded_value
|
809
|
+
@index.value
|
810
|
+
end
|
811
|
+
|
812
|
+
def literal_token
|
813
|
+
@index
|
814
|
+
end
|
815
|
+
|
816
|
+
def attributes
|
817
|
+
{
|
818
|
+
@index => { name: :index, value: @index.value }
|
819
|
+
}
|
820
|
+
end
|
821
|
+
end
|
822
|
+
|
823
|
+
class ObjectWithDumpMethodNode < Node
|
824
|
+
def initialize(token, class_name_node, length, user_dump)
|
825
|
+
super()
|
826
|
+
assert_token_type token, Lexer::OBJECT_WITH_DUMP_PREFIX
|
827
|
+
assert_token_type length, Lexer::INTEGER
|
828
|
+
assert_token_type user_dump, Lexer::STRING
|
829
|
+
|
830
|
+
@prefix = token
|
831
|
+
@class_name_node = class_name_node
|
832
|
+
@length = length
|
833
|
+
@user_dump = user_dump
|
834
|
+
end
|
835
|
+
|
836
|
+
def child_entities
|
837
|
+
[@prefix, @class_name_node, @length, @user_dump]
|
838
|
+
end
|
839
|
+
|
840
|
+
def literal_token
|
841
|
+
@user_dump
|
842
|
+
end
|
843
|
+
|
844
|
+
def attributes
|
845
|
+
{
|
846
|
+
@length => { name: :length, value: @length.value },
|
847
|
+
@user_dump => { name: :dump, value: @user_dump }
|
848
|
+
}
|
849
|
+
end
|
850
|
+
end
|
851
|
+
|
852
|
+
class ObjectWithMarshalDumpMethod < Node
|
853
|
+
def initialize(prefix, class_name_node, child_node)
|
854
|
+
super()
|
855
|
+
assert_token_type prefix, Lexer::OBJECT_WITH_MARSHAL_DUMP_PREFIX
|
856
|
+
|
857
|
+
@prefix = prefix
|
858
|
+
@class_name_node = class_name_node
|
859
|
+
@child_node = child_node
|
860
|
+
end
|
861
|
+
|
862
|
+
def child_entities
|
863
|
+
[@prefix, @class_name_node, @child_node]
|
864
|
+
end
|
865
|
+
end
|
866
|
+
|
867
|
+
class ObjectExtendedNode < Node
|
868
|
+
def initialize(prefix, module_name_node, object_node)
|
869
|
+
super()
|
870
|
+
@prefix = prefix
|
871
|
+
@module_name_node = module_name_node
|
872
|
+
@object_node = object_node
|
873
|
+
end
|
874
|
+
|
875
|
+
def child_entities
|
876
|
+
[@prefix, @module_name_node, @object_node]
|
877
|
+
end
|
878
|
+
end
|
879
|
+
end
|
880
|
+
end
|