crokus 0.1.3 → 0.1.9
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/bin/crokus +0 -0
- data/lib/crokus/ast.rb +7 -0
- data/lib/crokus/cfg_builder.rb +10 -0
- data/lib/crokus/cfg_cleaner.rb +1 -1
- data/lib/crokus/cfg_optim.rb +31 -0
- data/lib/crokus/cfg_printer.rb +1 -0
- data/lib/crokus/cfg_printer_only.rb +24 -0
- data/lib/crokus/cfg_printer_only_dot.rb +54 -0
- data/lib/crokus/cfg_printer_only_json.rb +45 -0
- data/lib/crokus/cfg_random_gen.rb +24 -0
- data/lib/crokus/cleaner.rb +8 -3
- data/lib/crokus/compiler.rb +24 -2
- data/lib/crokus/pretty_printer.rb +5 -0
- data/lib/crokus/runner.rb +17 -2
- data/lib/crokus/token.rb +2 -0
- data/lib/crokus/trojan_inserter.rb +47 -8
- data/lib/crokus/version.rb +1 -1
- data/lib/crokus/visitor.rb +65 -65
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16ac10dda4aa48100822c10d91bb98b51c35ca9066bacec035d5506c1933d75b
|
4
|
+
data.tar.gz: 02eef79bfb835434b1291b0a455815af0033bd492df11380859bf52357117d10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c07b2bdc63d8a2394e5e1ad4aa1d04e78d1eff0ac6d0c3848a694170ab9aa1752db4b12d39e78decb314aa096ec42474ced16325b29079dfdf189c7c414b8c3a
|
7
|
+
data.tar.gz: b4256b738357558184a059600495bd97d9a3157f214ab9c5781a98737131b679d3fb81a46d8b43510cc4fe892791ad4c91caf2d02b9cb9766c6877fd543040b1
|
data/bin/crokus
CHANGED
File without changes
|
data/lib/crokus/ast.rb
CHANGED
@@ -35,6 +35,10 @@ module Crokus
|
|
35
35
|
def to_s
|
36
36
|
@tok.val
|
37
37
|
end
|
38
|
+
|
39
|
+
def self.create str
|
40
|
+
Ident.new(Token.create(str))
|
41
|
+
end
|
38
42
|
end
|
39
43
|
|
40
44
|
class Include < Ast
|
@@ -439,6 +443,9 @@ module Crokus
|
|
439
443
|
end
|
440
444
|
|
441
445
|
class StrLit < Literal
|
446
|
+
def self.create str
|
447
|
+
StrLit.new( Token.new [:string_lit,"\"#{str}\"",[0,0]] )
|
448
|
+
end
|
442
449
|
end
|
443
450
|
|
444
451
|
class CharLit < Literal
|
data/lib/crokus/cfg_builder.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'cfg'
|
2
2
|
require_relative 'cfg_cleaner'
|
3
|
+
require_relative 'cfg_optim'
|
3
4
|
|
4
5
|
require_relative 'visitor'
|
5
6
|
require_relative 'cleaner'
|
@@ -24,6 +25,7 @@ module Crokus
|
|
24
25
|
func.body.accept(self)
|
25
26
|
@cfg.print
|
26
27
|
@cfg=CFGCleaner.new.clean(@cfg)
|
28
|
+
@cfg=CFGOptimizer.new.clean(@cfg)
|
27
29
|
@cfg.name=Ident.new(Token.create "#{@cfg.name}_clean")
|
28
30
|
func.cfg=@cfg
|
29
31
|
puts " "*5+"|--[+] cfg size for '#{func.name}' : #{@cfg.size}" unless $options[:mute]
|
@@ -126,6 +128,10 @@ module Crokus
|
|
126
128
|
@current=falseBranch
|
127
129
|
end
|
128
130
|
|
131
|
+
def visitFunCall fcall,args=nil
|
132
|
+
@current << fcall
|
133
|
+
end
|
134
|
+
|
129
135
|
def visitFor for_,args=nil
|
130
136
|
for_.init.each{|stmt| stmt.accept(self)}
|
131
137
|
cond=for_.cond.accept(self)
|
@@ -148,6 +154,10 @@ module Crokus
|
|
148
154
|
@current=falseBranch
|
149
155
|
end
|
150
156
|
|
157
|
+
def visitReturn ret,args=nil
|
158
|
+
@current << ret
|
159
|
+
end
|
160
|
+
|
151
161
|
def visitDoWhile dowhile,args=nil
|
152
162
|
@cfg << cond_bb = BasicBlock.new
|
153
163
|
@current_continue_dest = cond_bb # for continue stmt !
|
data/lib/crokus/cfg_cleaner.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Crokus
|
2
|
+
|
3
|
+
class CFGOptimizer
|
4
|
+
|
5
|
+
def clean cfg
|
6
|
+
puts " "*5+"|--[+] optimizing cfg '#{cfg.name}'" unless $options[:mute]
|
7
|
+
@cfg=cfg
|
8
|
+
@visited=[]
|
9
|
+
@new_succs={}
|
10
|
+
optim_rec cfg.starter
|
11
|
+
cfg
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def optim_rec bb
|
17
|
+
@visited << bb
|
18
|
+
@new_succs[bb]=[]
|
19
|
+
bb.succs.each_with_index do |succ,idx|
|
20
|
+
if bb.succs.size==1 and succ.succs.size==1
|
21
|
+
bb.stmts << succ.stmts
|
22
|
+
bb.stmts.flatten!
|
23
|
+
@cfg.bbs.delete(succ)
|
24
|
+
bb.succs[0]=succ.succs.first
|
25
|
+
end
|
26
|
+
optim_rec succ unless @visited.include?(succ)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/crokus/cfg_printer.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Crokus
|
2
|
+
|
3
|
+
class CFGOnlyPrinter < Visitor
|
4
|
+
|
5
|
+
def visitFunction func,format
|
6
|
+
puts " "*1+"|--[+] print CFG for '#{func.name}'"
|
7
|
+
ir_code=dump(func.cfg)
|
8
|
+
format=ir_code.lines.first.start_with?("digraph") ? "dot" : "json"
|
9
|
+
filename=func.name.to_s+".#{format}"
|
10
|
+
ir_code.save_as filename
|
11
|
+
puts " "*5+"|--[+] generated #{filename}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump cfg
|
15
|
+
@visited=[]
|
16
|
+
@code=Code.new
|
17
|
+
header
|
18
|
+
visit_rec(cfg.starter)
|
19
|
+
footer
|
20
|
+
return @code
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative "cfg_printer_only"
|
2
|
+
|
3
|
+
module Crokus
|
4
|
+
|
5
|
+
class CFGOnlyPrinterDot < CFGOnlyPrinter
|
6
|
+
|
7
|
+
def header
|
8
|
+
@code << "digraph ControlFlowGraph {"
|
9
|
+
@code.indent=2
|
10
|
+
@code << "forcelabels=true;"
|
11
|
+
@code << "graph [ label=\"\","
|
12
|
+
@code << " bgcolor=\"white\","
|
13
|
+
@code << " fontname=\"Arial\","
|
14
|
+
@code << " rankdir=\"TB\"]"
|
15
|
+
@code.newline
|
16
|
+
@code << "node [ fontname=\"Arial\","
|
17
|
+
@code << " shape=\"box\","
|
18
|
+
@code << " style=\"filled\","
|
19
|
+
@code << " fillcolor=\"AliceBlue\"]"
|
20
|
+
@code.newline
|
21
|
+
@code << "edge [ fontname=\"Arial\","
|
22
|
+
@code << " color=\"Blue\","
|
23
|
+
@code << " dir=\"forward\"]"
|
24
|
+
end
|
25
|
+
|
26
|
+
def visit_rec bb
|
27
|
+
@visited << bb
|
28
|
+
@code << "bb_#{bb.label} [label=\"\",shape=rectangle, xlabel=#{bb.label}]"
|
29
|
+
@current=bb
|
30
|
+
if (ite=bb.stmts.last).is_a? ITE
|
31
|
+
|
32
|
+
unless @visited.include? (bb_t=ite.trueBranch)
|
33
|
+
visit_rec(bb_t)
|
34
|
+
end
|
35
|
+
unless @visited.include? (bb_f=ite.falseBranch)
|
36
|
+
visit_rec(bb_f)
|
37
|
+
end
|
38
|
+
@code << "bb_#{bb.label} -> bb_#{(bb_t=ite.trueBranch).label} [label=\"T\"]"
|
39
|
+
@code << "bb_#{bb.label} -> bb_#{(bb_f=ite.falseBranch).label} [label=\"F\"]"
|
40
|
+
else
|
41
|
+
bb.succs.each do |succ|
|
42
|
+
unless @visited.include? succ
|
43
|
+
visit_rec(succ)
|
44
|
+
end
|
45
|
+
@code << "bb_#{bb.label} -> bb_#{succ.label}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def footer
|
51
|
+
@code << "}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "cfg_printer_only"
|
2
|
+
|
3
|
+
module Crokus
|
4
|
+
|
5
|
+
class CFGOnlyPrinterJson < CFGOnlyPrinter
|
6
|
+
|
7
|
+
def header
|
8
|
+
@code << "{"
|
9
|
+
@code.indent=2
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit_rec bb
|
13
|
+
@visited << bb
|
14
|
+
@current=bb
|
15
|
+
if (ite=bb.stmts.last).is_a? ITE
|
16
|
+
@code << "\"#{bb.label}\": {"
|
17
|
+
@code.indent=4
|
18
|
+
@code << "\"true\": \"#{(bb_t=ite.trueBranch).label}\""
|
19
|
+
@code << "\"false\": \"#{(bb_f=ite.falseBranch).label}\""
|
20
|
+
@code.indent=2
|
21
|
+
@code << "}"
|
22
|
+
unless @visited.include? bb_t
|
23
|
+
visit_rec(bb_t)
|
24
|
+
end
|
25
|
+
unless @visited.include? bb_t
|
26
|
+
visit_rec(bb_t)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
bb.succs.each do |succ|
|
30
|
+
@code << "\"#{bb.label}\": \"#{succ.label}\""
|
31
|
+
unless @visited.include? succ
|
32
|
+
visit_rec(succ)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def footer
|
39
|
+
@code.indent=0
|
40
|
+
@code << "}"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -131,8 +131,14 @@ module Crokus
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
+
def bb_track bb
|
135
|
+
bb << fcall=FunCall.new(Ident.create("printf"),[StrLit.create("cfg track : %s\\n"),StrLit.create(bb.label)])
|
136
|
+
bb << SemicolonStmt.new(nil)
|
137
|
+
end
|
138
|
+
|
134
139
|
def gen_plain_block level
|
135
140
|
@cfg << bb=BasicBlock.new
|
141
|
+
bb_track(bb)
|
136
142
|
@current.to bb
|
137
143
|
@current=bb
|
138
144
|
end
|
@@ -143,6 +149,11 @@ module Crokus
|
|
143
149
|
@cfg << trueBranch =BasicBlock.new
|
144
150
|
@cfg << falseBranch=BasicBlock.new
|
145
151
|
@cfg << mergeBranch=BasicBlock.new
|
152
|
+
|
153
|
+
bb_track(trueBranch)
|
154
|
+
bb_track(falseBranch)
|
155
|
+
bb_track(mergeBranch)
|
156
|
+
|
146
157
|
@current.to trueBranch
|
147
158
|
@current.to falseBranch
|
148
159
|
|
@@ -162,6 +173,12 @@ module Crokus
|
|
162
173
|
cond_bb.infos[:cond]=create_condition
|
163
174
|
@cfg << trueBranch = BasicBlock.new
|
164
175
|
@cfg << falseBranch = BasicBlock.new
|
176
|
+
|
177
|
+
|
178
|
+
bb_track(cond_bb)
|
179
|
+
bb_track(trueBranch)
|
180
|
+
bb_track(falseBranch)
|
181
|
+
|
165
182
|
@current.to cond_bb
|
166
183
|
cond_bb.to trueBranch
|
167
184
|
cond_bb.to falseBranch
|
@@ -183,6 +200,13 @@ module Crokus
|
|
183
200
|
@cfg << trueBranch = BasicBlock.new
|
184
201
|
@cfg << falseBranch = BasicBlock.new
|
185
202
|
@cfg << postBranch = BasicBlock.new(:loop_body_end => true)
|
203
|
+
|
204
|
+
# control flow tracking
|
205
|
+
bb_track(cond_bb)
|
206
|
+
bb_track(trueBranch)
|
207
|
+
bb_track(falseBranch)
|
208
|
+
bb_track(postBranch)
|
209
|
+
|
186
210
|
@current.to cond_bb
|
187
211
|
cond_bb.to trueBranch
|
188
212
|
cond_bb.to falseBranch
|
data/lib/crokus/cleaner.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
module Crokus
|
2
2
|
class Cleaner
|
3
3
|
def clean str_c
|
4
|
-
|
5
|
-
str_c.gsub!(";;",";")
|
6
4
|
str_c.gsub!(";)",")")
|
7
5
|
str_c.gsub!(/\n+\s*\;/,";")
|
8
6
|
str_c.gsub!(/\;\s*\:/,":")
|
9
|
-
|
7
|
+
str_c.gsub!(/\n\s+\{/,"{")
|
8
|
+
str_c.gsub!(/\;+/,";")
|
10
9
|
str_c
|
11
10
|
end
|
11
|
+
|
12
|
+
def debug str_c
|
13
|
+
puts "hit a key"
|
14
|
+
$stdin.gets.chomp
|
15
|
+
puts str_c
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
data/lib/crokus/compiler.rb
CHANGED
@@ -6,6 +6,8 @@ require_relative 'pretty_printer'
|
|
6
6
|
require_relative 'trojan_inserter'
|
7
7
|
|
8
8
|
require_relative 'cfg_builder'
|
9
|
+
require_relative 'cfg_printer_only_dot'
|
10
|
+
require_relative 'cfg_printer_only_json'
|
9
11
|
require_relative 'tac_builder'
|
10
12
|
require_relative 'ir_dumper'
|
11
13
|
require_relative 'cfg_random_gen' # random C generation
|
@@ -33,10 +35,20 @@ module Crokus
|
|
33
35
|
build_cfg
|
34
36
|
return true if options[:cfg]
|
35
37
|
|
38
|
+
if options[:print_cfg_dot]
|
39
|
+
print_cfg_only(:dot)
|
40
|
+
return true
|
41
|
+
end
|
42
|
+
|
43
|
+
if options[:print_cfg_json]
|
44
|
+
print_cfg_only(:json)
|
45
|
+
return true
|
46
|
+
end
|
47
|
+
|
36
48
|
pretty_print
|
37
49
|
|
38
50
|
if options[:trojan]
|
39
|
-
return_code=insert_trojan
|
51
|
+
return_code=insert_trojan()
|
40
52
|
return return_code
|
41
53
|
end
|
42
54
|
|
@@ -101,13 +113,23 @@ module Crokus
|
|
101
113
|
IRDumper.new.visit(ast)
|
102
114
|
end
|
103
115
|
|
116
|
+
def print_cfg_only format
|
117
|
+
puts "[+] print textual CFG only format #{format}" unless options[:mute]
|
118
|
+
case format
|
119
|
+
when :dot
|
120
|
+
CFGOnlyPrinterDot.new.visit(ast)
|
121
|
+
when :json
|
122
|
+
CFGOnlyPrinterJson.new.visit(ast)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
104
126
|
def execute params
|
105
127
|
RandomGen.new.run(params)
|
106
128
|
end
|
107
129
|
|
108
130
|
def insert_trojan
|
109
131
|
puts "[+] inserting trojan" unless options[:mute]
|
110
|
-
infected_ast=TrojanInserter.new.insert(ast)
|
132
|
+
infected_ast=TrojanInserter.new(@options).insert(ast)
|
111
133
|
if infected_ast
|
112
134
|
code=PrettyPrinter.new.visit(infected_ast)
|
113
135
|
pp_c=@base_name+"_troj.c"
|
data/lib/crokus/runner.rb
CHANGED
@@ -23,7 +23,7 @@ module Crokus
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def header
|
26
|
-
puts "Crokus (#{VERSION})- (c) JC Le Lann 2016-
|
26
|
+
puts "Crokus (#{VERSION})- (c) JC Le Lann 2016-today"
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
@@ -65,12 +65,27 @@ module Crokus
|
|
65
65
|
options[:emit_ir] = true
|
66
66
|
end
|
67
67
|
|
68
|
+
parser.on("--print-cfg-dot", "print textual CFG ONLY in Graphviz format") do
|
69
|
+
options[:print_cfg_dot] = true
|
70
|
+
end
|
71
|
+
|
72
|
+
parser.on("--print-cfg-json", "print textual CFG ONLY in JSON format") do
|
73
|
+
options[:print_cfg_json] = true
|
74
|
+
end
|
75
|
+
|
68
76
|
parser.on('--random PARAMS', "generates random c files, using parameters", String) do |params_filename|
|
69
77
|
options[:random] = params_filename
|
70
78
|
end
|
71
79
|
|
72
|
-
|
80
|
+
# optional argument for --trojan
|
81
|
+
parser.on('--trojan FUNC', "insert Syracuse Trojan in function FUNC") do |target_func|
|
82
|
+
if target_func.end_with?(".c")
|
83
|
+
puts "wrong argument for --trojan . It requires a function name as argument."
|
84
|
+
abort
|
85
|
+
|
86
|
+
end
|
73
87
|
options[:trojan] = true
|
88
|
+
options[:trojan_target_func]=target_func
|
74
89
|
end
|
75
90
|
|
76
91
|
parser.on("--vv", "verbose") do
|
data/lib/crokus/token.rb
CHANGED
@@ -5,6 +5,10 @@ module Crokus
|
|
5
5
|
|
6
6
|
class TrojanInserter < Transformer
|
7
7
|
|
8
|
+
def initialize options={}
|
9
|
+
@options=options
|
10
|
+
end
|
11
|
+
|
8
12
|
def insert ast
|
9
13
|
@nb_trojans=0
|
10
14
|
new_ast=transform(ast)
|
@@ -13,6 +17,12 @@ module Crokus
|
|
13
17
|
return new_ast
|
14
18
|
else
|
15
19
|
puts " "*1+"|--[?] insertion failed"
|
20
|
+
if func=@options[:trojan_target_func] and @target_reached.nil?
|
21
|
+
puts " "*5+"|-- no function named '#{func}' found"
|
22
|
+
end
|
23
|
+
if @failure_reason
|
24
|
+
puts " "*5+"|-- #{@failure_reason}"
|
25
|
+
end
|
16
26
|
end
|
17
27
|
nil
|
18
28
|
end
|
@@ -25,11 +35,20 @@ module Crokus
|
|
25
35
|
end
|
26
36
|
|
27
37
|
def visitFunction func,args=nil
|
28
|
-
puts " "*1+"|--[+] func #{func.name}"
|
29
38
|
func_troj=super(func,args)
|
30
|
-
|
31
|
-
|
32
|
-
|
39
|
+
if @options[:trojan_target_func].nil? or (name=@options[:trojan_target_func] and target_reached=(func.name.to_s==name))
|
40
|
+
puts " "*1+"|--[+] func #{func.name}"
|
41
|
+
if target_reached
|
42
|
+
@target_reached=true
|
43
|
+
end
|
44
|
+
success=insert_trojan(func_troj)
|
45
|
+
if success
|
46
|
+
# hannah request : add a _troj to the function :
|
47
|
+
func_troj.name=Ident.create(func.name.to_s+'_troj')
|
48
|
+
@rename_funcs||={} # take cares of future calls to func !
|
49
|
+
@rename_funcs[func.name.to_s]=func_troj.name.to_s
|
50
|
+
@nb_trojans+=1
|
51
|
+
end
|
33
52
|
end
|
34
53
|
func_troj
|
35
54
|
end
|
@@ -37,7 +56,7 @@ module Crokus
|
|
37
56
|
def insert_trojan func
|
38
57
|
if trojan=build_trojan(func)
|
39
58
|
bodies=bodies_collect(func)
|
40
|
-
puts "\t#bodies = #{bodies.size}"
|
59
|
+
#puts "\t#bodies = #{bodies.size}"
|
41
60
|
target_body=bodies.sample
|
42
61
|
stmts=target_body.stmts
|
43
62
|
nb_decls=stmts.select{|stmt| stmt.is_a? Decl}.size
|
@@ -48,6 +67,18 @@ module Crokus
|
|
48
67
|
success=false
|
49
68
|
end
|
50
69
|
|
70
|
+
def visitFunCall fcall,args=nil
|
71
|
+
name=fcall.name.accept(self)
|
72
|
+
if @rename_funcs # propagate func renaming applied during visitFunction
|
73
|
+
if @rename_funcs.keys.include?(name.to_s)
|
74
|
+
new_name=@rename_funcs[name.to_s]
|
75
|
+
name=Ident.create(new_name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
args=fcall.args.collect{|arg| arg.accept(self)}
|
79
|
+
FunCall.new(name,args)
|
80
|
+
end
|
81
|
+
|
51
82
|
def bodies_collect func
|
52
83
|
bodies=[]
|
53
84
|
bodies << func.body
|
@@ -86,7 +117,10 @@ module Crokus
|
|
86
117
|
def build_trojan func
|
87
118
|
trojan=Body.new
|
88
119
|
anchor_var=choose_anchor(func)
|
89
|
-
|
120
|
+
if anchor_var.nil?
|
121
|
+
@failure_reason="no int type variable found in function local declarations, needed in the trojan insertion process."
|
122
|
+
return
|
123
|
+
end
|
90
124
|
u_=Ident.new(Token.create("u_"))
|
91
125
|
v_=Ident.new(Token.create("v_"))
|
92
126
|
i_=Ident.new(Token.create("i_"))
|
@@ -124,8 +158,13 @@ module Crokus
|
|
124
158
|
def build_trigger func
|
125
159
|
args=find_int_arg(func)
|
126
160
|
arg_names=get_arg_names(args)
|
127
|
-
|
128
|
-
|
161
|
+
unless arg_names.size>1
|
162
|
+
@failure_reason="not enough args of type int in func '#{func.name}' to build a trigger."
|
163
|
+
return
|
164
|
+
end
|
165
|
+
arg1,arg2=arg_names.shuffle[0..1]
|
166
|
+
puts " "*5+"|--> trigger variables are : #{arg1},#{arg2}"
|
167
|
+
cond=Binary.new(Parenth.new(Binary.new(arg1,AND,arg2)),EQUAL,T42)
|
129
168
|
If.new(cond,nil)
|
130
169
|
end
|
131
170
|
|
data/lib/crokus/version.rb
CHANGED
data/lib/crokus/visitor.rb
CHANGED
@@ -10,8 +10,8 @@ module Crokus
|
|
10
10
|
@verbose=false
|
11
11
|
end
|
12
12
|
|
13
|
-
def visit ast
|
14
|
-
ast.accept(self)
|
13
|
+
def visit ast,args=nil
|
14
|
+
ast.accept(self,args)
|
15
15
|
end
|
16
16
|
|
17
17
|
def visitToken tok, args=nil
|
@@ -20,62 +20,62 @@ module Crokus
|
|
20
20
|
|
21
21
|
def visitDesignUnit du,args=nil
|
22
22
|
indent "DesignUnit"
|
23
|
-
du.list.each{|e| e.accept(self)}
|
23
|
+
du.list.each{|e| e.accept(self,args)}
|
24
24
|
dedent
|
25
25
|
du
|
26
26
|
end
|
27
27
|
|
28
28
|
def visitDecl decl,args=nil
|
29
29
|
indent "Decl"
|
30
|
-
decl.type.accept(self)
|
31
|
-
decl.var.accept(self) if decl.var #case of struct decl only.
|
32
|
-
decl.init.accept(self) if decl.init
|
30
|
+
decl.type.accept(self,args)
|
31
|
+
decl.var.accept(self,args) if decl.var #case of struct decl only.
|
32
|
+
decl.init.accept(self,args) if decl.init
|
33
33
|
dedent
|
34
34
|
decl
|
35
35
|
end
|
36
36
|
|
37
37
|
def visitInclude include,args=nil
|
38
38
|
indent "Include"
|
39
|
-
include.name.accept(self)
|
39
|
+
include.name.accept(self,args)
|
40
40
|
dedent
|
41
41
|
include
|
42
42
|
end
|
43
43
|
|
44
44
|
def visitDefine define,args=nil
|
45
45
|
indent "Define"
|
46
|
-
define.name.accept(self)
|
47
|
-
define.expr.accept(self)
|
46
|
+
define.name.accept(self,args)
|
47
|
+
define.expr.accept(self,args)
|
48
48
|
dedent
|
49
49
|
define
|
50
50
|
end
|
51
51
|
|
52
52
|
def visitTypedef typdef,args=nil
|
53
53
|
indent "Typdef"
|
54
|
-
typdef.type.accept(self)
|
55
|
-
typdef.name.accept(self)
|
54
|
+
typdef.type.accept(self,args)
|
55
|
+
typdef.name.accept(self,args)
|
56
56
|
dedent
|
57
57
|
typdef
|
58
58
|
end
|
59
59
|
|
60
60
|
def visitType type,args=nil
|
61
61
|
indent "Type"
|
62
|
-
type.precisions.each{|precision| precision.accept(self)}
|
63
|
-
type.name.accept(self)
|
62
|
+
type.precisions.each{|precision| precision.accept(self,args)}
|
63
|
+
type.name.accept(self,args)
|
64
64
|
dedent
|
65
65
|
type
|
66
66
|
end
|
67
67
|
|
68
68
|
def visitPointerTo pto,args=nil
|
69
69
|
indent "PointerTo"
|
70
|
-
pto.type.accept(self)
|
70
|
+
pto.type.accept(self,args)
|
71
71
|
dedent
|
72
72
|
pto
|
73
73
|
end
|
74
74
|
|
75
75
|
def visitArrayOf aof,args=nil
|
76
76
|
indent "ArrayOf"
|
77
|
-
aof.type.accept(self)
|
78
|
-
aof.size.accept(self) if aof.size
|
77
|
+
aof.type.accept(self,args)
|
78
|
+
aof.size.accept(self,args) if aof.size
|
79
79
|
dedent
|
80
80
|
aof
|
81
81
|
end
|
@@ -88,15 +88,15 @@ module Crokus
|
|
88
88
|
|
89
89
|
def visitCasting cast,args=nil
|
90
90
|
indent "Casting"
|
91
|
-
cast.type.accept(self)
|
91
|
+
cast.type.accept(self,args)
|
92
92
|
dedent
|
93
93
|
cast
|
94
94
|
end
|
95
95
|
|
96
96
|
def visitCastedExpr cexpr,args=nil
|
97
97
|
indent "CastedExpr"
|
98
|
-
cexpr.type.accept(self)
|
99
|
-
cexpr.expr.accept(self)
|
98
|
+
cexpr.type.accept(self,args)
|
99
|
+
cexpr.expr.accept(self,args)
|
100
100
|
dedent
|
101
101
|
cexpr
|
102
102
|
end
|
@@ -105,118 +105,118 @@ module Crokus
|
|
105
105
|
|
106
106
|
def visitFunction func,args=nil
|
107
107
|
indent "Function"
|
108
|
-
func.type.accept(self)
|
109
|
-
func.name.accept(self)
|
110
|
-
func.args.each{|arg| arg.accept(self)}
|
111
|
-
func.body.accept(self)
|
108
|
+
func.type.accept(self,args)
|
109
|
+
func.name.accept(self,args)
|
110
|
+
func.args.each{|arg| arg.accept(self,args)}
|
111
|
+
func.body.accept(self,args)
|
112
112
|
dedent
|
113
113
|
func
|
114
114
|
end
|
115
115
|
|
116
116
|
def visitFunctionProto func,args=nil
|
117
117
|
indent "FunctionProto"
|
118
|
-
func.type.accept(self)
|
119
|
-
func.name.accept(self)
|
120
|
-
func.args.each{|arg| arg.accept(self)}
|
118
|
+
func.type.accept(self,args)
|
119
|
+
func.name.accept(self,args)
|
120
|
+
func.args.each{|arg| arg.accept(self,args)}
|
121
121
|
dedent
|
122
122
|
func
|
123
123
|
end
|
124
124
|
|
125
125
|
def visitFormalArg formalArg,args=nil
|
126
126
|
indent "FormalArg"
|
127
|
-
formalArg.name.accept(self) if formalArg.name # e.g : main(void)
|
128
|
-
formalArg.type.accept(self)
|
127
|
+
formalArg.name.accept(self,args) if formalArg.name # e.g : main(void)
|
128
|
+
formalArg.type.accept(self,args)
|
129
129
|
dedent
|
130
130
|
formalArg
|
131
131
|
end
|
132
132
|
|
133
133
|
#...........stmts...............
|
134
134
|
def visitCommaStmt comma,args=nil
|
135
|
-
lhs=comma.lhs.accept(self)
|
136
|
-
rhs=comma.rhs.accept(self)
|
135
|
+
lhs=comma.lhs.accept(self,args)
|
136
|
+
rhs=comma.rhs.accept(self,args)
|
137
137
|
comma
|
138
138
|
end
|
139
139
|
|
140
140
|
def visitAssign assign,args=nil
|
141
|
-
assign.lhs.accept(self)
|
142
|
-
assign.op.accept(self)
|
143
|
-
assign.rhs.accept(self)
|
141
|
+
assign.lhs.accept(self,args)
|
142
|
+
assign.op.accept(self,args)
|
143
|
+
assign.rhs.accept(self,args)
|
144
144
|
assign
|
145
145
|
end
|
146
146
|
|
147
147
|
def visitPostFixAccu accu,args=nil
|
148
148
|
lhs=accu.lhs.accept(self,args) if accu.lhs #++i
|
149
|
-
op =accu.op.accept(self)
|
149
|
+
op =accu.op.accept(self,args)
|
150
150
|
accu
|
151
151
|
end
|
152
152
|
|
153
153
|
def visitPreFixAccu accu,args=nil
|
154
154
|
lhs=accu.lhs.accept(self,args) if accu.lhs #++i
|
155
|
-
op =accu.op.accept(self)
|
155
|
+
op =accu.op.accept(self,args)
|
156
156
|
accu
|
157
157
|
end
|
158
158
|
|
159
159
|
def visitFunCall fcall,args=nil
|
160
160
|
indent "FunCall"
|
161
|
-
fcall.name.accept(self)
|
162
|
-
fcall.args.each{|arg| arg.accept(self)}
|
161
|
+
fcall.name.accept(self,args)
|
162
|
+
fcall.args.each{|arg| arg.accept(self,args)}
|
163
163
|
dedent
|
164
164
|
fcall
|
165
165
|
end
|
166
166
|
|
167
167
|
def visitFor for_,args=nil
|
168
168
|
indent "For"
|
169
|
-
for_.init.each{|stmt| stmt.accept(self)}
|
170
|
-
for_.cond.accept(self)
|
171
|
-
for_.increment.accept(self)
|
172
|
-
for_.body.accept(self)
|
169
|
+
for_.init.each{|stmt| stmt.accept(self,args)}
|
170
|
+
for_.cond.accept(self,args)
|
171
|
+
for_.increment.accept(self,args)
|
172
|
+
for_.body.accept(self,args)
|
173
173
|
dedent
|
174
174
|
for_
|
175
175
|
end
|
176
176
|
|
177
177
|
def visitReturn ret,args=nil
|
178
178
|
indent "Return"
|
179
|
-
ret.expr.accept(self) if ret.expr
|
179
|
+
ret.expr.accept(self,args) if ret.expr
|
180
180
|
dedent
|
181
181
|
ret
|
182
182
|
end
|
183
183
|
|
184
184
|
def visitIf if_,args=nil
|
185
185
|
indent "If"
|
186
|
-
if_.cond.accept(self)
|
187
|
-
if_.body.accept(self)
|
186
|
+
if_.cond.accept(self,args)
|
187
|
+
if_.body.accept(self,args)
|
188
188
|
dedent
|
189
189
|
if_
|
190
190
|
end
|
191
191
|
|
192
192
|
def visitSwitch sw_,args=nil
|
193
193
|
indent "Switch"
|
194
|
-
sw_.expr.accept(self)
|
195
|
-
sw_.cases.each{|case_| case_.accept(self)}
|
194
|
+
sw_.expr.accept(self,args)
|
195
|
+
sw_.cases.each{|case_| case_.accept(self,args)}
|
196
196
|
dedent
|
197
197
|
sw_
|
198
198
|
end
|
199
199
|
|
200
200
|
def visitCase case_,args=nil
|
201
201
|
indent "Case"
|
202
|
-
case_.expr.accept(self)
|
203
|
-
case_.body.accept(self)
|
202
|
+
case_.expr.accept(self,args)
|
203
|
+
case_.body.accept(self,args)
|
204
204
|
dedent
|
205
205
|
case_
|
206
206
|
end
|
207
207
|
|
208
208
|
def visitWhile while_,args=nil
|
209
209
|
indent "While"
|
210
|
-
while_.cond.accept(self)
|
211
|
-
while_.body.each{|stmt| stmt.accept(self)}
|
210
|
+
while_.cond.accept(self,args)
|
211
|
+
while_.body.each{|stmt| stmt.accept(self,args)}
|
212
212
|
dedent
|
213
213
|
while_
|
214
214
|
end
|
215
215
|
|
216
216
|
def visitDoWhile while_,args=nil
|
217
217
|
indent "DoWhile"
|
218
|
-
while_.cond.accept(self)
|
219
|
-
while_.body.each{|stmt| stmt.accept(self)}
|
218
|
+
while_.cond.accept(self,args)
|
219
|
+
while_.body.each{|stmt| stmt.accept(self,args)}
|
220
220
|
dedent
|
221
221
|
while_
|
222
222
|
end
|
@@ -241,7 +241,7 @@ module Crokus
|
|
241
241
|
|
242
242
|
def visitGoto goto,args=nil
|
243
243
|
indent "Goto"
|
244
|
-
goto.label.accept(self)
|
244
|
+
goto.label.accept(self,args)
|
245
245
|
dedent
|
246
246
|
goto
|
247
247
|
end
|
@@ -268,7 +268,7 @@ module Crokus
|
|
268
268
|
|
269
269
|
def visitCondExpr cexpr,args=nil
|
270
270
|
indent "condexpr"
|
271
|
-
cexpr.cond.accept(self)
|
271
|
+
cexpr.cond.accept(self,args)
|
272
272
|
cexpr.lhs.accept(self,args)
|
273
273
|
cexpr.rhs.accept(self,args)
|
274
274
|
dedent
|
@@ -278,7 +278,7 @@ module Crokus
|
|
278
278
|
def visitBinary expr,args=nil
|
279
279
|
indent "Binary"
|
280
280
|
expr.lhs.accept(self,args)
|
281
|
-
expr.op.accept(self)
|
281
|
+
expr.op.accept(self,args)
|
282
282
|
expr.rhs.accept(self,args)
|
283
283
|
dedent
|
284
284
|
expr
|
@@ -292,28 +292,28 @@ module Crokus
|
|
292
292
|
|
293
293
|
def visitParenth par,args=nil
|
294
294
|
indent "Parenth"
|
295
|
-
par.expr.accept(self)
|
295
|
+
par.expr.accept(self,args)
|
296
296
|
dedent
|
297
297
|
par
|
298
298
|
end
|
299
299
|
|
300
300
|
def visitArrow arrow,args=nil
|
301
301
|
indent "arrow"
|
302
|
-
arrow.lhs.accept(self)
|
303
|
-
arrow.rhs.accept(self)
|
302
|
+
arrow.lhs.accept(self,args)
|
303
|
+
arrow.rhs.accept(self,args)
|
304
304
|
dedent
|
305
305
|
end
|
306
306
|
|
307
307
|
def visitIndexed index,args=nil
|
308
308
|
indent "Index"
|
309
|
-
index.lhs.accept(self)
|
310
|
-
index.rhs.accept(self)
|
309
|
+
index.lhs.accept(self,args)
|
310
|
+
index.rhs.accept(self,args)
|
311
311
|
dedent
|
312
312
|
end
|
313
313
|
|
314
314
|
def visitArrayOrStructInit init,args=nil
|
315
315
|
indent "ArrayOrStructInit"
|
316
|
-
init.elements.each{|e| e.accept(self)}
|
316
|
+
init.elements.each{|e| e.accept(self,args)}
|
317
317
|
dedent
|
318
318
|
end
|
319
319
|
|
@@ -324,14 +324,14 @@ module Crokus
|
|
324
324
|
|
325
325
|
def visitPointed pointed,args=nil
|
326
326
|
indent "Pointed"
|
327
|
-
pointed.lhs.accept(self)
|
328
|
-
pointed.rhs.accept(self)
|
327
|
+
pointed.lhs.accept(self,args)
|
328
|
+
pointed.rhs.accept(self,args)
|
329
329
|
dedent
|
330
330
|
end
|
331
331
|
|
332
332
|
def visitSizeof sizeof,args=nil
|
333
333
|
indent "Sizeof"
|
334
|
-
sizeof.type.accept(self)
|
334
|
+
sizeof.type.accept(self,args)
|
335
335
|
dedent
|
336
336
|
sizeof
|
337
337
|
end
|
@@ -343,7 +343,7 @@ module Crokus
|
|
343
343
|
|
344
344
|
def visitBody body,args=nil
|
345
345
|
indent "body"
|
346
|
-
body.stmts.each{|stmt| stmt.accept(self)}
|
346
|
+
body.stmts.each{|stmt| stmt.accept(self,args)}
|
347
347
|
dedent
|
348
348
|
end
|
349
349
|
end #class Visitor
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crokus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean-Christophe Le Lann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: distribution
|
@@ -53,8 +53,12 @@ files:
|
|
53
53
|
- lib/crokus/cfg.rb
|
54
54
|
- lib/crokus/cfg_builder.rb
|
55
55
|
- lib/crokus/cfg_cleaner.rb
|
56
|
+
- lib/crokus/cfg_optim.rb
|
56
57
|
- lib/crokus/cfg_printer.rb
|
57
58
|
- lib/crokus/cfg_printer_c.rb
|
59
|
+
- lib/crokus/cfg_printer_only.rb
|
60
|
+
- lib/crokus/cfg_printer_only_dot.rb
|
61
|
+
- lib/crokus/cfg_printer_only_json.rb
|
58
62
|
- lib/crokus/cfg_random_gen.rb
|
59
63
|
- lib/crokus/cleaner.rb
|
60
64
|
- lib/crokus/code.rb
|
@@ -92,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
96
|
- !ruby/object:Gem::Version
|
93
97
|
version: '0'
|
94
98
|
requirements: []
|
95
|
-
rubygems_version: 3.
|
99
|
+
rubygems_version: 3.2.3
|
96
100
|
signing_key:
|
97
101
|
specification_version: 4
|
98
102
|
summary: Simple parser for a subset of C language, for experimental purposes
|