-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcpp_pretty_frame.py
109 lines (89 loc) · 3.7 KB
/
cpp_pretty_frame.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
#!/usr/bin/env python3
# This file:
# CC-BY-SA: Author Phil Weir <[email protected]>
# With thanks to Paul McGuire:
# http://stackoverflow.com/questions/4801403/how-can-i-use-pyparsing-to-parse-nested-expressions-that-have-mutiple-opener-clo
import colorama
import pyparsing as pyp
def _indent(text, indent):
return indent + ('\n' + indent).join(text.split('\n'))
def _color_wrap(c, text):
return c + text + colorama.Style.RESET_ALL
class PrettyFrame:
types = ['auto', 'bool', 'char', 'double', 'float', 'int', 'long', 'short']
keywords = ['const', 'mutable', 'public', 'private', 'protected',
'virtual']
redwords = ['null', 'true', 'false']
known_namespaces = ['std', 'boost']
def __init__(self):
self.enclosed = pyp.Forward()
nestedAngles = pyp.nestedExpr('<', '>', content=self.enclosed)
self.enclosed << (pyp.Word('_' + pyp.alphanums) | '{' | '}' |
'(' | ')' | '*' | '&' | ',' | pyp.Word("::") |
nestedAngles)
def format_nested(self, nested, level=0):
formatted = ''
sublevels = False
segments = []
flat_segments = []
name = []
for tok in nested:
if isinstance(tok, list):
sublevels = True
name.append(self.format_nested(tok, level + 1))
elif tok == ',':
if name:
segments.append(name)
name = []
else:
if tok in self.redwords:
tok = _color_wrap(colorama.Fore.RED, tok)
elif tok in self.keywords:
tok = _color_wrap(colorama.Fore.BLUE, tok)
elif tok in self.types:
tok = _color_wrap(colorama.Fore.MAGENTA, tok)
name.append(tok)
segments.append(name)
multiline = False
for segment in segments:
if not segment:
continue
if isinstance(segment, list):
if segment[0] not in self.known_namespaces and '::' in segment:
sep = len(segment) - segment[-1::-1].index('::') - 1
segment[sep + 1] = _color_wrap(colorama.Fore.YELLOW,
segment[sep + 1])
flat_segment = ''.join(segment)
if segment[0] in self.known_namespaces:
flat_segment = _color_wrap(colorama.Fore.CYAN,
flat_segment)
else:
flat_segment = segment
if '\n' in flat_segment:
multiline = True
flat_segments.append(flat_segment)
formatted += (',\n' if multiline else ', ').join(flat_segments)
indent = _color_wrap(colorama.Style.DIM, ' ' if level % 4 else '| ')
if sublevels:
formatted = '<\n%s\n>' % _indent(formatted, indent)
else:
formatted = '<%s>' % formatted
formatted = _color_wrap(colorama.Style.RESET_ALL, formatted)
return formatted
def parse_line(self, line):
e = None
was_missing_end_bracket = True
added_brackets = 0
while was_missing_end_bracket:
was_missing_end_bracket = False
try:
nested = self.enclosed.parseString('<%s>' % line)[0]
except Exception as e:
if str(e).startswith('Expected ">"'):
was_missing_end_bracket = True
line += '>'
added_brackets += 1
else:
print(e)
nested = []
return self.format_nested([] if nested == [] else nested.asList())