crokus 0.0.2
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/bin/crokus +5 -0
- data/lib/crokus.rb +4 -0
- data/lib/crokus/ast.rb +431 -0
- data/lib/crokus/ast_printer.rb +86 -0
- data/lib/crokus/cfg.rb +81 -0
- data/lib/crokus/cfg_builder.rb +169 -0
- data/lib/crokus/cfg_cleaner.rb +62 -0
- data/lib/crokus/cfg_printer.rb +73 -0
- data/lib/crokus/cleaner.rb +10 -0
- data/lib/crokus/code.rb +46 -0
- data/lib/crokus/compiler.rb +124 -0
- data/lib/crokus/generic_lexer.rb +62 -0
- data/lib/crokus/indent.rb +19 -0
- data/lib/crokus/ir_dumper.rb +48 -0
- data/lib/crokus/lexer.rb +113 -0
- data/lib/crokus/parser.rb +1072 -0
- data/lib/crokus/parser_only.rb +993 -0
- data/lib/crokus/pretty_printer.rb +443 -0
- data/lib/crokus/runner.rb +86 -0
- data/lib/crokus/tac_builder.rb +109 -0
- data/lib/crokus/token.rb +43 -0
- data/lib/crokus/transformer.rb +304 -0
- data/lib/crokus/version.rb +3 -0
- data/lib/crokus/visitor.rb +341 -0
- metadata +70 -0
@@ -0,0 +1,993 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
require_relative 'lexer'
|
4
|
+
require_relative 'ast'
|
5
|
+
require_relative 'indent'
|
6
|
+
require_relative 'pretty_printer'
|
7
|
+
|
8
|
+
module Crokus
|
9
|
+
|
10
|
+
class ParserOnly
|
11
|
+
|
12
|
+
attr_accessor :tokens,:str
|
13
|
+
include Indent
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@ppr=PrettyPrinter.new
|
17
|
+
@verbose=false
|
18
|
+
#@verbose=true
|
19
|
+
end
|
20
|
+
|
21
|
+
def acceptIt
|
22
|
+
say showNext.kind.to_s+" "+showNext.val
|
23
|
+
tokens.shift
|
24
|
+
end
|
25
|
+
|
26
|
+
def maybe kind
|
27
|
+
return acceptIt if showNext.is_a? kind
|
28
|
+
end
|
29
|
+
|
30
|
+
def expect kind
|
31
|
+
if ((actual=tokens.shift).kind)!=kind
|
32
|
+
puts "ERROR :"
|
33
|
+
show_line(actual.pos)
|
34
|
+
raise "expecting '#{kind}'. Received '#{actual.val}' around #{actual.pos}"
|
35
|
+
end
|
36
|
+
say actual.kind.to_s+" "+actual.val
|
37
|
+
return actual
|
38
|
+
end
|
39
|
+
|
40
|
+
def showNext(n=1)
|
41
|
+
tokens[n-1] if tokens.any?
|
42
|
+
end
|
43
|
+
|
44
|
+
def lookahead(n=2)
|
45
|
+
tokens[n] if tokens.any?
|
46
|
+
end
|
47
|
+
|
48
|
+
def show_line pos
|
49
|
+
l,c=*pos
|
50
|
+
show_lines(str,l-2)
|
51
|
+
line=str.split(/\n/)[l-1]
|
52
|
+
pointer="-"*(5+c)+ "^"
|
53
|
+
puts "#{l.to_s.ljust(5)}|#{line}"
|
54
|
+
puts pointer
|
55
|
+
end
|
56
|
+
#--------------------------------------------------
|
57
|
+
def dbg_print_next n
|
58
|
+
p tokens[0..n-1].collect{|tok| tok.inspect}
|
59
|
+
end
|
60
|
+
|
61
|
+
def dbg_print node
|
62
|
+
puts "debug ast node".center(60,'-')
|
63
|
+
puts node.accept(@ppr)
|
64
|
+
puts "-"*60
|
65
|
+
end
|
66
|
+
#............ parsing methods ...........
|
67
|
+
def parse str
|
68
|
+
begin
|
69
|
+
@str=str
|
70
|
+
@tokens=Lexer.new.tokenize(str)
|
71
|
+
@tokens=remove_comments()
|
72
|
+
warnings=@tokens.select{|tok| tok.is_a? :lexer_warning}
|
73
|
+
show_lexer_warnings(warnings)
|
74
|
+
@tokens=@tokens.select{|tok| !tok.is_a? [:newline]}
|
75
|
+
ast=design_unit()
|
76
|
+
rescue Exception => e
|
77
|
+
puts "PARSING ERROR : #{e}"
|
78
|
+
puts "in C source at line/col #{showNext.pos}"
|
79
|
+
puts e.backtrace
|
80
|
+
abort
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def show_lexer_warnings warnings
|
85
|
+
warnings.each do |warn|
|
86
|
+
puts "lexer warning : #{warn.val} at #{warn.pos}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def remove_comments
|
91
|
+
ret=[]
|
92
|
+
in_comment=false
|
93
|
+
tokens.each do |tok|
|
94
|
+
case tok.kind
|
95
|
+
when :comment
|
96
|
+
when :lcomment
|
97
|
+
in_comment=true
|
98
|
+
when :rcomment
|
99
|
+
in_comment=false
|
100
|
+
else
|
101
|
+
ret << tok unless in_comment
|
102
|
+
end
|
103
|
+
end
|
104
|
+
ret
|
105
|
+
end
|
106
|
+
|
107
|
+
def design_unit
|
108
|
+
indent "designUnit"
|
109
|
+
du=DesignUnit.new
|
110
|
+
while tokens.any?
|
111
|
+
case showNext.kind
|
112
|
+
when :sharp
|
113
|
+
case showNext(2).val
|
114
|
+
when "include"
|
115
|
+
du << include()
|
116
|
+
when "define"
|
117
|
+
du << define()
|
118
|
+
end
|
119
|
+
else
|
120
|
+
du << declaration
|
121
|
+
maybe :semicolon if tokens.any?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
dedent
|
125
|
+
du.list.flatten!
|
126
|
+
return du
|
127
|
+
end
|
128
|
+
|
129
|
+
def include
|
130
|
+
indent "include"
|
131
|
+
expect :sharp
|
132
|
+
expect :ident #include
|
133
|
+
case showNext.kind
|
134
|
+
when :lt
|
135
|
+
acceptIt
|
136
|
+
id1=expect :ident
|
137
|
+
expect :dot
|
138
|
+
id2=expect :ident
|
139
|
+
expect :gt
|
140
|
+
name=Token.new [:ident,id1.val+"."+id2.val,id1.pos]
|
141
|
+
env=:env
|
142
|
+
when :string_lit
|
143
|
+
name=acceptIt
|
144
|
+
env=:local
|
145
|
+
end
|
146
|
+
dedent
|
147
|
+
return Include.new(name,env)
|
148
|
+
end
|
149
|
+
|
150
|
+
def define
|
151
|
+
indent "define"
|
152
|
+
expect :sharp
|
153
|
+
expect :ident #define
|
154
|
+
name=expect :ident
|
155
|
+
e=expression()
|
156
|
+
dedent
|
157
|
+
return Define.new(name,e)
|
158
|
+
end
|
159
|
+
|
160
|
+
def parse_struct
|
161
|
+
indent "struct"
|
162
|
+
expect :struct
|
163
|
+
name=nil
|
164
|
+
if showNext.is_a? :ident
|
165
|
+
name=acceptIt
|
166
|
+
end
|
167
|
+
ret=Struct.new(name)
|
168
|
+
if showNext.is_a? :lbrace
|
169
|
+
acceptIt
|
170
|
+
while !showNext.is_a? :rbrace
|
171
|
+
ret.decls << declaration()
|
172
|
+
end
|
173
|
+
ret.decls.flatten!
|
174
|
+
expect :rbrace
|
175
|
+
end
|
176
|
+
dedent
|
177
|
+
return ret
|
178
|
+
end
|
179
|
+
|
180
|
+
def typedef
|
181
|
+
indent "typedef"
|
182
|
+
expect :typedef
|
183
|
+
type=parse_type()
|
184
|
+
id=expect(:ident)
|
185
|
+
dedent
|
186
|
+
return Typedef.new(type,id)
|
187
|
+
end
|
188
|
+
|
189
|
+
def function_decl name,type_
|
190
|
+
indent "function"
|
191
|
+
args=function_formal_args()
|
192
|
+
case showNext.kind
|
193
|
+
when :semicolon
|
194
|
+
acceptIt
|
195
|
+
ret =FunctionProto.new(name,type_,args)
|
196
|
+
else
|
197
|
+
body=function_body()
|
198
|
+
ret= Function.new(name,type_,args,body)
|
199
|
+
end
|
200
|
+
dedent
|
201
|
+
return ret
|
202
|
+
end
|
203
|
+
|
204
|
+
def function_formal_args
|
205
|
+
indent "function_formal_args"
|
206
|
+
args=[]
|
207
|
+
expect :lparen
|
208
|
+
while !showNext.is_a? :rparen
|
209
|
+
args << func_formal_arg()
|
210
|
+
if !showNext.is_a? :rparen
|
211
|
+
expect :comma
|
212
|
+
end
|
213
|
+
end
|
214
|
+
expect :rparen
|
215
|
+
dedent
|
216
|
+
return args
|
217
|
+
end
|
218
|
+
|
219
|
+
def func_formal_arg
|
220
|
+
indent "function_arg"
|
221
|
+
@current_type=parse_type()
|
222
|
+
declarator
|
223
|
+
arrayed?
|
224
|
+
parenthesized?
|
225
|
+
dedent
|
226
|
+
#return FormalArg.new(name,type)
|
227
|
+
end
|
228
|
+
|
229
|
+
def function_body
|
230
|
+
indent "function_body"
|
231
|
+
body=Body.new
|
232
|
+
expect :lbrace
|
233
|
+
while showNext.kind!=:rbrace
|
234
|
+
body << statement()
|
235
|
+
end
|
236
|
+
expect :rbrace
|
237
|
+
dedent
|
238
|
+
return body
|
239
|
+
end
|
240
|
+
|
241
|
+
def statement(arg=nil)
|
242
|
+
indent "statement ...#{showNext.kind} #{showNext.pos.first}"
|
243
|
+
case showNext.kind
|
244
|
+
when :lbrace
|
245
|
+
ret=parse_body()
|
246
|
+
when :unsigned,:signed,:int,:short,:float,:double,:long,:char,:void
|
247
|
+
ret=declaration()
|
248
|
+
when :struct
|
249
|
+
ret=declaration()
|
250
|
+
when :if
|
251
|
+
ret=parse_if()
|
252
|
+
when :while
|
253
|
+
ret=parse_while()
|
254
|
+
when :for
|
255
|
+
ret=parse_for()
|
256
|
+
when :switch
|
257
|
+
ret=switch()
|
258
|
+
when :return
|
259
|
+
ret=parse_return
|
260
|
+
when :break
|
261
|
+
acceptIt
|
262
|
+
ret=Break.new
|
263
|
+
when :do
|
264
|
+
ret=do_while()
|
265
|
+
when :goto
|
266
|
+
ret=parse_goto()
|
267
|
+
when :ident
|
268
|
+
case showNext(2).kind
|
269
|
+
when :ident
|
270
|
+
declaration
|
271
|
+
when :colon
|
272
|
+
parse_label
|
273
|
+
statement
|
274
|
+
else
|
275
|
+
expression_statement
|
276
|
+
end
|
277
|
+
when :const,:volatile
|
278
|
+
declaration
|
279
|
+
when :semicolon
|
280
|
+
expression_statement
|
281
|
+
else
|
282
|
+
show_line(showNext.pos)
|
283
|
+
raise "unknown statement start at #{showNext.pos} .Got #{showNext.kind} #{showNext.val}"
|
284
|
+
end
|
285
|
+
dedent
|
286
|
+
return ret
|
287
|
+
end
|
288
|
+
|
289
|
+
def parse_label
|
290
|
+
expect :ident
|
291
|
+
expect :colon
|
292
|
+
end
|
293
|
+
|
294
|
+
def parse_goto
|
295
|
+
indent "goto"
|
296
|
+
expect :goto #label
|
297
|
+
id=expect(:ident)
|
298
|
+
dedent
|
299
|
+
Goto.new(id)
|
300
|
+
end
|
301
|
+
|
302
|
+
def do_while
|
303
|
+
indent "do_while"
|
304
|
+
expect :do
|
305
|
+
body=statement()
|
306
|
+
expect :while
|
307
|
+
e=expression
|
308
|
+
dedent
|
309
|
+
DoWhile.new(e,body)
|
310
|
+
end
|
311
|
+
|
312
|
+
def switch
|
313
|
+
indent "switch"
|
314
|
+
expect :switch
|
315
|
+
expect :lparen
|
316
|
+
e=expression
|
317
|
+
ret=Switch.new(e,cases=[])
|
318
|
+
expect :rparen
|
319
|
+
expect :lbrace
|
320
|
+
while showNext.is_a? :case
|
321
|
+
expect :case
|
322
|
+
case_e=expression
|
323
|
+
case_body=Body.new
|
324
|
+
expect :colon
|
325
|
+
while showNext.kind!=:rbrace and showNext.kind!=:case and showNext.kind!=:default
|
326
|
+
case_body << statement()
|
327
|
+
end
|
328
|
+
cases << Case.new(case_e,case_body)
|
329
|
+
end
|
330
|
+
if showNext.is_a? :default
|
331
|
+
acceptIt
|
332
|
+
expect :colon
|
333
|
+
while showNext.kind!=:rbrace
|
334
|
+
statement()
|
335
|
+
end
|
336
|
+
end
|
337
|
+
expect :rbrace
|
338
|
+
dedent
|
339
|
+
return ret
|
340
|
+
end
|
341
|
+
|
342
|
+
def parse_return
|
343
|
+
indent "parse_return"
|
344
|
+
expect :return
|
345
|
+
if showNext.is_a? :semicolon
|
346
|
+
else
|
347
|
+
e=expression
|
348
|
+
end
|
349
|
+
dedent
|
350
|
+
Return.new(e)
|
351
|
+
end
|
352
|
+
|
353
|
+
# int a
|
354
|
+
# int * a
|
355
|
+
# int a=1,b=2;
|
356
|
+
# int a[]
|
357
|
+
# int* f()
|
358
|
+
# struct name *ptr;
|
359
|
+
# paire_t paire = {1,2};
|
360
|
+
# int a,b[10],*c
|
361
|
+
#------------------------------
|
362
|
+
# TYPE ident
|
363
|
+
# ident ident
|
364
|
+
|
365
|
+
def declaration
|
366
|
+
ret=[]
|
367
|
+
@current_type=type=parse_type()
|
368
|
+
declarator()
|
369
|
+
arrayed?
|
370
|
+
parenthesized?
|
371
|
+
initialization?
|
372
|
+
while tokens.any? and showNext.is_a?(:comma)
|
373
|
+
acceptIt
|
374
|
+
pointed?
|
375
|
+
declarator
|
376
|
+
arrayed?
|
377
|
+
initialization?
|
378
|
+
end
|
379
|
+
if tokens.any?
|
380
|
+
maybe :semicolon
|
381
|
+
end
|
382
|
+
return ret
|
383
|
+
end
|
384
|
+
|
385
|
+
def declarator
|
386
|
+
if showNext.is_a? :ident
|
387
|
+
ret=@current_ident=Ident.new(acceptIt)
|
388
|
+
end
|
389
|
+
return ret
|
390
|
+
end
|
391
|
+
|
392
|
+
def pointed?
|
393
|
+
return if tokens.empty?
|
394
|
+
while showNext.is_a? :mul
|
395
|
+
acceptIt
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
def arrayed?
|
400
|
+
return if tokens.empty?
|
401
|
+
while showNext.is_a? :lbrack
|
402
|
+
acceptIt
|
403
|
+
if showNext.is_a? :rbrack
|
404
|
+
acceptIt
|
405
|
+
else
|
406
|
+
e=expression
|
407
|
+
expect :rbrack
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
def initialization?
|
413
|
+
return if tokens.empty?
|
414
|
+
if showNext.is_a? :assign
|
415
|
+
expect :assign
|
416
|
+
expression
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
def parenthesized?
|
421
|
+
return if tokens.empty?
|
422
|
+
if showNext.is_a? :lparen
|
423
|
+
function_decl(@current_ident,@current_type)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def func_call as_procedure=false
|
428
|
+
indent "func_call"
|
429
|
+
name=expect(:ident)
|
430
|
+
expect :lparen
|
431
|
+
args=[]
|
432
|
+
while !showNext.is_a? :rparen
|
433
|
+
args << expression()
|
434
|
+
if showNext.is_a? :comma
|
435
|
+
acceptIt
|
436
|
+
end
|
437
|
+
end
|
438
|
+
expect :rparen
|
439
|
+
dedent
|
440
|
+
FunCall.new(name,args,as_procedure)
|
441
|
+
end
|
442
|
+
|
443
|
+
def parse_type
|
444
|
+
indent "parse_type"
|
445
|
+
qualifier=type_qualifier?()
|
446
|
+
case showNext.kind
|
447
|
+
when :signed,:unsigned
|
448
|
+
acceptIt
|
449
|
+
when :ident,:char,:int,:short,:long,:float,:double,:void
|
450
|
+
tok=acceptIt
|
451
|
+
ret=Type.new(tok)
|
452
|
+
(ret.specifiers << qualifier) if qualifier
|
453
|
+
when :struct
|
454
|
+
struct=parse_struct()
|
455
|
+
when :typedef
|
456
|
+
typedef()
|
457
|
+
else
|
458
|
+
raise "Parsing ERROR in type declaration: '#{showNext}'"
|
459
|
+
end
|
460
|
+
while showNext.is_a? [:mul,:lparen]
|
461
|
+
case showNext.kind
|
462
|
+
when :mul
|
463
|
+
acceptIt
|
464
|
+
when :lparen
|
465
|
+
acceptIt
|
466
|
+
if showNext.is_a? :rparen
|
467
|
+
acceptIt
|
468
|
+
else
|
469
|
+
expression
|
470
|
+
expect :rparen
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
dedent
|
475
|
+
return ret
|
476
|
+
end
|
477
|
+
|
478
|
+
def type_qualifier?
|
479
|
+
while showNext.is_a? STARTERS_TYPE_QUALIFIER
|
480
|
+
case showNext.kind
|
481
|
+
when :volatile
|
482
|
+
acceptIt
|
483
|
+
when :const
|
484
|
+
acceptIt
|
485
|
+
end
|
486
|
+
end
|
487
|
+
nil
|
488
|
+
end
|
489
|
+
|
490
|
+
def parse_if
|
491
|
+
indent "parse_if"
|
492
|
+
expect :if
|
493
|
+
if showNext.is_a? :lparen # helps wrt casting.
|
494
|
+
acceptIt
|
495
|
+
lparen=true
|
496
|
+
end
|
497
|
+
cond=expression()
|
498
|
+
expect :rparen if lparen
|
499
|
+
body=statement()
|
500
|
+
if showNext.is_a? :else
|
501
|
+
else_=parse_else()
|
502
|
+
end
|
503
|
+
dedent
|
504
|
+
return If.new(cond,body,else_)
|
505
|
+
end
|
506
|
+
|
507
|
+
def parse_else
|
508
|
+
indent "parse else"
|
509
|
+
expect :else
|
510
|
+
ret=Else.new
|
511
|
+
ret.body=statement()
|
512
|
+
dedent
|
513
|
+
return ret
|
514
|
+
end
|
515
|
+
|
516
|
+
def parse_while
|
517
|
+
indent "parse_while"
|
518
|
+
expect :while
|
519
|
+
cond=expression()
|
520
|
+
body=[]
|
521
|
+
body << statement()
|
522
|
+
dedent
|
523
|
+
return While.new(cond,body)
|
524
|
+
end
|
525
|
+
|
526
|
+
def parse_for
|
527
|
+
indent "parse_for"
|
528
|
+
forloop=For.new
|
529
|
+
expect :for
|
530
|
+
expect :lparen
|
531
|
+
forloop.init=expression_statement()
|
532
|
+
forloop.cond=expression_statement()
|
533
|
+
forloop.increment=expression()
|
534
|
+
expect :rparen
|
535
|
+
forloop.body=statement()
|
536
|
+
dedent
|
537
|
+
forloop
|
538
|
+
end
|
539
|
+
|
540
|
+
def parseLoopInit
|
541
|
+
indent "parseLoopInit"
|
542
|
+
ret=statement()
|
543
|
+
dedent
|
544
|
+
return [ret] # because for (int a,b=0;i<10;i++) is also possible.
|
545
|
+
# then parser returns an array of Decl
|
546
|
+
end
|
547
|
+
|
548
|
+
def parseLoopCond
|
549
|
+
indent "parseLoopCond"
|
550
|
+
e=expression()
|
551
|
+
dedent
|
552
|
+
return e
|
553
|
+
end
|
554
|
+
|
555
|
+
def parseLoopEnd
|
556
|
+
indent "parseLoopEnd"
|
557
|
+
s=statement()
|
558
|
+
dedent
|
559
|
+
return s
|
560
|
+
end
|
561
|
+
|
562
|
+
def accu
|
563
|
+
indent "accu"
|
564
|
+
#expect(:ident)
|
565
|
+
lhs=expression
|
566
|
+
case showNext.kind
|
567
|
+
when :addadd,:subsub
|
568
|
+
tok=acceptIt
|
569
|
+
when :addeq,:subeq
|
570
|
+
tok=acceptIt
|
571
|
+
e=expression
|
572
|
+
else
|
573
|
+
show_line(showNext.pos)
|
574
|
+
raise "unknown accumulator at #{showNext.pos}"
|
575
|
+
end
|
576
|
+
dedent
|
577
|
+
Accu.new(lhs,tok,e)
|
578
|
+
end
|
579
|
+
|
580
|
+
def parse_body
|
581
|
+
body=Body.new
|
582
|
+
expect :lbrace
|
583
|
+
while !showNext.is_a? :rbrace
|
584
|
+
body << statement()
|
585
|
+
end
|
586
|
+
expect :rbrace
|
587
|
+
return body
|
588
|
+
end
|
589
|
+
|
590
|
+
def expression_statement
|
591
|
+
if showNext.is_a? :semicolon
|
592
|
+
return SemicolonStmt.new(acceptIt)
|
593
|
+
else
|
594
|
+
e=expression
|
595
|
+
expect :semicolon
|
596
|
+
return e
|
597
|
+
end
|
598
|
+
end
|
599
|
+
#===============================================================
|
600
|
+
def debug
|
601
|
+
puts " "*@indentation+@tokens[0..4].map{|t| "'#{t.val}'"}.join(" ")
|
602
|
+
end
|
603
|
+
#===============================================================
|
604
|
+
def expression
|
605
|
+
indent "expression : #{showNext}"
|
606
|
+
e1=assign()
|
607
|
+
while showNext.is_a? :comma
|
608
|
+
acceptIt
|
609
|
+
e2=assign()
|
610
|
+
e1=CommaStmt.new(e1,e2)
|
611
|
+
end
|
612
|
+
dedent
|
613
|
+
return e1
|
614
|
+
end
|
615
|
+
|
616
|
+
STARTERS_ARRAY_OR_STRUCT_INIT=[:lbrace]
|
617
|
+
STARTERS_PRIMARY=[:ident,:integer_lit,:float_lit,:string_lit,:char_lit,:lparen]+STARTERS_ARRAY_OR_STRUCT_INIT
|
618
|
+
UNARY_OP=[:and,:mul,:add,:sub,:tilde,:not]
|
619
|
+
STARTERS_UNARY=[:inc_op,:dec_op,:sizeof]+STARTERS_PRIMARY+UNARY_OP
|
620
|
+
ASSIGN_OP=[:assign,:add_assign,:mul_assign,:div_assign,:mod_assign,:xor_assign]
|
621
|
+
|
622
|
+
def assign
|
623
|
+
indent "assign : #{showNext}"
|
624
|
+
e1=cond_expr
|
625
|
+
while showNext.is_a? ASSIGN_OP
|
626
|
+
op=acceptIt
|
627
|
+
e2=assign
|
628
|
+
e1=Assign.new(e1,op,e2)
|
629
|
+
end
|
630
|
+
dedent
|
631
|
+
return e1
|
632
|
+
end
|
633
|
+
|
634
|
+
def cond_expr
|
635
|
+
indent "cond_expr : #{showNext}"
|
636
|
+
logor
|
637
|
+
while showNext.is_a? :qmark
|
638
|
+
acceptIt
|
639
|
+
expression
|
640
|
+
expect :colon
|
641
|
+
cond_expr
|
642
|
+
end
|
643
|
+
dedent
|
644
|
+
end
|
645
|
+
|
646
|
+
def logor
|
647
|
+
indent "logor : #{showNext}"
|
648
|
+
logand
|
649
|
+
while showNext.is_a? :oror
|
650
|
+
acceptIt
|
651
|
+
logand
|
652
|
+
end
|
653
|
+
dedent
|
654
|
+
end
|
655
|
+
|
656
|
+
def logand
|
657
|
+
indent "logand : #{showNext}"
|
658
|
+
inclor
|
659
|
+
while showNext.is_a? :andand
|
660
|
+
acceptIt
|
661
|
+
inclor
|
662
|
+
end
|
663
|
+
dedent
|
664
|
+
end
|
665
|
+
|
666
|
+
def inclor
|
667
|
+
indent "inclor : #{showNext}"
|
668
|
+
exclor
|
669
|
+
while showNext.is_a? :or
|
670
|
+
acceptIt
|
671
|
+
exclor
|
672
|
+
end
|
673
|
+
dedent
|
674
|
+
end
|
675
|
+
|
676
|
+
def exclor
|
677
|
+
indent "exclor : #{showNext}"
|
678
|
+
andexp
|
679
|
+
while showNext.is_a? :xor
|
680
|
+
acceptIt
|
681
|
+
andexp
|
682
|
+
end
|
683
|
+
dedent
|
684
|
+
end
|
685
|
+
|
686
|
+
def andexp
|
687
|
+
indent "andexp : #{showNext}"
|
688
|
+
eqexp
|
689
|
+
while showNext.is_a? :and
|
690
|
+
acceptIt
|
691
|
+
eqexp
|
692
|
+
end
|
693
|
+
dedent
|
694
|
+
end
|
695
|
+
|
696
|
+
def eqexp
|
697
|
+
indent "eqexp : #{showNext}"
|
698
|
+
relexp
|
699
|
+
while showNext.is_a? [:eq,:neq]
|
700
|
+
acceptIt
|
701
|
+
relexp
|
702
|
+
end
|
703
|
+
dedent
|
704
|
+
end
|
705
|
+
|
706
|
+
def relexp
|
707
|
+
indent "relexp : #{showNext}"
|
708
|
+
shiftexp
|
709
|
+
while showNext.is_a? [:lte,:lt,:gte,:gt ]
|
710
|
+
acceptIt
|
711
|
+
shiftexp
|
712
|
+
end
|
713
|
+
dedent
|
714
|
+
end
|
715
|
+
|
716
|
+
def shiftexp
|
717
|
+
indent "shiftexp : #{showNext}"
|
718
|
+
additive
|
719
|
+
while showNext.is_a? [:shift_l,:shift_r]
|
720
|
+
acceptIt
|
721
|
+
additive
|
722
|
+
end
|
723
|
+
dedent
|
724
|
+
end
|
725
|
+
|
726
|
+
def additive
|
727
|
+
indent "addititve : #{showNext}"
|
728
|
+
multitive
|
729
|
+
while showNext.is_a? [:add,:sub]
|
730
|
+
acceptIt
|
731
|
+
multitive
|
732
|
+
end
|
733
|
+
dedent
|
734
|
+
end
|
735
|
+
|
736
|
+
def multitive
|
737
|
+
indent "multitive : #{showNext}"
|
738
|
+
castexp
|
739
|
+
while showNext.is_a? [:mul,:div,:mod]
|
740
|
+
acceptIt
|
741
|
+
castexp
|
742
|
+
end
|
743
|
+
dedent
|
744
|
+
end
|
745
|
+
|
746
|
+
def castexp
|
747
|
+
indent "castexpr : #{showNext}"
|
748
|
+
case showNext.kind
|
749
|
+
when :lparen # parenth expr OR casting !
|
750
|
+
res=is_casting?
|
751
|
+
puts "casting? : #{res}" if @verbose
|
752
|
+
if res
|
753
|
+
casting
|
754
|
+
else
|
755
|
+
parenthesized
|
756
|
+
end
|
757
|
+
else
|
758
|
+
unary
|
759
|
+
end
|
760
|
+
dedent
|
761
|
+
end
|
762
|
+
|
763
|
+
def is_casting?
|
764
|
+
i=0
|
765
|
+
tok=DUMMY
|
766
|
+
while tok.kind!=:rparen
|
767
|
+
tok=@tokens[i]
|
768
|
+
i+=1
|
769
|
+
end
|
770
|
+
tok=@tokens[i]
|
771
|
+
return true if tok.is_a? STARTERS_UNARY-STARTERS_ARRAY_OR_STRUCT_INIT
|
772
|
+
return false
|
773
|
+
end
|
774
|
+
|
775
|
+
def casting
|
776
|
+
indent "casting : #{showNext}"
|
777
|
+
expect :lparen
|
778
|
+
typename
|
779
|
+
expect :rparen
|
780
|
+
unary
|
781
|
+
dedent
|
782
|
+
end
|
783
|
+
|
784
|
+
def parenthesized
|
785
|
+
indent "parenthesized : #{showNext}"
|
786
|
+
expect :lparen
|
787
|
+
expression
|
788
|
+
expect :rparen
|
789
|
+
dedent
|
790
|
+
end
|
791
|
+
|
792
|
+
def typename
|
793
|
+
indent "typename"
|
794
|
+
spec_qualifier_list
|
795
|
+
while showNext.is_a? STARTERS_ABSTRACT_DECLARATOR
|
796
|
+
abstract_decl
|
797
|
+
end
|
798
|
+
dedent
|
799
|
+
end
|
800
|
+
|
801
|
+
def spec_qualifier_list
|
802
|
+
indent "spec_qualifier_list #{showNext.inspect}"
|
803
|
+
while showNext.is_a? STARTERS_TYPE_SPECIFIER+STARTERS_TYPE_QUALIFIER
|
804
|
+
if showNext.is_a? STARTERS_TYPE_SPECIFIER
|
805
|
+
type_specifier
|
806
|
+
else
|
807
|
+
type_qualifier
|
808
|
+
end
|
809
|
+
end
|
810
|
+
dedent
|
811
|
+
end
|
812
|
+
|
813
|
+
STARTERS_TYPE_SPECIFIER=[:void,:char,:short,:int,:long,:float,:signed,:unsigned,:struct,:union,:enum,:ident]
|
814
|
+
def type_specifier
|
815
|
+
indent "type_specifier #{showNext}"
|
816
|
+
if showNext.is_a? STARTERS_TYPE_SPECIFIER
|
817
|
+
acceptIt
|
818
|
+
else
|
819
|
+
raise "ERROR : type_specifier. Expecting one of '#{STARTERS_TYPE_SPECIFIER}' at #{showNext.pos}"
|
820
|
+
end
|
821
|
+
dedent
|
822
|
+
end
|
823
|
+
|
824
|
+
# abstract_declarator
|
825
|
+
# : pointer
|
826
|
+
# | direct_abstract_declarator
|
827
|
+
# | pointer direct_abstract_declarator
|
828
|
+
# ;
|
829
|
+
STARTERS_ABSTRACT_DECLARATOR=[:mul,:lparen,:lbrack]
|
830
|
+
def abstract_decl
|
831
|
+
indent "abstract_decl"
|
832
|
+
if showNext.is_a? STARTERS_ABSTRACT_DECLARATOR
|
833
|
+
case showNext.kind
|
834
|
+
when :mul
|
835
|
+
pointer
|
836
|
+
else
|
837
|
+
direct_abstract_declarator
|
838
|
+
end
|
839
|
+
else
|
840
|
+
raise "ERROR : in abstract_declarator. Expecting one of #{STARTERS_ABSTRACT_DECLARATOR}"
|
841
|
+
end
|
842
|
+
dedent
|
843
|
+
end
|
844
|
+
|
845
|
+
# pointer
|
846
|
+
# : '*'
|
847
|
+
# | '*' type_qualifier_list
|
848
|
+
# | '*' pointer
|
849
|
+
# | '*' type_qualifier_list pointer
|
850
|
+
# ;
|
851
|
+
STARTERS_TYPE_QUALIFIER=[:const,:volatile]
|
852
|
+
def pointer
|
853
|
+
expect :mul
|
854
|
+
while showNext.is_a? STARTERS_TYPE_QUALIFIER+[:mul]
|
855
|
+
case showNext.kind
|
856
|
+
when :volatile
|
857
|
+
acceptIt
|
858
|
+
when :const
|
859
|
+
acceptIt
|
860
|
+
when :mult
|
861
|
+
acceptIt
|
862
|
+
end
|
863
|
+
end
|
864
|
+
end
|
865
|
+
|
866
|
+
def direct_abstract_declarator
|
867
|
+
raise
|
868
|
+
end
|
869
|
+
|
870
|
+
def unary
|
871
|
+
if STARTERS_PRIMARY.include? showNext.kind
|
872
|
+
postfix
|
873
|
+
elsif showNext.is_a? [:and,:mul,:add,:sub,:tilde,:not]
|
874
|
+
acceptIt
|
875
|
+
castexp
|
876
|
+
else
|
877
|
+
case showNext.kind
|
878
|
+
when :inc_op
|
879
|
+
acceptIt
|
880
|
+
unary
|
881
|
+
when :dec_op
|
882
|
+
acceptIt
|
883
|
+
unary
|
884
|
+
when :sizeof
|
885
|
+
sizeof()
|
886
|
+
else
|
887
|
+
raise "not an unary"
|
888
|
+
end
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
def sizeof
|
893
|
+
expect :sizeof
|
894
|
+
case showNext.kind
|
895
|
+
when :lparen
|
896
|
+
acceptIt
|
897
|
+
typename
|
898
|
+
expect :rparen
|
899
|
+
else
|
900
|
+
unary
|
901
|
+
end
|
902
|
+
end
|
903
|
+
|
904
|
+
def postfix
|
905
|
+
indent "postfix : #{showNext}"
|
906
|
+
primary
|
907
|
+
while showNext.is_a? [:lbrack,:lparen,:dot,:inc_op,:dec_op,:ptr_op]
|
908
|
+
case showNext.kind
|
909
|
+
when :lbrack
|
910
|
+
acceptIt
|
911
|
+
expression
|
912
|
+
expect :rbrack
|
913
|
+
when :lparen
|
914
|
+
acceptIt
|
915
|
+
if !showNext.is_a? :rparen
|
916
|
+
argument_expr_list
|
917
|
+
end
|
918
|
+
expect :rparen
|
919
|
+
when :dot
|
920
|
+
acceptIt
|
921
|
+
expect :ident
|
922
|
+
when :ptr_op
|
923
|
+
acceptIt
|
924
|
+
expect :ident
|
925
|
+
when :inc_op
|
926
|
+
acceptIt
|
927
|
+
when :dec_op
|
928
|
+
acceptIt
|
929
|
+
end
|
930
|
+
end
|
931
|
+
dedent
|
932
|
+
end
|
933
|
+
|
934
|
+
def primary
|
935
|
+
case showNext.kind
|
936
|
+
when :ident
|
937
|
+
return Ident.new(acceptIt)
|
938
|
+
when :integer_lit
|
939
|
+
return IntLit.new(acceptIt)
|
940
|
+
when :float_lit
|
941
|
+
return FloatLit.new(acceptIt)
|
942
|
+
when :string_lit
|
943
|
+
return acceptIt
|
944
|
+
when :char_lit
|
945
|
+
return acceptIt
|
946
|
+
when :lparen
|
947
|
+
acceptIt
|
948
|
+
e=expression
|
949
|
+
expect :rparen
|
950
|
+
return Parenth.new(e)
|
951
|
+
when :lbrace
|
952
|
+
return array_or_struct_init()
|
953
|
+
end
|
954
|
+
end
|
955
|
+
|
956
|
+
def argument_expr_list
|
957
|
+
expression
|
958
|
+
while showNext.is_a? :comma
|
959
|
+
acceptIt
|
960
|
+
expression
|
961
|
+
end
|
962
|
+
end
|
963
|
+
|
964
|
+
def array_or_struct_init
|
965
|
+
indent "array_or_struct_init"
|
966
|
+
expect :lbrace
|
967
|
+
elements=[]
|
968
|
+
while !showNext.is_a? :rbrace
|
969
|
+
elements << (e=expression)
|
970
|
+
if showNext.is_a? :comma
|
971
|
+
acceptIt
|
972
|
+
end
|
973
|
+
end
|
974
|
+
expect :rbrace
|
975
|
+
dedent
|
976
|
+
return ArrayOrStructInit.new(elements)
|
977
|
+
end
|
978
|
+
|
979
|
+
end#class Parser
|
980
|
+
end #module
|
981
|
+
|
982
|
+
if $PROGRAM_NAME == __FILE__
|
983
|
+
require_relative 'dot_printer_rec'
|
984
|
+
str=IO.read(ARGV[0])
|
985
|
+
show_lines(str)
|
986
|
+
t1 = Time.now
|
987
|
+
parser=C::Parser.new
|
988
|
+
ast=parser.parse(str)
|
989
|
+
dot=C::DotPrinter.new.print(ast)
|
990
|
+
dot.save_as "test.dot"
|
991
|
+
t2 = Time.now
|
992
|
+
puts "parsed in : #{t2-t1} s"
|
993
|
+
end
|