rubasteme 0.1.1 → 0.1.6
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 +4 -4
- data/CHANGELOG.md +35 -0
- data/examples/mini_rus3 +9 -4
- data/examples/mini_sicp_scheme +1 -1
- data/examples/sicp_scheme/evaluator.rb +18 -5
- data/exe/rubasteme +2 -2
- data/lib/rbscmlex/missing.rb +46 -0
- data/lib/rubasteme.rb +5 -0
- data/lib/rubasteme/ast.rb +11 -1
- data/lib/rubasteme/ast/branch_node.rb +221 -75
- data/lib/rubasteme/ast/leaf_node.rb +4 -0
- data/lib/rubasteme/error.rb +3 -3
- data/lib/rubasteme/parser.rb +29 -582
- data/lib/rubasteme/parser/derived_converter.rb +315 -0
- data/lib/rubasteme/parser/phase1_parser.rb +119 -0
- data/lib/rubasteme/parser/phase2_parser.rb +255 -0
- data/lib/rubasteme/version.rb +7 -2
- data/rubasteme.gemspec +1 -1
- metadata +8 -4
data/lib/rubasteme/error.rb
CHANGED
@@ -5,7 +5,7 @@ module Rubasteme
|
|
5
5
|
|
6
6
|
# :stopdoc:
|
7
7
|
EMSG = {
|
8
|
-
|
8
|
+
scheme_syntax_error: "syntax error: %s",
|
9
9
|
unexpected_token_type: "unexpected token type: got=%s, expected=%s",
|
10
10
|
missing_right_parenthesis: "missing right parenthesis",
|
11
11
|
unsupported_feature: "unsupported feature: %s",
|
@@ -15,8 +15,8 @@ module Rubasteme
|
|
15
15
|
|
16
16
|
# Indicates a syntax error as Scheme program.
|
17
17
|
class SchemeSyntaxErrorError < Error
|
18
|
-
def initialize(
|
19
|
-
super(EMSG[:scheme_syntax_error] %
|
18
|
+
def initialize(msg)
|
19
|
+
super(EMSG[:scheme_syntax_error] % msg)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
data/lib/rubasteme/parser.rb
CHANGED
@@ -3,607 +3,54 @@
|
|
3
3
|
module Rubasteme
|
4
4
|
|
5
5
|
def self.parser
|
6
|
-
Parser.new
|
6
|
+
Parser::Parser.new
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
module Parser
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def self.version
|
12
|
+
Rubasteme.send(:make_version, self.name)
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
parse_program
|
19
|
-
end
|
20
|
-
|
21
|
-
def parse_program
|
22
|
-
ast_program = AST.instantiate(:ast_program, nil)
|
23
|
-
Kernel.loop {
|
24
|
-
ast_program << parse_expression
|
25
|
-
}
|
26
|
-
ast_program
|
27
|
-
end
|
28
|
-
|
29
|
-
def parse_expression
|
30
|
-
if start_delimiter?(@lexer.peek_token)
|
31
|
-
parse_compound_expression
|
32
|
-
else
|
33
|
-
parse_simple_expression
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def parse_simple_expression
|
38
|
-
type, literal = *@lexer.next_token
|
39
|
-
AST.instantiate(ast_simple_type(type), literal)
|
40
|
-
end
|
41
|
-
|
42
|
-
def parse_identifier
|
43
|
-
parse_simple_expression
|
44
|
-
end
|
45
|
-
|
46
|
-
TOKEN_START_DELIMITERS = [ # :nodoc:
|
47
|
-
:lparen, # list: ( ... )
|
48
|
-
:vec_lparen, # vector: #( ... )
|
49
|
-
:bytevec_lparen, # bytevector: #u8( ... )
|
50
|
-
:quotation, # quotation: '<something>
|
51
|
-
:backquote, # quasiquote: `<something>
|
52
|
-
:comma, # used in quasiquote
|
53
|
-
:comma_at, # used in quasiquote
|
54
|
-
:comment_lparen, # comment start
|
55
|
-
]
|
56
|
-
|
57
|
-
def start_delimiter?(token)
|
58
|
-
TOKEN_START_DELIMITERS.include?(token.type)
|
59
|
-
end
|
60
|
-
|
61
|
-
def parse_compound_expression
|
62
|
-
case @lexer.peek_token.type
|
63
|
-
when :vec_lparen
|
64
|
-
parse_vector
|
65
|
-
when :quotation
|
66
|
-
parse_quotation
|
67
|
-
when :lparen
|
68
|
-
parse_list_expression
|
69
|
-
else
|
70
|
-
raise SchemeSyntaxError, @lexer.peek_token.literal
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def parse_vector
|
75
|
-
parse_data_to_matched_rparen
|
76
|
-
end
|
77
|
-
|
78
|
-
def parse_data_to_matched_rparen
|
79
|
-
token = @lexer.next_token
|
80
|
-
node = AST.instantiate(ast_compound_type(token.type), nil)
|
81
|
-
Kernel.loop {
|
82
|
-
break if @lexer.peek_token.type == :rparen
|
83
|
-
node << parse_datum
|
84
|
-
}
|
85
|
-
skip_rparen
|
86
|
-
|
87
|
-
node
|
88
|
-
end
|
89
|
-
|
90
|
-
def parse_datum
|
91
|
-
if start_delimiter?(@lexer.peek_token)
|
92
|
-
parse_compound_datum
|
93
|
-
else
|
94
|
-
parse_simple_datum
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def parse_simple_datum
|
99
|
-
parse_simple_expression
|
100
|
-
end
|
101
|
-
|
102
|
-
def parse_compound_datum
|
103
|
-
case @lexer.peek_token.type
|
104
|
-
when :lparen
|
105
|
-
parse_data_list
|
106
|
-
when :vec_lparen
|
107
|
-
parse_vector
|
108
|
-
else
|
109
|
-
parse_simple_expression
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def parse_data_list
|
114
|
-
parse_data_to_matched_rparen
|
115
|
-
end
|
116
|
-
|
117
|
-
def parse_quotation
|
118
|
-
literal = @lexer.next_token.literal
|
119
|
-
quote_node = AST.instantiate(:ast_quotation, literal)
|
120
|
-
quote_node << parse_datum
|
121
|
-
quote_node
|
122
|
-
end
|
123
|
-
|
124
|
-
DERIVED_IDENTIFIERS = [
|
125
|
-
"cond", "case", "and", "or", "when", "unless",
|
126
|
-
"let", "let*", "letrec", "letrec*",
|
127
|
-
"let-values", "let*-values",
|
128
|
-
"begin", "do",
|
129
|
-
"delay", "delay-force",
|
130
|
-
"parameterize",
|
131
|
-
"guard",
|
132
|
-
"case-lambda",
|
133
|
-
]
|
134
|
-
|
135
|
-
def parse_list_expression
|
136
|
-
node = nil
|
137
|
-
skip_lparen
|
138
|
-
type, literal = *@lexer.peek_token
|
139
|
-
case type
|
140
|
-
when :rparen
|
141
|
-
# an empty list
|
142
|
-
node = AST.instantiate(:ast_empty_list, nil)
|
143
|
-
skip_rparen
|
144
|
-
when :identifier
|
145
|
-
case literal
|
146
|
-
when "lambda"
|
147
|
-
node = parse_lambda_expression
|
148
|
-
when "if"
|
149
|
-
node = parse_conditional
|
150
|
-
when "set!"
|
151
|
-
node = parse_assignment
|
152
|
-
when "let-syntax", "letrec-syntax"
|
153
|
-
node = parse_macro_block
|
154
|
-
when "define", "define-syntax", "define-values", "define-record-type"
|
155
|
-
node = parse_definition
|
156
|
-
when "include", "include-ci"
|
157
|
-
node = parse_includer
|
158
|
-
when *DERIVED_IDENTIFIERS
|
159
|
-
node = parse_derived_expression
|
160
|
-
end
|
161
|
-
end
|
162
|
-
node || parse_procedure_call
|
163
|
-
end
|
164
|
-
|
165
|
-
def parse_procedure_call
|
166
|
-
proc_call_node = AST.instantiate(:ast_procedure_call, nil)
|
167
|
-
proc_call_node.operator = parse_operator
|
168
|
-
Kernel.loop {
|
169
|
-
break if @lexer.peek_token.type == :rparen
|
170
|
-
proc_call_node.add_operand(parse_operand)
|
171
|
-
}
|
172
|
-
skip_rparen
|
173
|
-
proc_call_node
|
174
|
-
end
|
175
|
-
|
176
|
-
def parse_operator
|
177
|
-
parse_expression
|
178
|
-
end
|
179
|
-
|
180
|
-
def parse_operand
|
181
|
-
parse_expression
|
182
|
-
end
|
183
|
-
|
184
|
-
def parse_lambda_expression
|
185
|
-
@lexer.skip_token # skip :lambda
|
186
|
-
lambda_node = make_lambda_expression_node(parse_formals, read_body)
|
187
|
-
skip_rparen
|
188
|
-
lambda_node
|
189
|
-
end
|
190
|
-
|
191
|
-
def make_lambda_expression_node(formals, body)
|
192
|
-
lambda_node = AST.instantiate(:ast_lambda_expression, nil)
|
193
|
-
lambda_node.formals = formals
|
194
|
-
lambda_node.body = body
|
195
|
-
lambda_node
|
196
|
-
end
|
197
|
-
|
198
|
-
def parse_formals
|
199
|
-
formals_node = nil
|
200
|
-
# type 1: <identifier>
|
201
|
-
# type 2: ( <identifier 1> <identifier 2> ... )
|
202
|
-
# type 3: ( <identifier 1> <identifier 2> <dot> <identifier n> )
|
203
|
-
# => not supported yet
|
204
|
-
if @lexer.peek_token.type == :lparen
|
205
|
-
formals_node = AST.instantiate(:ast_formals, nil)
|
206
|
-
skip_lparen
|
207
|
-
Kernel.loop {
|
208
|
-
break if @lexer.peek_token.type == :rparen
|
209
|
-
formals_node.add_identifier(parse_identifier)
|
210
|
-
}
|
211
|
-
else # type 1
|
212
|
-
formals_node = parse_identifier
|
213
|
-
end
|
214
|
-
skip_rparen
|
215
|
-
formals_node
|
216
|
-
end
|
217
|
-
|
218
|
-
def read_body
|
219
|
-
body = []
|
220
|
-
Kernel.loop {
|
221
|
-
break if @lexer.peek_token.type == :rparen # the end of lambda exp.
|
222
|
-
body << parse_expression
|
223
|
-
}
|
224
|
-
body
|
225
|
-
end
|
226
|
-
|
227
|
-
def parse_conditional
|
228
|
-
if_node = AST.instantiate(:ast_conditional, @lexer.next_token.literal)
|
229
|
-
if_node.test = parse_test
|
230
|
-
if_node.consequent = parse_consequent
|
231
|
-
if @lexer.peek_token.type != :rparen
|
232
|
-
if_node.alternate = parse_alternate
|
233
|
-
end
|
234
|
-
skip_rparen
|
235
|
-
if_node
|
236
|
-
end
|
237
|
-
|
238
|
-
def parse_test
|
239
|
-
parse_expression
|
240
|
-
end
|
241
|
-
|
242
|
-
def parse_consequent
|
243
|
-
parse_expression
|
244
|
-
end
|
245
|
-
|
246
|
-
def parse_alternate
|
247
|
-
parse_expression
|
248
|
-
end
|
249
|
-
|
250
|
-
def parse_assignment
|
251
|
-
assignment_node = AST.instantiate(:ast_assignment, @lexer.next_token.literal)
|
252
|
-
assignment_node.identifier = parse_identifier
|
253
|
-
assignment_node.expression = parse_expression
|
254
|
-
skip_rparen
|
255
|
-
assignment_node
|
256
|
-
end
|
257
|
-
|
258
|
-
def parse_macro_block
|
259
|
-
not_implemented_yet("MACRO block")
|
260
|
-
end
|
261
|
-
|
262
|
-
def parse_definition
|
263
|
-
case @lexer.peek_token.literal
|
264
|
-
when "define"
|
265
|
-
parse_identifier_definition
|
266
|
-
when "define-syntax"
|
267
|
-
parse_define_syntax
|
268
|
-
when "define-values"
|
269
|
-
parse_define_values
|
270
|
-
when "define-record-type"
|
271
|
-
parse_define_record_type
|
272
|
-
else
|
273
|
-
raise SchemeSyntaxErrorError, @lexer.peek_token.literal
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
def parse_identifier_definition
|
278
|
-
# type 1: (define foo 3)
|
279
|
-
# type 2: (define bar (lambda (x y) (+ x y)))
|
280
|
-
# type 3: (define (hoge n m) (display n) (display m) (* n m))
|
281
|
-
define_node = AST.instantiate(:ast_identifier_definition, @lexer.next_token.literal)
|
282
|
-
|
283
|
-
case @lexer.peek_token.type
|
284
|
-
when :identifier
|
285
|
-
# type 1 and type 2
|
286
|
-
define_node.identifier = parse_identifier
|
287
|
-
define_node.expression = parse_expression
|
288
|
-
skip_rparen
|
289
|
-
when :lparen
|
290
|
-
# type 3:
|
291
|
-
# make a lambda expression, then handle as type 2
|
292
|
-
skip_lparen
|
293
|
-
define_node.identifier = parse_identifier
|
294
|
-
def_formals_node = AST.instantiate(:ast_formals, nil)
|
295
|
-
Kernel.loop {
|
296
|
-
break if @lexer.peek_token.type == :rparen
|
297
|
-
def_formals_node.add_identifier(parse_identifier)
|
298
|
-
}
|
299
|
-
skip_rparen
|
300
|
-
|
301
|
-
lambda_node = make_lambda_expression_node(def_formals_node, read_body)
|
302
|
-
skip_rparen
|
303
|
-
|
304
|
-
define_node.expression = lambda_node
|
305
|
-
else
|
306
|
-
raise SchemeSyntaxErrorError, @lexer.peek_token.literal
|
307
|
-
end
|
308
|
-
|
309
|
-
define_node
|
310
|
-
end
|
311
|
-
|
312
|
-
def parse_define_syntax
|
313
|
-
not_implemented_yet("DEFINE-SYNTAX")
|
314
|
-
end
|
315
|
-
|
316
|
-
def parse_define_values
|
317
|
-
not_implemented_yet("DEFINE-VALUES")
|
318
|
-
end
|
319
|
-
|
320
|
-
def parse_define_record_type
|
321
|
-
not_implemented_yet("DEFINE-RECORD-TYPE")
|
322
|
-
end
|
323
|
-
|
324
|
-
def parse_includer
|
325
|
-
not_implemented_yet("INCLUDE or INCLUDE-CI")
|
326
|
-
end
|
327
|
-
|
328
|
-
def parse_derived_expression
|
329
|
-
literal = @lexer.next_token.literal
|
330
|
-
name = compose_method_name("parse_", literal).intern
|
331
|
-
if self.respond_to?(name)
|
332
|
-
m = self.method(name)
|
333
|
-
m.call
|
334
|
-
else
|
335
|
-
not_implemented_yet(literal)
|
15
|
+
module Utils
|
16
|
+
def ast?(obj)
|
17
|
+
obj.kind_of?(AST::Node)
|
336
18
|
end
|
337
|
-
end
|
338
|
-
|
339
|
-
def parse_cond
|
340
|
-
cond_node = AST.instantiate(:ast_cond, nil)
|
341
|
-
Kernel.loop {
|
342
|
-
break if @lexer.peek_token.type == :rparen
|
343
|
-
cond_node.add_clause(parse_cond_clause)
|
344
|
-
}
|
345
|
-
skip_rparen
|
346
|
-
cond_node
|
347
|
-
end
|
348
|
-
|
349
|
-
def parse_cond_clause
|
350
|
-
skip_lparen
|
351
|
-
clause_node = AST.instantiate(:ast_cond_clause, nil)
|
352
|
-
# type 1: ( <test> )
|
353
|
-
# type 2: ( <test> => <expression> )
|
354
|
-
# type 3: ( <test> <sequence> )
|
355
|
-
# type 4: ( else <sequence> )
|
356
|
-
clause_node.test = parse_test
|
357
|
-
Kernel.loop {
|
358
|
-
break if @lexer.peek_token.type == :rparen
|
359
|
-
clause_node.add_expression(parse_expression)
|
360
|
-
}
|
361
|
-
skip_rparen
|
362
|
-
clause_node
|
363
|
-
end
|
364
|
-
|
365
|
-
def parse_case
|
366
|
-
not_implemented_yet("CASE")
|
367
|
-
end
|
368
|
-
|
369
|
-
def parse_and
|
370
|
-
parse_logical_test("and")
|
371
|
-
end
|
372
|
-
|
373
|
-
def parse_or
|
374
|
-
parse_logical_test("or")
|
375
|
-
end
|
376
19
|
|
377
|
-
|
378
|
-
|
379
|
-
node = AST.instantiate(ast_type, nil)
|
380
|
-
Kernel.loop {
|
381
|
-
break if @lexer.peek_token.type == :rparen
|
382
|
-
node << parse_test
|
383
|
-
}
|
384
|
-
skip_rparen
|
385
|
-
node
|
386
|
-
end
|
387
|
-
|
388
|
-
def parse_when
|
389
|
-
parse_test_and_sequence("when")
|
390
|
-
end
|
391
|
-
|
392
|
-
def parse_unless
|
393
|
-
parse_test_and_sequence("unless")
|
394
|
-
end
|
395
|
-
|
396
|
-
def parse_test_and_sequence(type)
|
397
|
-
ast_type = "ast_#{type}".intern
|
398
|
-
node = AST.instantiate(ast_type, nil)
|
399
|
-
node.test = parse_test
|
400
|
-
Kernel.loop {
|
401
|
-
break if @lexer.peek_token.type == :rparen
|
402
|
-
node << parse_expression
|
403
|
-
}
|
404
|
-
skip_rparen
|
405
|
-
node
|
406
|
-
end
|
407
|
-
|
408
|
-
def parse_let
|
409
|
-
let_node = AST.instantiate(:ast_let, nil)
|
410
|
-
if @lexer.peek_token.type == :identifier
|
411
|
-
let_node.identifier = parse_identifier
|
20
|
+
def ast_type?(obj, type)
|
21
|
+
ast?(obj) && obj.type == type
|
412
22
|
end
|
413
|
-
let_node.bindings = parse_bindings
|
414
|
-
let_node.body = read_body
|
415
|
-
skip_rparen
|
416
|
-
let_node
|
417
|
-
end
|
418
|
-
|
419
|
-
def parse_bindings
|
420
|
-
bindings_node = AST.instantiate(:ast_bindings, nil)
|
421
|
-
skip_lparen
|
422
|
-
Kernel.loop {
|
423
|
-
break if @lexer.peek_token.type == :rparen
|
424
|
-
bindings_node.add_bind_spec(parse_bind_spec)
|
425
|
-
}
|
426
|
-
skip_rparen
|
427
|
-
bindings_node
|
428
|
-
end
|
429
|
-
|
430
|
-
def parse_bind_spec
|
431
|
-
spec_node = AST.instantiate(:ast_bind_spec, nil)
|
432
|
-
skip_lparen
|
433
|
-
spec_node.identifier = parse_identifier
|
434
|
-
spec_node.expression = parse_expression
|
435
|
-
skip_rparen
|
436
|
-
spec_node
|
437
|
-
end
|
438
|
-
|
439
|
-
def parse_let_star
|
440
|
-
parse_let_base("let_star")
|
441
|
-
end
|
442
|
-
|
443
|
-
def parse_letrec
|
444
|
-
parse_let_base("letrec")
|
445
|
-
end
|
446
|
-
|
447
|
-
def parse_letrec_star
|
448
|
-
parse_let_base("letrec_star")
|
449
|
-
end
|
450
23
|
|
451
|
-
|
452
|
-
|
453
|
-
node = AST.instantiate(ast_type, nil)
|
454
|
-
node.bindings = parse_bindings
|
455
|
-
node.body = read_body
|
456
|
-
skip_rparen
|
457
|
-
node
|
458
|
-
end
|
459
|
-
|
460
|
-
def parse_let_values
|
461
|
-
not_implemented_yet("LET-VALUES")
|
462
|
-
end
|
463
|
-
|
464
|
-
def parse_let_star_values
|
465
|
-
not_implemented_yet("LET*-VALUES")
|
466
|
-
end
|
467
|
-
|
468
|
-
def parse_begin
|
469
|
-
begin_node = AST.instantiate(:ast_begin, nil)
|
470
|
-
Kernel.loop {
|
471
|
-
break if @lexer.peek_token.type == :rparen
|
472
|
-
begin_node << parse_expression
|
473
|
-
}
|
474
|
-
skip_rparen
|
475
|
-
begin_node
|
476
|
-
end
|
477
|
-
|
478
|
-
def parse_do
|
479
|
-
do_node = AST.instantiate(:ast_do, nil)
|
480
|
-
do_node.iteration_bindings = parse_iteration_bindings
|
481
|
-
do_node.test_and_do_result = parse_test_and_do_result
|
482
|
-
Kernel.loop {
|
483
|
-
break if @lexer.peek_token.type == :rparen
|
484
|
-
do_node.add_command(parse_expression)
|
485
|
-
}
|
486
|
-
skip_rparen
|
487
|
-
do_node
|
488
|
-
end
|
489
|
-
|
490
|
-
def parse_iteration_bindings
|
491
|
-
node = AST.instantiate(:ast_iteration_bindings, nil)
|
492
|
-
skip_lparen
|
493
|
-
Kernel.loop {
|
494
|
-
break if @lexer.peek_token.type == :rparen
|
495
|
-
node.add_iteration_spec(parse_iteration_spec)
|
496
|
-
}
|
497
|
-
skip_rparen
|
498
|
-
node
|
499
|
-
end
|
500
|
-
|
501
|
-
def parse_iteration_spec
|
502
|
-
spec_node = AST.instantiate(:ast_iteration_spec, nil)
|
503
|
-
skip_lparen
|
504
|
-
spec_node.identifier = parse_identifier
|
505
|
-
spec_node.init = parse_init
|
506
|
-
if @lexer.peek_token.type != :rparen
|
507
|
-
spec_node.step = parse_step
|
24
|
+
def not_implemented_yet(feature)
|
25
|
+
raise NotImplementedYetError, feature
|
508
26
|
end
|
509
|
-
skip_rparen
|
510
|
-
spec_node
|
511
|
-
end
|
512
|
-
|
513
|
-
def parse_init
|
514
|
-
parse_expression
|
515
|
-
end
|
516
|
-
|
517
|
-
def parse_step
|
518
|
-
parse_expression
|
519
|
-
end
|
520
|
-
|
521
|
-
def parse_test_and_do_result
|
522
|
-
node = AST.instantiate(:ast_test_and_do_result, nil)
|
523
|
-
skip_lparen
|
524
|
-
node << parse_test
|
525
|
-
Kernel.loop {
|
526
|
-
break if @lexer.peek_token.type == :rparen
|
527
|
-
node.add_expression(parse_expression)
|
528
|
-
}
|
529
|
-
skip_rparen
|
530
|
-
node
|
531
|
-
end
|
532
|
-
|
533
|
-
def parse_delay
|
534
|
-
not_implemented_yet("DELAY")
|
535
|
-
end
|
536
|
-
|
537
|
-
def parse_delay_force
|
538
|
-
not_implemented_yet("DELAY-FORCE")
|
539
|
-
end
|
540
|
-
|
541
|
-
def parse_parameterize
|
542
|
-
not_implemented_yet("PARAMETERIZE")
|
543
27
|
end
|
544
28
|
|
545
|
-
|
546
|
-
|
547
|
-
end
|
548
|
-
|
549
|
-
def parse_case_lambda
|
550
|
-
not_implemented_yet("CASE-LAMBDA")
|
551
|
-
end
|
29
|
+
require_relative "parser/phase1_parser"
|
30
|
+
require_relative "parser/phase2_parser"
|
552
31
|
|
553
|
-
|
32
|
+
class Parser
|
33
|
+
include Utils
|
554
34
|
|
555
|
-
|
556
|
-
|
557
|
-
@lexer.skip_token
|
558
|
-
else
|
559
|
-
raise UnexpectedTokenTypeError.new(@lexer.peek_token.type, :lparen)
|
35
|
+
def self.version
|
36
|
+
Rubasteme::Parser.send(:version)
|
560
37
|
end
|
561
|
-
end
|
562
38
|
|
563
|
-
|
564
|
-
|
565
|
-
@lexer.skip_token
|
566
|
-
else
|
567
|
-
raise MissingRightParenthesisError
|
39
|
+
def version
|
40
|
+
self.class.version
|
568
41
|
end
|
569
|
-
end
|
570
42
|
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
:ast_identifier
|
575
|
-
when :boolean, :character, :number, :string
|
576
|
-
"ast_#{token_type}".intern
|
577
|
-
when :dot
|
578
|
-
:ast_dot
|
579
|
-
else
|
580
|
-
:ast_identifier
|
43
|
+
def initialize
|
44
|
+
@p1 = Phase1Parser.new
|
45
|
+
@p2 = Phase2Parser.new
|
581
46
|
end
|
582
|
-
end
|
583
47
|
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
:ast_list
|
48
|
+
def parse(lexer)
|
49
|
+
return [] if lexer.nil?
|
50
|
+
ast_program = AST.instantiate(:ast_program)
|
51
|
+
Kernel.loop{ast_program << @p2.parse(@p1.parse(lexer))}
|
52
|
+
ast_program
|
590
53
|
end
|
591
|
-
end
|
592
|
-
|
593
|
-
SCM_CHAR_TO_RB_MAP = {
|
594
|
-
"*" => "_star",
|
595
|
-
"-" => "_",
|
596
|
-
}
|
597
|
-
|
598
|
-
def compose_method_name(prefix, type_name)
|
599
|
-
converted_name = type_name.gsub(/[*\-]/, SCM_CHAR_TO_RB_MAP)
|
600
|
-
prefix + converted_name
|
601
|
-
end
|
602
|
-
|
603
|
-
def not_implemented_yet(feature)
|
604
|
-
raise NotImplementedYetError, feature
|
605
|
-
end
|
606
|
-
|
607
|
-
end # end of Parser class
|
608
|
-
|
54
|
+
end # end of Parser class
|
55
|
+
end # end of Parser module
|
609
56
|
end
|