5 def text_to_python(text, indent):
6 text_strip = text.strip()
7 if text_strip[:1] == '{' and text_strip[-1:] == '}':
8 text = text_strip[1:-1]
9 lines = text.rstrip().split('\n')
10 while len(lines) and len(lines[0].lstrip()) == 0:
12 while len(lines) and len(lines[-1].lstrip()) == 0:
15 return '' #{0:s}pass\n'.format(indent)
16 for j in range(len(lines[0])):
17 if lines[0][j] != '\t' and lines[0][j] != ' ':
25 for j in range(len(lines)):
26 if len(lines[j]) == 0:
29 assert lines[j][:len(prefix)] == prefix
30 lines[j] = '{0:s}{1:s}\n'.format(indent, lines[j][len(prefix):])
33 # note: these routines are literally the same, but conceptually different,
34 # because ast.Text and regex.Text are different and unrelated base classes
35 def ast_text_to_python(ast_text, indent):
36 return text_to_python(ast_text.get_text(), indent)
37 def regex_text_to_python(regex_text, indent):
38 return text_to_python(regex_text.get_text(), indent)
40 def generate_py(_ast, _element, home_dir, skel_file, out_file):
41 # generate group action function names (ref_data) and body text
44 group_actions_text = []
45 for i in _ast.flex_rules:
46 group_ref_data.extend(
49 'yy_group{0:d}'.format(len(group_actions_text) + j),
51 'yy_group_end_element'
52 if isinstance(i.groups0[j], regex.RegexGroupElement) else
56 for j in range(len(i.groups0))
61 'yy_rule{0:d}'.format(len(group_rules_text))
66 'yy_group{0:d}'.format(len(group_actions_text) + j),
68 'yy_group_end_element'
69 if isinstance(i.groups1[j], regex.RegexGroupElement) else
73 for j in range(len(i.groups1))
76 groups = i.groups0 + i.groups1
77 group_rules_text.append(
79 text = '''global yy_groups, yy_groups_by_name, yy_action
80 yy_groups = [yy_group_text[:yy_group_stack[-1]]{0:s}]
81 yy_groups_by_name = {{}}
82 yy_action = yy_action{1:d}
84 ', None' * len(groups),
89 group_actions_text.extend(
93 if isinstance(groups[j], regex.RegexGroupAction) else
95 text = '''_element = yy_group_element(
98 yy_element_stack.pop(),
101 yy_element_stack[-1].append(
102 (yy_group_stack[-1], yy_group_stack[-2], _element)
104 del yy_group_stack[-2:]
106 groups[j][0].get_text()
109 if isinstance(groups[j], regex.RegexGroupElement) else
111 text = '''if yy_groups[{0:d}] is None:
112 yy_groups[{1:d}] = yy_group_text[yy_group_stack[-1]:yy_group_stack[-2]]
113 if '{2:s}' not in yy_groups_by_name:
114 yy_groups_by_name['{3:s}'] = yy_groups[{4:d}]
115 del yy_group_stack[-2:]
119 groups[j][0].get_text(),
120 groups[j][0].get_text(),
124 if isinstance(groups[j], regex.RegexGroupName) else
126 text = '''if yy_groups[{0:d}] is None:
127 yy_groups[{1:d}] = yy_group_text[yy_group_stack[-1]:yy_group_stack[-2]]
128 del yy_group_stack[-2:]
135 for j in range(len(groups))
139 # add group for default rule
140 group_ref_data.append(
143 'yy_rule{0:d}'.format(len(group_rules_text))
146 group_rules_text.append(
148 text = '''global yy_groups, yy_groups_by_name, yy_action
149 yy_groups = [yy_group_text[:yy_group_stack[-1]]]
150 yy_groups_by_name = {{}}
151 yy_action = yy_action{0:d}
158 _dfa = _ast.to_nfa(group_ref_data).to_dfa()
160 if skel_file is None:
161 skel_file = os.path.join(
163 'skel/skel_py_element.py' if _element else 'skel/skel_py.py'
168 if len(_ast[0].outfile) else
169 'lex_{0:s}.py'.format(_ast[0].prefix)
171 with open(skel_file, 'r') as fin:
172 with open(out_file, 'w+') as fout:
173 line = fin.readline()
175 if line == '# GENERATE SECTION1\n':
177 '''# GENERATE SECTION1 BEGIN
182 ast_text_to_python(i, '')
183 for i in _ast[0].code_blocks_text
188 elif line == '# GENERATE STARTCONDDECL\n':
190 '''# GENERATE STARTCONDDECL BEGIN
195 '{0:s} = {1:d}\n'.format(
196 _ast.start_conditions[i].name,
199 for i in range(len(_ast.start_conditions))
204 elif line == '# GENERATE SECTION2\n':
206 '''# GENERATE SECTION2 BEGIN
207 {0:s}{1:s}{2:s}{3:s}{4:s}{5:s}{6:s}yy_eof_actions = [{7:s}
213 '''def yy_action{0:d}():
214 {1:s} raise YYContinue()
217 ast_text_to_python(_ast.actions_text[i], ' ')
219 for i in range(len(_ast.actions_text))
224 '''def yy_rule{0:d}():
227 regex_text_to_python(group_rules_text[i], ' ')
229 for i in range(len(group_rules_text))
234 '''def yy_group{0:d}():
237 regex_text_to_python(group_actions_text[i], ' ')
239 for i in range(len(group_actions_text))
243 'yy_dfa_states = {0:s}'.format(repr(_dfa.states)),
247 'yy_dfa_actions = {0:s}'.format(
248 repr(_dfa.actions).replace('\'', '')
253 'yy_dfa_start_action = {0:s}'.format(repr(_dfa.start_action)),
258 '''def yy_eof_action{0:d}():
262 ast_text_to_python(_ast.eof_actions_text[i], ' ')
264 for i in range(len(_ast.eof_actions_text))
269 '\n yy_eof_action{0:d}'.format(i.eof_action)
270 for i in _ast.start_conditions
275 elif line == ' # GENERATE SECTION2INITIAL\n':
277 ''' # GENERATE SECTION2INITIAL BEGIN
282 ast_text_to_python(i, ' ')
283 for i in _ast[1].code_blocks_text
288 elif line == '# GENERATE SECTION3\n':
290 '''# GENERATE SECTION3 BEGIN
293 '' if len(_ast) < 3 else ast_text_to_python(_ast[2], '')
297 #if _ast[0].prefix != 'yy':
298 # line = line.replace('yywrap', '{0:s}wrap'.format(_ast[0].prefix))
300 line = fin.readline()