-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathparser.py
172 lines (141 loc) · 5.16 KB
/
parser.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
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
import re
import pymxs
from itertools import tee
INTERFACE = "Interface:"
PROPERTIES = "Properties:"
METHODS = "Methods:"
ACTIONS = "Actions:"
SPACE = " "
INTERFACES = []
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
def format_class_name(name, obj=None):
if name.startswith("<") and name.endswith(">"):
name = name[1:-1]
if name.startswith("&"): name = name[1:]
if name == "runtime":
return name
if not obj:
method_name = name.title()
else:
method_name = name
class_name = ""
for i, l in enumerate(zip(name, method_name)):
if l[0].isupper():
class_name += l[0]
else:
class_name += l[1]
if class_name == "Void":
class_name = "None"
class_name = class_name.replace(" ", "")
return class_name
def strip_string_stream(string):
start = 'StringStream:"'
end = '"'
return string[len(start):-len(end)]
def parse_property(string_list):
VALIDATION = "Validated by "
WRITE = "Write"
property = string_list[0]
comments = string_list[1:]
name, value, mode = property.split(" : ")
name = name[1:].upper()
value = format_class_name(value)
comment_str = ""
for comment in comments:
if " enums:" in comment:
pattern = r"#([\w]*)"
values = re.findall(pattern, comment)
comment_str = f"# {', '.join(values)} - rt.Name(\"\")"
else:
comment_str = f"# {comment}"
if VALIDATION in mode:
validation = mode.split(VALIDATION)[-1]
comment_str += f"# {validation}"
if WRITE not in mode:
print(f"{SPACE}@property")
print(f"{SPACE}def {name}() -> {value}: ...")
else:
print(f"{SPACE}{name}: {value} {comment_str}")
def parse_methods(string_list):
signature = string_list[0]
comments = string_list[1:]
pattern = r"(<[A-Za-z\s&\d]*>)([A-Za-z]+)"
return_name, *mandatory_parameters = re.findall(pattern, signature)
pattern = r"([A-Za-z]+):(<[A-Za-z\s&\d]*>)"
optional_parameters = re.findall(pattern, signature)
return_value = format_class_name(return_name[0])
method_name = format_class_name(return_name[1])
method_string = f"{SPACE}def {method_name}("
for parameter in mandatory_parameters:
value = format_class_name(parameter[0])
name = format_class_name(parameter[1])
method_string += f"{name}: {value}, "
for parameter in optional_parameters:
name = format_class_name(parameter[0])
value = format_class_name(parameter[1])
line = [comment for comment in comments if comment.lower().find(f"{name.lower()} default value:") != -1][0]
comments.remove(line)
default_value = line.split(": ")[1]
if default_value in ("true", "false"):
default_value = default_value.title()
method_string += f"{name}: {value} = {default_value}, "
if method_string[-1] == " ": method_string = method_string[:-2]
method_string += f") -> {return_value}: ..."
print(method_string)
if comments:
print(f"{SPACE}{SPACE}\"\"\"")
for comment in comments:
print(f"{SPACE}{SPACE}{comment}")
print(f"{SPACE}{SPACE}\"\"\"")
def parse_strings(string_list, signifier=".", output=parse_property):
properties = []
property = []
for i, line in enumerate(string_list):
content = line.strip()
if content.startswith(signifier):
if property:
properties.append(property)
property = [content]
else:
property.append(content)
if property:
properties.append(property)
for property in properties:
output(property)
return properties
def parse_interface(string_list):
interface_name = format_class_name(string_list[0].strip()[len(INTERFACE)+1:])
if interface_name in INTERFACES:
return
INTERFACES.append(interface_name)
print(f"class {interface_name}:")
property_line = string_list.index(f" {PROPERTIES}")
method_line = string_list.index(f" {METHODS}")
action_line = string_list.index(f" {ACTIONS}")
properties_lines = string_list[property_line+1:method_line]
parse_strings(properties_lines, ".", parse_property)
methods = string_list[method_line+1:action_line]
parse_strings(methods, "<", parse_methods)
actions = string_list[action_line+1:]
# haven't seen actions yet
print(f"{SPACE}...")
def parse_for_interfaces(string):
interfaces_string = strip_string_stream(string)
lines = interfaces_string.splitlines()
interface_lines = []
for i, line in enumerate(lines):
if line.strip().startswith("Interface:"):
interface_lines.append(i)
interface_lines.append(len(lines))
interface_borders = list(pairwise(interface_lines))
for interface in interface_borders:
parse_interface(lines[interface[0]:interface[1]])
def parse_node_interfaces(node):
string_stream = pymxs.runtime.stringStream('')
pymxs.runtime.showInterfaces(node, to=string_stream)
parse_for_interfaces(str(string_stream))
parse_node_interfaces(pymxs.runtime.Node)