-
Notifications
You must be signed in to change notification settings - Fork 0
/
format.py
executable file
·116 lines (94 loc) · 2.81 KB
/
format.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
#!/usr/bin/env python3
import re
import sys
class Syntax:
def __init__(self, string=""):
self.string = string
class Preprocessor(Syntax):
match = r"(#)\s*(include)\s*(<.*?>)"
name = "Preprocessor directives"
length = len(name) + 2
class Type(Syntax):
match = r"(int|char\*\*|uint_fast64_t|char\*|char\[\])"
name = "Types"
length = len(name) + 2
class Variable(Syntax):
match = r"(\w+)"
name = "Variables"
length = len(name) + 2
class Operator(Syntax):
match = r"(,|\+\+|--|\+=|<=|>=|/=|&&|&=|\+|-|\*|/|%|>>|<<|>|<|&|~|=)"
name = "Operators"
length = len(name) + 2
class Number(Syntax):
match = r"(\d+)"
name = "Numbers"
length = len(name) + 2
class Keyword(Syntax):
match = r"(if|for|return|while)"
name = "Keywords"
length = len(name) + 2
class Function(Syntax):
match = r"(main|malloc|memset|strtoumax|sqrt|puts|log10|putchar|free)"
name = "Functions"
length = len(name) + 2
class Bracket(Syntax):
match = r"(\[|\])"
name = "Square brackets"
length = len(name) + 2
class Parenthese(Syntax):
match = r"(\(|\))"
name = "Parentheses"
length = len(name) + 2
class Brace(Syntax):
match = r"(\{|\})"
name = "Curly braces"
length = len(name) + 2
class Semicolon(Syntax):
match = r"(;)"
name = "Semicolons"
length = len(name) + 2
class NoMatch(Syntax):
match = r"."
name = "No match"
def center(string, length):
diff = length - len(string)
if diff < 0:
sys.exit("error")
f = diff // 2
r = diff - f
return ' ' * f + string + ' ' * r
contents = re.sub(r"/\*.*?\*/", "", sys.stdin.read(), flags=re.DOTALL)
l = []
while contents != "":
for c in [Preprocessor, Type, Keyword, Function, Number, Bracket, Parenthese, Brace, Semicolon, Operator, Variable, NoMatch]:
m = re.search(r"^\s*" + c.match, contents, re.DOTALL)
if m:
l.append(c(''.join(m.groups())))
contents = contents[m.end():]
break
l = [m for m in l if not isinstance(m, NoMatch)]
order = [Type, Variable, Operator, Number, Keyword, Function, Bracket, Parenthese, Brace, Semicolon, Preprocessor]
output = "/*"
for s in order:
s.length = max(s.length, max([len(m.string) + 6 for m in l if isinstance(m, s)]))
output += "|" + center(s.name, s.length)
output += "|*/\n/*"
pos = 0
for m in l:
while not isinstance(m, order[pos]):
output += "|*/" + ' ' * (order[pos].length-4) + "/*"
pos += 1
if pos == len(order):
output += "|*/\n/*"
pos = 0
output += "|*/" + center(m.string, order[pos].length-4) + "/*"
pos += 1
if pos == len(order):
output += "|*/\n/*"
pos = 0
while pos < len(order):
output += "|*/" + ' ' * (order[pos].length-4) + "/*"
pos += 1
output += "|*/"
print(output)