-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
121 lines (97 loc) · 4.23 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import sys
import re
import argparse
import os.path
import importlib
import yaml
from pycparser import c_parser, c_ast, parse_file, c_generator
from typing import List, Set, Dict, Tuple, Optional
import cast_lib
import athos
import c99theory
def remove_c99_comments(text):
"""remove c-style comments"""
pattern = r"""
## --------- COMMENT ---------
//.*?$ ## Start of // .... comment
| ##
/\* ## Start of /* ... */ comment
[^*]*\*+ ## Non-* followed by 1-or-more *'s
( ##
[^/*][^*]*\*+ ##
)* ## 0-or-more things which don't start with /
## but do end with '*'
/ ## End of /* ... */ comment
| ## -OR- various things which aren't comments:
( ##
## ------ " ... " STRING ------
" ## Start of " ... " string
( ##
\\. ## Escaped char
| ## -OR-
[^"\\] ## Non "\ characters
)* ##
" ## End of " ... " string
| ## -OR-
##
## ------ ' ... ' STRING ------
' ## Start of ' ... ' string
( ##
\\. ## Escaped char
| ## -OR-
[^'\\] ## Non '\ characters
)* ##
' ## End of ' ... ' string
| ## -OR-
##
## ------ ANYTHING ELSE -------
. ## Anything other char
[^/"'\\]* ## Chars which doesn't start a comment, string
) ## or escape
"""
regex = re.compile(pattern, re.VERBOSE|re.MULTILINE|re.DOTALL)
noncomments = [m.group(2) for m in regex.finditer(text) if m.group(2)]
return "".join(noncomments)
def prepare_for_pycparser(filename):
with open(filename) as f:
original_file_str = f.read()
result_str = remove_c99_comments(original_file_str)
return result_str
def check_positive(value):
ivalue = int(value)
if ivalue < 1:
raise argparse.ArgumentTypeError("%s is an invalid positive int value" % value)
return ivalue
if __name__ == "__main__":
# Parse the program arguments
argparser = argparse.ArgumentParser('Event driven async to sync')
argparser.add_argument('filename', help='name of file to parse')
argparser.add_argument('configfile', help='configuration file with syncvars and labels')
argparser.add_argument('--unfold', help='number of unfolds to perform', type=check_positive)
argparser.add_argument('--athos', help='perform async to sync translation', action='store_true')
argparser.add_argument('--deadcode', help='perform a deadcode elimination', action='store_true')
args = argparser.parse_args()
# Pycparser doesn't support directives, we replace them for its content
input_str_pycparser = prepare_for_pycparser(args.filename)
# Read config file
config = yaml.safe_load(open(args.configfile))
# Now we can use pycparser to obtain the AST
parser = c_parser.CParser()
generator = c_generator.CGenerator()
codeast = parser.parse(input_str_pycparser)
if args.unfold:
cast_lib.unfold(codeast, args.unfold, config)
code = generator.visit(codeast)
print(code)
elif args.athos:
compho = athos.async_to_sync(codeast, config)
for label, compho in compho.items():
print("################## "+label+" ######################")
for step, step_code_ast in compho.items():
print("############ "+step+" ############")
code = generator.visit(step_code_ast)
print(code)
elif args.deadcode:
c99theory.dead_code_elimination(codeast, config['phase'])
code = generator.visit(codeast)
print(code)