-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcppConverter.py
More file actions
199 lines (165 loc) · 5.89 KB
/
cppConverter.py
File metadata and controls
199 lines (165 loc) · 5.89 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# Aaron Robeson
# CS3200 Spring 2017
# Feb 7
import sys
import re
# This global variable will keep track of the current indentation level as indicated by parsed opening and closing braces {}
indentLevel = 0
# Parse function that takes a single line of C++ code and translates it to python
def parseLine(line):
# print("Line: " + line)
global indentLevel
# First parse for strings so that regex won't be confused by reserved words
stringRE = "\"[^\"]*\""
stringsInLine = []
match = re.search(stringRE, line)
while match != None:
# print("found string at: " + match.span())
stringsInLine.append(line[match.span()[0]:match.span()[1]])
line = line[:match.span()[0]] + "!!STRING!!" + str(len(stringsInLine)) + "!!" + line[match.span()[1]:]
match = re.search(stringRE, line)
# remove whitespace at start of line and replace with the current indent
line = line.strip()
# If line is a comment replace // with # and return the line
if line[:2] == "//":
return (indentLevel * " ") + "#" + line[2:] + '\n'
# check for declarations without assignment which should be removed
decRE = "(int|double|string|float|char|bool|void|size_t)[^=]+;"
match = re.match(decRE, line)
if match != None:
return ""
# check for assignmens
decRE = "(int|double|string|float|char|bool|void|size_t)[ ]*"
match = re.match(decRE, line)
if match != None:
line = line[match.span()[1]:]
# if line starts with #include remove it
includeRE = "#include"
match = re.match(includeRE, line)
if match != None:
return ""
# if line starts with using remove it
usingRE = "using"
match = re.match(usingRE, line)
if match != None:
return ""
# replace keywords
# true -> True
trueRE = "true"
match = re.search(trueRE, line)
while match != None:
line = line[:match.span()[0]] + "True" + line[match.span()[1]:]
match = re.search(trueRE, line)
# false -> False
falseRE = "false"
match = re.search(falseRE, line)
while match != None:
line = line[:match.span()[0]] + "False" + line[match.span()[1]:]
match = re.search(falseRE, line)
# || -> or
orRE = "\|\|"
match = re.search(orRE, line)
while match != None:
line = line[:match.span()[0]] + " or " + line[match.span()[1]:]
match = re.search(orRE, line)
# && -> and
andRE = "&&"
match = re.search(andRE, line)
while match != None:
line = line[:match.span()[0]] + " and " + line[match.span()[1]:]
match = re.search(andRE, line)
# ++ -> += 1
plusplusRE = "\+\+"
match = re.search(plusplusRE, line)
while match != None:
line = line[:match.span()[0]] + " += 1 " + line[match.span()[1]:]
match = re.search(plusplusRE, line)
# remove semicolons
if line[-1:] == ';':
line = line[:-1]
# check for {
if line == "{":
indentLevel += 1
return ""
# check for }
if line == "}":
indentLevel -= 1
return ""
# check for main
mainRE = "main[ ]*([^)]*)"#"int +main +("
match = re.search(mainRE, line)
if match != None:
# this is the opening of the C++ main function, so replace it with python main (MUST CALL main() AT THE END OF THE FILE)
line = "def main():"
# check for cout
coutRE = "cout[ ]*<<"
match = re.search(coutRE, line)
if match != None:
line = line[:match.span()[0]] + "print( str(" + line[match.span()[1]:] + "), end=\"\")"
# replace << with +
lesslessRE = "<<"
match = re.search(lesslessRE, line)
while match != None:
line = line[:match.span()[0]] + ") + str(" + line[match.span()[1]:]
match = re.search(lesslessRE, line)
# replace endl with '\n'
endlRE = "endl"
match = re.search(endlRE, line)
while match != None:
line = line[:match.span()[0]] + "\"\\n\"" + line[match.span()[1]:]
match = re.search(endlRE, line)
# check for cin
cinRE = "cin[ ]*>>"
match = re.search(cinRE, line)
if match != None:
line = line[match.span()[1]:] + " = input()"
# check for if
ifRE = "if[ ]*([^)]*)"
match = re.search(ifRE, line)
if match != None:
line = line[:match.span()[1]+1] + ":" + line[match.span()[1]+1:]
# check for else if
elseifRE = "else[ ]+if"
match = re.search(elseifRE, line)
if match != None:
line = line[:match.span()[0]] + "elif" + line[match.span()[1]:]
# check for else
elseRE = "else"
match = re.search(elseRE, line)
if match != None:
line = line[:match.span()[0]] + "else:" + line[match.span()[1]:]
# check for while
whileRE = "while[ ]*([^)]*)"
match = re.search(whileRE, line)
if match != None:
line = line[:match.span()[1]+1] + ":" + line[match.span()[1]+1:]
# Add strings back in
stringReplacementRE = "!!STRING!!\d+!!"
match = re.search(stringReplacementRE, line)
while match != None:
stringToInsert = stringsInLine.pop(0)
line = line[:match.span()[0]] + stringToInsert + line[match.span()[1]:]
match = re.search(stringReplacementRE, line)
# if line != "":
line = (indentLevel * " ") + line + '\n'
return line
# Main function that checks for valid terminal input and passes each line of the given C++ file through the parseLine function placing the result in the output file
def main():
# check if command line args are correct
if len(sys.argv) != 3:
print('Invalid parameters count. Must be 2', file=sys.stderr)
print(help)
sys.exit(-1)
# open file and read line by line converting to cpp
in_filename = sys.argv[1];
out_filename = sys.argv[2];
print("infile: " + in_filename)
print("outfile: " + out_filename)
with open(in_filename, 'r') as inFile:
lines = inFile.readlines() # probably would die on sources more than 100 000 lines :D
with open(out_filename, 'w+') as outFile:
for line in lines:
outFile.write(parseLine(line))
outFile.write("main()") # add a call to the main function at the end of the file to start the program
# Start the program by calling the main function
main()