4 def generate_flex(_ast, _element, home_dir, skel_file, out_file):
5 # generate group_ref_data which emulates the old way where
6 # start = even, end = odd, remaining bits = flex rule index,
7 # ignoring user-defined groups by putting start = end = -1:
9 for i in range(len(_ast.flex_rules)):
10 group_ref_data.extend(
11 [(-1, -1) for j in range(len(_ast.flex_rules[i].groups0))] +
12 [(i * 2, i * 2 + 1)] +
13 [(-1, -1) for j in range(len(_ast.flex_rules[i].groups1))]
16 _nfa = _ast.to_nfa(group_ref_data)
18 # end of buffer expression (do here because only necessary for flex)
19 eob_regex = regex.RegexGroup(children = [regex.RegexEmpty()])
21 eob_regex.post_process(eob_groups, caseless = _ast[0].caseless)
22 assert len(eob_groups) == 1
25 [(len(_ast.flex_rules) * 2, len(_ast.flex_rules) * 2 + 1)]
28 _flex_dfa = _nfa.to_dfa().to_flex_dfa()
31 skel_file = os.path.join(home_dir, 'skel/skel_flex.c')
35 if len(_ast[0].outfile) else
36 'lex.{0:s}.c'.format(_ast[0].prefix)
38 with open(skel_file, 'r') as fin:
39 with open(out_file, 'w+') as fout:
42 if line == '/* GENERATE PREFIX */\n':
44 '''/* GENERATE PREFIX BEGIN */
45 {0:s}/* GENERATE END */
48 if _ast[0].prefix == 'yy' else
51 '#define yy{0:s} {1:s}{2:s}\n'.format(
68 'ensure_buffer_stack',
92 'ensure_buffer_stack',
125 elif line == '/* GENERATE YYWRAP */\n':
127 '''/* GENERATE YYWRAP BEGIN */
128 {0:s}/* GENERATE END */
131 if _ast[0].yywrap else
132 '''#define {0:s}wrap() (/*CONSTCOND*/1)
133 #define YY_SKIP_YYWRAP
139 elif line == '/* GENERATE TABLES */\n':
141 '''/* GENERATE TABLES BEGIN */
142 #define YY_END_OF_BUFFER {0:d}
143 static const flex_uint16_t yy_acclist[] = {{{1:s}
145 static const flex_uint16_t yy_accept[] = {{{2:s}
147 static const flex_uint16_t yy_base[] = {{{3:s}
149 static const flex_uint16_t yy_def[] = {{{4:s}
151 static const flex_uint16_t yy_nxt[] = {{{5:s}
153 static const flex_uint16_t yy_chk[] = {{{6:s}
157 len(_ast.actions_text),
164 for j in _flex_dfa.acclist[i:i + 10]
168 for i in range(0, _flex_dfa.acclist.shape[0], 10)
177 for j in _flex_dfa.accept[i:i + 10]
181 for i in range(0, _flex_dfa.accept.shape[0], 10)
190 for j in _flex_dfa.states[i:i + 10, 0]
194 for i in range(0, _flex_dfa.states.shape[0], 10)
203 for j in _flex_dfa.states[i:i + 10, 1]
207 for i in range(0, _flex_dfa.states.shape[0], 10)
216 for j in _flex_dfa.entries[i:i + 10, 0]
220 for i in range(0, _flex_dfa.entries.shape[0], 10)
229 for j in _flex_dfa.entries[i:i + 10, 1]
233 for i in range(0, _flex_dfa.entries.shape[0], 10)
238 elif line == '/* GENERATE SECTION1 */\n':
240 '''/* GENERATE SECTION1 BEGIN */
241 {0:s}/* GENERATE END */
243 ''.join([i.get_text() for i in _ast[0].code_blocks_text])
246 elif line == '/* GENERATE STARTCONDDECL */\n':
248 '''/* GENERATE STARTCONDDECL BEGIN */
249 {0:s}/* GENERATE END*/
253 '#define {0:s} {1:d}\n'.format(
254 _ast.start_conditions[i].name,
257 for i in range(len(_ast.start_conditions))
262 elif line == '/* GENERATE SECTION2INITIAL */\n':
264 '''/* GENERATE SECTION2INITIAL BEGIN */
265 {0:s}/* GENERATE END */
267 ''.join([i.get_text() for i in _ast[1].code_blocks_text])
270 elif line == '/* GENERATE SECTION2 */\n':
271 eof_action_to_start_conditions = [
274 for j in range(len(_ast.start_conditions))
275 if _ast.start_conditions[j].eof_action == i
277 for i in range(len(_ast.eof_actions_text))
279 #print('eof_action_to_start_conditions', eof_action_to_start_conditions)
281 '''/* GENERATE SECTION2 BEGIN */
282 {0:s}{1:s}/* GENERATE END */
291 _ast.actions_text[i].get_text()
293 for i in range(len(_ast.actions_text))
301 '\t\t\tcase YY_STATE_EOF({0:s}):\n'.format(
302 _ast.start_conditions[j].name
304 for j in eof_action_to_start_conditions[i]
307 _ast.eof_actions_text[i].get_text()
309 for i in range(len(_ast.eof_actions_text))
310 if len(eof_action_to_start_conditions[i]) > 0
315 elif line == '/* GENERATE SECTION3 */\n':
317 '''/* GENERATE SECTION3 BEGIN */
318 {0:s}/* GENERATE END */
320 '' if len(_ast) < 3 else _ast[2].get_text()
324 if _ast[0].prefix != 'yy':
325 line = line.replace('yywrap', '{0:s}wrap'.format(_ast[0].prefix))
327 line = fin.readline()