Line | Count | Source |
1 | | /* gen - actual generation (writing) of flex scanners */ |
2 | | |
3 | | /* Copyright (c) 1990 The Regents of the University of California. */ |
4 | | /* All rights reserved. */ |
5 | | |
6 | | /* This code is derived from software contributed to Berkeley by */ |
7 | | /* Vern Paxson. */ |
8 | | |
9 | | /* The United States Government has rights in this work pursuant */ |
10 | | /* to contract no. DE-AC03-76SF00098 between the United States */ |
11 | | /* Department of Energy and the University of California. */ |
12 | | |
13 | | /* This file is part of flex. */ |
14 | | |
15 | | /* Redistribution and use in source and binary forms, with or without */ |
16 | | /* modification, are permitted provided that the following conditions */ |
17 | | /* are met: */ |
18 | | |
19 | | /* 1. Redistributions of source code must retain the above copyright */ |
20 | | /* notice, this list of conditions and the following disclaimer. */ |
21 | | /* 2. Redistributions in binary form must reproduce the above copyright */ |
22 | | /* notice, this list of conditions and the following disclaimer in the */ |
23 | | /* documentation and/or other materials provided with the distribution. */ |
24 | | |
25 | | /* Neither the name of the University nor the names of its contributors */ |
26 | | /* may be used to endorse or promote products derived from this software */ |
27 | | /* without specific prior written permission. */ |
28 | | |
29 | | /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ |
30 | | /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ |
31 | | /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ |
32 | | /* PURPOSE. */ |
33 | | |
34 | | #include "flexdef.h" |
35 | | #include "tables.h" |
36 | | |
37 | | /* These typedefs are only used for computing footprint sizes, |
38 | | * You need to make sure they match reality in the skeleton file to |
39 | | * get accurate numbers, but they don't otherwise matter. |
40 | | */ |
41 | | typedef char YY_CHAR; |
42 | | struct yy_trans_info {int32_t yy_verify; int32_t yy_nxt;}; |
43 | | |
44 | | /* declare functions that have forward references */ |
45 | | |
46 | | static void genecs(void); |
47 | | |
48 | | struct packtype_t *optimize_pack(size_t sz) |
49 | 0 | { |
50 | | /* FIXME: There's a 32-bit assumption lurking here */ |
51 | 0 | static struct packtype_t out; |
52 | 0 | if (sz == 0) { |
53 | 0 | out.name = ctrl.long_align ? "M4_HOOK_INT32" : "M4_HOOK_INT16"; |
54 | 0 | out.width = ctrl.long_align ? 32 : 16; |
55 | 0 | } else { |
56 | 0 | out.name = (ctrl.long_align || sz >= INT16_MAX) ? "M4_HOOK_INT32" : "M4_HOOK_INT16"; |
57 | 0 | out.width = (ctrl.long_align || sz >= INT16_MAX) ? 32 : 16; |
58 | 0 | } |
59 | 0 | return &out; |
60 | 0 | } |
61 | | |
62 | | /* Almost everything is done in terms of arrays starting at 1, so provide |
63 | | * a null entry for the zero element of all C arrays. (The exception |
64 | | * to this is that the fast table representation generally uses the |
65 | | * 0 elements of its arrays, too.) |
66 | | */ |
67 | | |
68 | | /** Make the table for possible eol matches. |
69 | | * @return the newly allocated rule_can_match_eol table |
70 | | */ |
71 | | static struct yytbl_data *mkeoltbl (void) |
72 | 0 | { |
73 | 0 | int i; |
74 | 0 | flex_int8_t *tdata = 0; |
75 | 0 | struct yytbl_data *tbl; |
76 | |
|
77 | 0 | tbl = calloc(1, sizeof (struct yytbl_data)); |
78 | 0 | yytbl_data_init (tbl, YYTD_ID_RULE_CAN_MATCH_EOL); |
79 | 0 | tbl->td_flags = YYTD_DATA8; |
80 | 0 | tbl->td_lolen = (flex_uint32_t) (num_rules + 1); |
81 | 0 | tbl->td_data = tdata = |
82 | 0 | calloc(tbl->td_lolen, sizeof (flex_int8_t)); |
83 | |
|
84 | 0 | for (i = 1; i <= num_rules; i++) |
85 | 0 | tdata[i] = rule_has_nl[i] ? 1 : 0; |
86 | |
|
87 | 0 | return tbl; |
88 | 0 | } |
89 | | |
90 | | /* Generate the table for possible eol matches. */ |
91 | | static void geneoltbl (void) |
92 | 0 | { |
93 | 0 | int i; |
94 | 0 | struct packtype_t *ptype = optimize_pack(num_rules); |
95 | |
|
96 | 0 | outn ("m4_ifdef( [[M4_MODE_YYLINENO]],[["); |
97 | 0 | out_str ("m4_define([[M4_HOOK_EOLTABLE_TYPE]], [[%s]])\n", ptype->name); |
98 | 0 | out_dec ("m4_define([[M4_HOOK_EOLTABLE_SIZE]], [[%d]])", num_rules + 1); |
99 | 0 | outn ("m4_define([[M4_HOOK_EOLTABLE_BODY]], [[m4_dnl"); |
100 | |
|
101 | 0 | if (gentables) { |
102 | 0 | for (i = 1; i <= num_rules; i++) { |
103 | 0 | out_dec ("%d, ", rule_has_nl[i] ? 1 : 0); |
104 | | /* format nicely, 20 numbers per line. */ |
105 | 0 | if ((i % 20) == 19) |
106 | 0 | out ("\n "); |
107 | 0 | } |
108 | 0 | } |
109 | 0 | footprint += num_rules * ptype->width; |
110 | 0 | outn ("]])"); |
111 | 0 | outn ("]])"); |
112 | 0 | } |
113 | | |
114 | | |
115 | | /** mkctbl - make full speed compressed transition table |
116 | | * This is an array of structs; each struct a pair of integers. |
117 | | * You should call mkssltbl() immediately after this. |
118 | | * Then, I think, mkecstbl(). Arrrg. |
119 | | * @return the newly allocated trans table |
120 | | */ |
121 | | |
122 | | static struct yytbl_data *mkctbl (void) |
123 | 0 | { |
124 | 0 | int i; |
125 | 0 | struct yytbl_data *tbl = 0; |
126 | 0 | flex_int32_t *tdata = 0, curr = 0; |
127 | 0 | int end_of_buffer_action = num_rules + 1; |
128 | |
|
129 | 0 | struct packtype_t *ptype = optimize_pack(tblend + 2 + 1); |
130 | 0 | out_str ("m4_define([[M4_HOOK_MKCTBL_TYPE]], [[%s]])", ptype->name); |
131 | |
|
132 | 0 | tbl = calloc(1, sizeof (struct yytbl_data)); |
133 | 0 | yytbl_data_init (tbl, YYTD_ID_TRANSITION); |
134 | 0 | tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT; |
135 | 0 | tbl->td_hilen = 0; |
136 | 0 | tbl->td_lolen = (flex_uint32_t) (tblend + 2 + 1); /* number of structs */ |
137 | |
|
138 | 0 | tbl->td_data = tdata = |
139 | 0 | calloc(tbl->td_lolen * 2, sizeof (flex_int32_t)); |
140 | | |
141 | | /* We want the transition to be represented as the offset to the |
142 | | * next state, not the actual state number, which is what it currently |
143 | | * is. The offset is base[nxt[i]] - (base of current state)]. That's |
144 | | * just the difference between the starting points of the two involved |
145 | | * states (to - from). |
146 | | * |
147 | | * First, though, we need to find some way to put in our end-of-buffer |
148 | | * flags and states. We do this by making a state with absolutely no |
149 | | * transitions. We put it at the end of the table. |
150 | | */ |
151 | | |
152 | | /* We need to have room in nxt/chk for two more slots: One for the |
153 | | * action and one for the end-of-buffer transition. We now *assume* |
154 | | * that we're guaranteed the only character we'll try to index this |
155 | | * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure |
156 | | * there's room for jam entries for other characters. |
157 | | */ |
158 | |
|
159 | 0 | while (tblend + 2 >= current_max_xpairs) |
160 | 0 | expand_nxt_chk (); |
161 | |
|
162 | 0 | while (lastdfa + 1 >= current_max_dfas) |
163 | 0 | increase_max_dfas (); |
164 | |
|
165 | 0 | base[lastdfa + 1] = tblend + 2; |
166 | 0 | nxt[tblend + 1] = end_of_buffer_action; |
167 | 0 | chk[tblend + 1] = numecs + 1; |
168 | 0 | chk[tblend + 2] = 1; /* anything but EOB */ |
169 | | |
170 | | /* So that "make test" won't show arb. differences. */ |
171 | 0 | nxt[tblend + 2] = 0; |
172 | | |
173 | | /* Make sure every state has an end-of-buffer transition and an |
174 | | * action #. |
175 | | */ |
176 | 0 | for (i = 0; i <= lastdfa; ++i) { |
177 | 0 | int anum = dfaacc[i].dfaacc_state; |
178 | 0 | int offset = base[i]; |
179 | |
|
180 | 0 | chk[offset] = EOB_POSITION; |
181 | 0 | chk[offset - 1] = ACTION_POSITION; |
182 | 0 | nxt[offset - 1] = anum; /* action number */ |
183 | 0 | } |
184 | |
|
185 | 0 | for (i = 0; i <= tblend; ++i) { |
186 | 0 | if (chk[i] == EOB_POSITION) { |
187 | 0 | tdata[curr++] = 0; |
188 | 0 | tdata[curr++] = base[lastdfa + 1] - i; |
189 | 0 | } |
190 | | |
191 | 0 | else if (chk[i] == ACTION_POSITION) { |
192 | 0 | tdata[curr++] = 0; |
193 | 0 | tdata[curr++] = nxt[i]; |
194 | 0 | } |
195 | | |
196 | 0 | else if (chk[i] > numecs || chk[i] == 0) { |
197 | 0 | tdata[curr++] = 0; |
198 | 0 | tdata[curr++] = 0; |
199 | 0 | } |
200 | 0 | else { /* verify, transition */ |
201 | |
|
202 | 0 | tdata[curr++] = chk[i]; |
203 | 0 | tdata[curr++] = base[nxt[i]] - (i - chk[i]); |
204 | 0 | } |
205 | 0 | } |
206 | | |
207 | | /* Here's the final, end-of-buffer state. */ |
208 | 0 | tdata[curr++] = chk[tblend + 1]; |
209 | 0 | tdata[curr++] = nxt[tblend + 1]; |
210 | |
|
211 | 0 | tdata[curr++] = chk[tblend + 2]; |
212 | 0 | tdata[curr++] = nxt[tblend + 2]; |
213 | |
|
214 | 0 | return tbl; |
215 | 0 | } |
216 | | |
217 | | |
218 | | /** Make start_state_list table. |
219 | | * @return the newly allocated start_state_list table |
220 | | */ |
221 | | static struct yytbl_data *mkssltbl (void) |
222 | 0 | { |
223 | 0 | struct yytbl_data *tbl = 0; |
224 | 0 | flex_int32_t *tdata = 0; |
225 | 0 | flex_int32_t i; |
226 | |
|
227 | 0 | tbl = calloc(1, sizeof (struct yytbl_data)); |
228 | 0 | yytbl_data_init (tbl, YYTD_ID_START_STATE_LIST); |
229 | 0 | tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS; |
230 | 0 | tbl->td_hilen = 0; |
231 | 0 | tbl->td_lolen = (flex_uint32_t) (lastsc * 2 + 1); |
232 | |
|
233 | 0 | tbl->td_data = tdata = |
234 | 0 | calloc(tbl->td_lolen, sizeof (flex_int32_t)); |
235 | |
|
236 | 0 | for (i = 0; i <= lastsc * 2; ++i) |
237 | 0 | tdata[i] = base[i]; |
238 | |
|
239 | 0 | return tbl; |
240 | 0 | } |
241 | | |
242 | | |
243 | | |
244 | | /* genctbl - generates full speed compressed transition table */ |
245 | | |
246 | | static void genctbl(void) |
247 | 0 | { |
248 | 0 | int i; |
249 | 0 | int end_of_buffer_action = num_rules + 1; |
250 | | |
251 | | /* Table of verify for transition and offset to next state. */ |
252 | 0 | out_dec ("m4_define([[M4_HOOK_TRANSTABLE_SIZE]], [[%d]])", tblend + 2 + 1); |
253 | 0 | outn ("m4_define([[M4_HOOK_TRANSTABLE_BODY]], [[m4_dnl"); |
254 | | |
255 | | /* We want the transition to be represented as the offset to the |
256 | | * next state, not the actual state number, which is what it currently |
257 | | * is. The offset is base[nxt[i]] - (base of current state)]. That's |
258 | | * just the difference between the starting points of the two involved |
259 | | * states (to - from). |
260 | | * |
261 | | * First, though, we need to find some way to put in our end-of-buffer |
262 | | * flags and states. We do this by making a state with absolutely no |
263 | | * transitions. We put it at the end of the table. |
264 | | */ |
265 | | |
266 | | /* We need to have room in nxt/chk for two more slots: One for the |
267 | | * action and one for the end-of-buffer transition. We now *assume* |
268 | | * that we're guaranteed the only character we'll try to index this |
269 | | * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure |
270 | | * there's room for jam entries for other characters. |
271 | | */ |
272 | |
|
273 | 0 | while (tblend + 2 >= current_max_xpairs) |
274 | 0 | expand_nxt_chk (); |
275 | |
|
276 | 0 | while (lastdfa + 1 >= current_max_dfas) |
277 | 0 | increase_max_dfas (); |
278 | |
|
279 | 0 | base[lastdfa + 1] = tblend + 2; |
280 | 0 | nxt[tblend + 1] = end_of_buffer_action; |
281 | 0 | chk[tblend + 1] = numecs + 1; |
282 | 0 | chk[tblend + 2] = 1; /* anything but EOB */ |
283 | | |
284 | | /* So that "make test" won't show arb. differences. */ |
285 | 0 | nxt[tblend + 2] = 0; |
286 | | |
287 | | /* Make sure every state has an end-of-buffer transition and an |
288 | | * action #. |
289 | | */ |
290 | 0 | for (i = 0; i <= lastdfa; ++i) { |
291 | 0 | int anum = dfaacc[i].dfaacc_state; |
292 | 0 | int offset = base[i]; |
293 | |
|
294 | 0 | chk[offset] = EOB_POSITION; |
295 | 0 | chk[offset - 1] = ACTION_POSITION; |
296 | 0 | nxt[offset - 1] = anum; /* action number */ |
297 | 0 | } |
298 | |
|
299 | 0 | for (i = 0; i <= tblend; ++i) { |
300 | 0 | if (chk[i] == EOB_POSITION) |
301 | 0 | transition_struct_out (0, base[lastdfa + 1] - i); |
302 | | |
303 | 0 | else if (chk[i] == ACTION_POSITION) |
304 | 0 | transition_struct_out (0, nxt[i]); |
305 | | |
306 | 0 | else if (chk[i] > numecs || chk[i] == 0) |
307 | 0 | transition_struct_out (0, 0); /* unused slot */ |
308 | | |
309 | 0 | else /* verify, transition */ |
310 | 0 | transition_struct_out (chk[i], |
311 | 0 | base[nxt[i]] - (i - |
312 | 0 | chk[i])); |
313 | 0 | } |
314 | | |
315 | | |
316 | | /* Here's the final, end-of-buffer state. */ |
317 | 0 | transition_struct_out (chk[tblend + 1], nxt[tblend + 1]); |
318 | 0 | transition_struct_out (chk[tblend + 2], nxt[tblend + 2]); |
319 | |
|
320 | 0 | outn ("]])"); |
321 | 0 | footprint += sizeof(struct yy_trans_info) * (tblend + 2 + 1); |
322 | |
|
323 | 0 | out_dec ("m4_define([[M4_HOOK_STARTTABLE_SIZE]], [[%d]])", lastsc * 2 + 1); |
324 | 0 | if (gentables) { |
325 | 0 | outn ("m4_define([[M4_HOOK_STARTTABLE_BODY]], [[m4_dnl"); |
326 | 0 | for (i = 0; i <= lastsc * 2; ++i) |
327 | 0 | out_dec ("M4_HOOK_STATE_ENTRY_FORMAT(%d)", base[i]); |
328 | |
|
329 | 0 | dataend (NULL); |
330 | 0 | outn("]])"); |
331 | 0 | footprint += sizeof(struct yy_trans_info *) * (lastsc * 2 + 1); |
332 | 0 | } |
333 | |
|
334 | 0 | if (ctrl.useecs) |
335 | 0 | genecs (); |
336 | 0 | } |
337 | | |
338 | | |
339 | | /* mkecstbl - Make equivalence-class tables. */ |
340 | | |
341 | | static struct yytbl_data *mkecstbl (void) |
342 | 0 | { |
343 | 0 | int i; |
344 | 0 | struct yytbl_data *tbl = 0; |
345 | 0 | flex_int32_t *tdata = 0; |
346 | |
|
347 | 0 | tbl = calloc(1, sizeof (struct yytbl_data)); |
348 | 0 | yytbl_data_init (tbl, YYTD_ID_EC); |
349 | 0 | tbl->td_flags |= YYTD_DATA32; |
350 | 0 | tbl->td_hilen = 0; |
351 | 0 | tbl->td_lolen = (flex_uint32_t) ctrl.csize; |
352 | |
|
353 | 0 | tbl->td_data = tdata = |
354 | 0 | calloc(tbl->td_lolen, sizeof (flex_int32_t)); |
355 | |
|
356 | 0 | for (i = 1; i < ctrl.csize; ++i) { |
357 | 0 | ecgroup[i] = ABS (ecgroup[i]); |
358 | 0 | tdata[i] = ecgroup[i]; |
359 | 0 | } |
360 | |
|
361 | 0 | return tbl; |
362 | 0 | } |
363 | | |
364 | | /* Generate equivalence-class tables. */ |
365 | | |
366 | | static void genecs(void) |
367 | 0 | { |
368 | 0 | int ch, row; |
369 | 0 | int numrows; |
370 | |
|
371 | 0 | out_dec ("m4_define([[M4_HOOK_ECSTABLE_SIZE]], [[%d]])", ctrl.csize); |
372 | 0 | outn ("m4_define([[M4_HOOK_ECSTABLE_BODY]], [[m4_dnl"); |
373 | |
|
374 | 0 | for (ch = 1; ch < ctrl.csize; ++ch) { |
375 | 0 | ecgroup[ch] = ABS (ecgroup[ch]); |
376 | 0 | mkdata (ecgroup[ch]); |
377 | 0 | } |
378 | |
|
379 | 0 | dataend (NULL); |
380 | 0 | outn("]])"); |
381 | 0 | footprint += sizeof(YY_CHAR) * ctrl.csize; |
382 | |
|
383 | 0 | if (env.trace) { |
384 | 0 | fputs (_("\n\nEquivalence Classes:\n\n"), stderr); |
385 | | |
386 | | /* Print in 8 columns */ |
387 | 0 | numrows = ctrl.csize / 8; |
388 | |
|
389 | 0 | for (row = 0; row < numrows; ++row) { |
390 | 0 | for (ch = row; ch < ctrl.csize; ch += numrows) { |
391 | 0 | fprintf (stderr, "%4s = %-2d", |
392 | 0 | readable_form (ch), ecgroup[ch]); |
393 | |
|
394 | 0 | putc (' ', stderr); |
395 | 0 | } |
396 | |
|
397 | 0 | putc ('\n', stderr); |
398 | 0 | } |
399 | 0 | } |
400 | 0 | } |
401 | | |
402 | | /* mkftbl - make the full table and return the struct . |
403 | | * you should call mkecstbl() after this. |
404 | | */ |
405 | | |
406 | | static struct yytbl_data *mkftbl(void) |
407 | 0 | { |
408 | 0 | int i; |
409 | 0 | int end_of_buffer_action = num_rules + 1; |
410 | 0 | struct yytbl_data *tbl; |
411 | 0 | flex_int32_t *tdata = 0; |
412 | |
|
413 | 0 | tbl = calloc(1, sizeof (struct yytbl_data)); |
414 | 0 | yytbl_data_init (tbl, YYTD_ID_ACCEPT); |
415 | 0 | tbl->td_flags |= YYTD_DATA32; |
416 | 0 | tbl->td_hilen = 0; /* it's a one-dimensional array */ |
417 | 0 | tbl->td_lolen = (flex_uint32_t) (lastdfa + 1); |
418 | |
|
419 | 0 | tbl->td_data = tdata = |
420 | 0 | calloc(tbl->td_lolen, sizeof (flex_int32_t)); |
421 | |
|
422 | 0 | dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; |
423 | |
|
424 | 0 | for (i = 1; i <= lastdfa; ++i) { |
425 | 0 | int anum = dfaacc[i].dfaacc_state; |
426 | |
|
427 | 0 | tdata[i] = anum; |
428 | |
|
429 | 0 | if (env.trace && anum) |
430 | 0 | fprintf (stderr, _("state # %d accepts: [%d]\n"), |
431 | 0 | i, anum); |
432 | 0 | } |
433 | |
|
434 | 0 | return tbl; |
435 | 0 | } |
436 | | |
437 | | |
438 | | /* genftbl - generate full transition table */ |
439 | | |
440 | | static void genftbl(void) |
441 | 0 | { |
442 | 0 | int i; |
443 | 0 | int end_of_buffer_action = num_rules + 1; |
444 | 0 | struct packtype_t *ptype = optimize_pack(num_rules + 1); |
445 | |
|
446 | 0 | dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; |
447 | |
|
448 | 0 | outn ("m4_define([[M4_HOOK_NEED_ACCEPT]], 1)"); |
449 | 0 | out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name); |
450 | 0 | out_dec ("m4_define([[M4_HOOK_ACCEPT_SIZE]], [[%d]])", lastdfa + 1); |
451 | 0 | outn ("m4_define([[M4_HOOK_ACCEPT_BODY]], [[m4_dnl"); |
452 | |
|
453 | 0 | for (i = 1; i <= lastdfa; ++i) { |
454 | 0 | int anum = dfaacc[i].dfaacc_state; |
455 | |
|
456 | 0 | mkdata (anum); |
457 | |
|
458 | 0 | if (env.trace && anum) |
459 | 0 | fprintf (stderr, _("state # %d accepts: [%d]\n"), |
460 | 0 | i, anum); |
461 | 0 | } |
462 | |
|
463 | 0 | dataend (NULL); |
464 | 0 | outn("]])"); |
465 | 0 | footprint += (lastdfa + 1) * ptype->width; |
466 | |
|
467 | 0 | if (ctrl.useecs) |
468 | 0 | genecs (); |
469 | | |
470 | | /* Don't have to dump the actual full table entries - they were |
471 | | * created on-the-fly. |
472 | | */ |
473 | 0 | } |
474 | | |
475 | | /* gentabs - generate data statements for the transition tables */ |
476 | | |
477 | | static void gentabs(void) |
478 | 0 | { |
479 | 0 | int sz, i, j, k, *accset, nacc, *acc_array, total_states; |
480 | 0 | int end_of_buffer_action = num_rules + 1; |
481 | 0 | struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0, |
482 | 0 | *yydef_tbl = 0, *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl=0; |
483 | 0 | flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0, |
484 | 0 | *yynxt_data = 0, *yychk_data = 0, *yyacclist_data=0; |
485 | 0 | flex_int32_t yybase_curr = 0, yyacclist_curr=0,yyacc_curr=0; |
486 | 0 | struct packtype_t *ptype; |
487 | |
|
488 | 0 | acc_array = allocate_integer_array (current_max_dfas); |
489 | 0 | nummt = 0; |
490 | | |
491 | | /* The compressed table format jams by entering the "jam state", |
492 | | * losing information about the previous state in the process. |
493 | | * In order to recover the previous state, we effectively need |
494 | | * to keep backing-up information. |
495 | | */ |
496 | 0 | ++num_backing_up; |
497 | |
|
498 | 0 | if (reject) { |
499 | | /* Write out accepting list and pointer list. |
500 | | |
501 | | * First we generate the "yy_acclist" array. In the process, |
502 | | * we compute the indices that will go into the "yy_accept" |
503 | | * array, and save the indices in the dfaacc array. |
504 | | */ |
505 | 0 | int EOB_accepting_list[2]; |
506 | | |
507 | | /* Set up accepting structures for the End Of Buffer state. */ |
508 | 0 | EOB_accepting_list[0] = 0; |
509 | 0 | EOB_accepting_list[1] = end_of_buffer_action; |
510 | 0 | accsiz[end_of_buffer_state] = 1; |
511 | 0 | dfaacc[end_of_buffer_state].dfaacc_set = |
512 | 0 | EOB_accepting_list; |
513 | |
|
514 | 0 | sz = MAX (numas, 1) + 1; |
515 | 0 | ptype = optimize_pack(sz); |
516 | 0 | out_str ("m4_define([[M4_HOOK_ACCLIST_TYPE]], [[%s]])", ptype->name); |
517 | 0 | out_dec ("m4_define([[M4_HOOK_ACCLIST_SIZE]], [[%d]])", sz); |
518 | 0 | outn ("m4_define([[M4_HOOK_ACCLIST_BODY]], [[m4_dnl"); |
519 | |
|
520 | 0 | yyacclist_tbl = calloc(1,sizeof(struct yytbl_data)); |
521 | 0 | yytbl_data_init (yyacclist_tbl, YYTD_ID_ACCLIST); |
522 | 0 | yyacclist_tbl->td_lolen = (flex_uint32_t) (MAX(numas,1) + 1); |
523 | 0 | yyacclist_tbl->td_data = yyacclist_data = |
524 | 0 | calloc(yyacclist_tbl->td_lolen, sizeof (flex_int32_t)); |
525 | 0 | yyacclist_curr = 1; |
526 | |
|
527 | 0 | j = 1; /* index into "yy_acclist" array */ |
528 | |
|
529 | 0 | for (i = 1; i <= lastdfa; ++i) { |
530 | 0 | acc_array[i] = j; |
531 | |
|
532 | 0 | if (accsiz[i] != 0) { |
533 | 0 | accset = dfaacc[i].dfaacc_set; |
534 | 0 | nacc = accsiz[i]; |
535 | |
|
536 | 0 | if (env.trace) |
537 | 0 | fprintf (stderr, |
538 | 0 | _("state # %d accepts: "), |
539 | 0 | i); |
540 | |
|
541 | 0 | for (k = 1; k <= nacc; ++k) { |
542 | 0 | int accnum = accset[k]; |
543 | |
|
544 | 0 | ++j; |
545 | |
|
546 | 0 | if (variable_trailing_context_rules |
547 | 0 | && !(accnum & |
548 | 0 | YY_TRAILING_HEAD_MASK) |
549 | 0 | && accnum > 0 |
550 | 0 | && accnum <= num_rules |
551 | 0 | && rule_type[accnum] == |
552 | 0 | RULE_VARIABLE) { |
553 | | /* Special hack to flag |
554 | | * accepting number as part |
555 | | * of trailing context rule. |
556 | | */ |
557 | 0 | accnum |= YY_TRAILING_MASK; |
558 | 0 | } |
559 | |
|
560 | 0 | mkdata (accnum); |
561 | 0 | yyacclist_data[yyacclist_curr++] = accnum; |
562 | |
|
563 | 0 | if (env.trace) { |
564 | 0 | fprintf (stderr, "[%d]", |
565 | 0 | accset[k]); |
566 | |
|
567 | 0 | if (k < nacc) |
568 | 0 | fputs (", ", |
569 | 0 | stderr); |
570 | 0 | else |
571 | 0 | putc ('\n', |
572 | 0 | stderr); |
573 | 0 | } |
574 | 0 | } |
575 | 0 | } |
576 | 0 | } |
577 | | |
578 | | /* add accepting number for the "jam" state */ |
579 | 0 | acc_array[i] = j; |
580 | |
|
581 | 0 | dataend (NULL); |
582 | 0 | outn("]])"); |
583 | 0 | footprint += sz * ptype->width; |
584 | 0 | if (tablesext) { |
585 | 0 | yytbl_data_compress (yyacclist_tbl); |
586 | 0 | if (yytbl_data_fwrite (&tableswr, yyacclist_tbl) < 0) |
587 | 0 | flexerror (_("Could not write yyacclist_tbl")); |
588 | 0 | yytbl_data_destroy (yyacclist_tbl); |
589 | 0 | yyacclist_tbl = NULL; |
590 | 0 | } |
591 | 0 | } |
592 | | |
593 | 0 | else { |
594 | 0 | dfaacc[end_of_buffer_state].dfaacc_state = |
595 | 0 | end_of_buffer_action; |
596 | |
|
597 | 0 | for (i = 1; i <= lastdfa; ++i) |
598 | 0 | acc_array[i] = dfaacc[i].dfaacc_state; |
599 | | |
600 | | /* add accepting number for jam state */ |
601 | 0 | acc_array[i] = 0; |
602 | 0 | } |
603 | | |
604 | | /* Begin generating yy_accept */ |
605 | | |
606 | | /* Spit out "yy_accept" array. If we're doing "reject", it'll be |
607 | | * pointers into the "yy_acclist" array. Otherwise it's actual |
608 | | * accepting numbers. In either case, we just dump the numbers. |
609 | | */ |
610 | | |
611 | | /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays |
612 | | * beginning at 0 and for "jam" state. |
613 | | */ |
614 | 0 | sz = lastdfa + 2; |
615 | |
|
616 | 0 | if (reject) |
617 | | /* We put a "cap" on the table associating lists of accepting |
618 | | * numbers with state numbers. This is needed because we tell |
619 | | * where the end of an accepting list is by looking at where |
620 | | * the list for the next state starts. |
621 | | */ |
622 | 0 | ++sz; |
623 | | |
624 | | /* Note that this table is alternately defined if ctrl.fulltbl */ |
625 | 0 | ptype = optimize_pack(sz); |
626 | 0 | outn ("m4_define([[M4_HOOK_NEED_ACCEPT]], 1)"); |
627 | 0 | out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name); |
628 | 0 | out_dec ("m4_define([[M4_HOOK_ACCEPT_SIZE]], [[%d]])", sz); |
629 | 0 | outn ("m4_define([[M4_HOOK_ACCEPT_BODY]], [[m4_dnl"); |
630 | |
|
631 | 0 | yyacc_tbl = calloc(1, sizeof (struct yytbl_data)); |
632 | 0 | yytbl_data_init (yyacc_tbl, YYTD_ID_ACCEPT); |
633 | 0 | yyacc_tbl->td_lolen = (flex_uint32_t) sz; |
634 | 0 | yyacc_tbl->td_data = yyacc_data = |
635 | 0 | calloc(yyacc_tbl->td_lolen, sizeof (flex_int32_t)); |
636 | 0 | yyacc_curr=1; |
637 | |
|
638 | 0 | for (i = 1; i <= lastdfa; ++i) { |
639 | 0 | mkdata (acc_array[i]); |
640 | 0 | yyacc_data[yyacc_curr++] = acc_array[i]; |
641 | |
|
642 | 0 | if (!reject && env.trace && acc_array[i]) |
643 | 0 | fprintf (stderr, _("state # %d accepts: [%d]\n"), |
644 | 0 | i, acc_array[i]); |
645 | 0 | } |
646 | | |
647 | | /* Add entry for "jam" state. */ |
648 | 0 | mkdata (acc_array[i]); |
649 | 0 | yyacc_data[yyacc_curr++] = acc_array[i]; |
650 | |
|
651 | 0 | if (reject) { |
652 | | /* Add "cap" for the list. */ |
653 | 0 | mkdata (acc_array[i]); |
654 | 0 | yyacc_data[yyacc_curr++] = acc_array[i]; |
655 | 0 | } |
656 | |
|
657 | 0 | dataend (NULL); |
658 | 0 | outn ("]])"); |
659 | 0 | footprint += sz * ptype->width; |
660 | |
|
661 | 0 | if (tablesext) { |
662 | 0 | yytbl_data_compress (yyacc_tbl); |
663 | 0 | if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0) |
664 | 0 | flexerror (_("Could not write yyacc_tbl")); |
665 | 0 | } |
666 | 0 | yytbl_data_destroy (yyacc_tbl); |
667 | 0 | yyacc_tbl = NULL; |
668 | | /* End generating yy_accept */ |
669 | |
|
670 | 0 | if (ctrl.useecs) { |
671 | |
|
672 | 0 | genecs (); |
673 | 0 | if (tablesext) { |
674 | 0 | struct yytbl_data *tbl; |
675 | |
|
676 | 0 | tbl = mkecstbl (); |
677 | 0 | yytbl_data_compress (tbl); |
678 | 0 | if (yytbl_data_fwrite (&tableswr, tbl) < 0) |
679 | 0 | flexerror (_("Could not write ecstbl")); |
680 | 0 | yytbl_data_destroy (tbl); |
681 | 0 | tbl = 0; |
682 | 0 | } |
683 | 0 | } |
684 | |
|
685 | 0 | if (ctrl.usemecs) { |
686 | | /* Begin generating yy_meta */ |
687 | | /* Write out meta-equivalence classes (used to index |
688 | | * templates with). |
689 | | */ |
690 | 0 | flex_int32_t *yymecs_data = 0; |
691 | 0 | yymeta_tbl = calloc(1, sizeof (struct yytbl_data)); |
692 | 0 | yytbl_data_init (yymeta_tbl, YYTD_ID_META); |
693 | 0 | yymeta_tbl->td_lolen = (flex_uint32_t) (numecs + 1); |
694 | 0 | yymeta_tbl->td_data = yymecs_data = |
695 | 0 | calloc(yymeta_tbl->td_lolen, |
696 | 0 | sizeof (flex_int32_t)); |
697 | |
|
698 | 0 | if (env.trace) |
699 | 0 | fputs (_("\n\nMeta-Equivalence Classes:\n"), |
700 | 0 | stderr); |
701 | 0 | out_dec ("m4_define([[M4_HOOK_MECSTABLE_SIZE]], [[%d]])", numecs+1); |
702 | 0 | outn ("m4_define([[M4_HOOK_MECSTABLE_BODY]], [[m4_dnl"); |
703 | | |
704 | 0 | for (i = 1; i <= numecs; ++i) { |
705 | 0 | if (env.trace) |
706 | 0 | fprintf (stderr, "%d = %d\n", |
707 | 0 | i, ABS (tecbck[i])); |
708 | |
|
709 | 0 | mkdata (ABS (tecbck[i])); |
710 | 0 | yymecs_data[i] = ABS (tecbck[i]); |
711 | 0 | } |
712 | |
|
713 | 0 | dataend (NULL); |
714 | 0 | outn ("]])"); |
715 | 0 | footprint += sizeof(YY_CHAR) * (numecs + 1); |
716 | 0 | if (tablesext) { |
717 | 0 | yytbl_data_compress (yymeta_tbl); |
718 | 0 | if (yytbl_data_fwrite (&tableswr, yymeta_tbl) < 0) |
719 | 0 | flexerror (_("Could not write yymeta_tbl")); |
720 | 0 | } |
721 | 0 | yytbl_data_destroy (yymeta_tbl); |
722 | 0 | yymeta_tbl = NULL; |
723 | | /* End generating yy_meta */ |
724 | 0 | } |
725 | |
|
726 | 0 | total_states = lastdfa + numtemps; |
727 | | |
728 | | /* Begin generating yy_base */ |
729 | 0 | sz = total_states + 1; |
730 | 0 | ptype = optimize_pack(sz); |
731 | 0 | out_str ("m4_define([[M4_HOOK_BASE_TYPE]], [[%s]])", ptype->name); |
732 | 0 | out_dec ("m4_define([[M4_HOOK_BASE_SIZE]], [[%d]])", sz); |
733 | 0 | outn ("m4_define([[M4_HOOK_BASE_BODY]], [[m4_dnl"); |
734 | |
|
735 | 0 | yybase_tbl = calloc (1, sizeof (struct yytbl_data)); |
736 | 0 | yytbl_data_init (yybase_tbl, YYTD_ID_BASE); |
737 | 0 | yybase_tbl->td_lolen = (flex_uint32_t) (total_states + 1); |
738 | 0 | yybase_tbl->td_data = yybase_data = |
739 | 0 | calloc(yybase_tbl->td_lolen, |
740 | 0 | sizeof (flex_int32_t)); |
741 | 0 | yybase_curr = 1; |
742 | |
|
743 | 0 | for (i = 1; i <= lastdfa; ++i) { |
744 | 0 | int d = def[i]; |
745 | |
|
746 | 0 | if (base[i] == JAMSTATE) |
747 | 0 | base[i] = jambase; |
748 | |
|
749 | 0 | if (d == JAMSTATE) |
750 | 0 | def[i] = jamstate; |
751 | | |
752 | 0 | else if (d < 0) { |
753 | | /* Template reference. */ |
754 | 0 | ++tmpuses; |
755 | 0 | def[i] = lastdfa - d + 1; |
756 | 0 | } |
757 | |
|
758 | 0 | mkdata (base[i]); |
759 | 0 | yybase_data[yybase_curr++] = base[i]; |
760 | 0 | } |
761 | | |
762 | | /* Generate jam state's base index. */ |
763 | 0 | mkdata (base[i]); |
764 | 0 | yybase_data[yybase_curr++] = base[i]; |
765 | |
|
766 | 0 | for (++i /* skip jam state */ ; i <= total_states; ++i) { |
767 | 0 | mkdata (base[i]); |
768 | 0 | yybase_data[yybase_curr++] = base[i]; |
769 | 0 | def[i] = jamstate; |
770 | 0 | } |
771 | |
|
772 | 0 | dataend (NULL); |
773 | 0 | outn ("]])"); |
774 | 0 | footprint += sz * ptype->width; |
775 | |
|
776 | 0 | if (tablesext) { |
777 | 0 | yytbl_data_compress (yybase_tbl); |
778 | 0 | if (yytbl_data_fwrite (&tableswr, yybase_tbl) < 0) |
779 | 0 | flexerror (_("Could not write yybase_tbl")); |
780 | 0 | } |
781 | 0 | yytbl_data_destroy (yybase_tbl); |
782 | 0 | yybase_tbl = NULL; |
783 | | /* End generating yy_base */ |
784 | | |
785 | | |
786 | | /* Begin generating yy_def */ |
787 | 0 | ptype = optimize_pack(total_states + 1); |
788 | 0 | out_str ("m4_define([[M4_HOOK_DEF_TYPE]], [[%s]])", ptype->name); |
789 | 0 | out_dec ("m4_define([[M4_HOOK_DEF_SIZE]], [[%d]])", total_states + 1); |
790 | 0 | outn ("m4_define([[M4_HOOK_DEF_BODY]], [[m4_dnl"); |
791 | |
|
792 | 0 | yydef_tbl = calloc(1, sizeof (struct yytbl_data)); |
793 | 0 | yytbl_data_init (yydef_tbl, YYTD_ID_DEF); |
794 | 0 | yydef_tbl->td_lolen = (flex_uint32_t)(total_states + 1); |
795 | 0 | yydef_tbl->td_data = yydef_data = |
796 | 0 | calloc(yydef_tbl->td_lolen, sizeof (flex_int32_t)); |
797 | |
|
798 | 0 | for (i = 1; i <= total_states; ++i) { |
799 | 0 | mkdata (def[i]); |
800 | 0 | yydef_data[i] = def[i]; |
801 | 0 | } |
802 | |
|
803 | 0 | dataend (NULL); |
804 | 0 | outn ("]])"); |
805 | 0 | footprint += (total_states + 1) * ptype->width; |
806 | |
|
807 | 0 | if (tablesext) { |
808 | 0 | yytbl_data_compress (yydef_tbl); |
809 | 0 | if (yytbl_data_fwrite (&tableswr, yydef_tbl) < 0) |
810 | 0 | flexerror (_("Could not write yydef_tbl")); |
811 | 0 | } |
812 | 0 | yytbl_data_destroy (yydef_tbl); |
813 | 0 | yydef_tbl = NULL; |
814 | | /* End generating yy_def */ |
815 | | |
816 | |
|
817 | 0 | ptype = optimize_pack(tblend + 1); |
818 | | /* Note: Used when !ctrl.fulltbl && !ctrl.fullspd). |
819 | | * (Alternately defined when ctrl.fullspd) |
820 | | */ |
821 | 0 | out_str ("m4_define([[M4_HOOK_YYNXT_TYPE]], [[%s]])", ptype->name); |
822 | 0 | out_dec ("m4_define([[M4_HOOK_YYNXT_SIZE]], [[%d]])", tblend + 1); |
823 | 0 | outn ("m4_define([[M4_HOOK_YYNXT_BODY]], [[m4_dnl"); |
824 | |
|
825 | 0 | yynxt_tbl = calloc (1, sizeof (struct yytbl_data)); |
826 | 0 | yytbl_data_init (yynxt_tbl, YYTD_ID_NXT); |
827 | 0 | yynxt_tbl->td_lolen = (flex_uint32_t) (tblend + 1); |
828 | 0 | yynxt_tbl->td_data = yynxt_data = |
829 | 0 | calloc (yynxt_tbl->td_lolen, sizeof (flex_int32_t)); |
830 | |
|
831 | 0 | for (i = 1; i <= tblend; ++i) { |
832 | | /* Note, the order of the following test is important. |
833 | | * If chk[i] is 0, then nxt[i] is undefined. |
834 | | */ |
835 | 0 | if (chk[i] == 0 || nxt[i] == 0) |
836 | 0 | nxt[i] = jamstate; /* new state is the JAM state */ |
837 | |
|
838 | 0 | mkdata (nxt[i]); |
839 | 0 | yynxt_data[i] = nxt[i]; |
840 | 0 | } |
841 | |
|
842 | 0 | dataend (NULL); |
843 | 0 | outn("]])"); |
844 | 0 | footprint += ptype->width * (tblend + 1); |
845 | |
|
846 | 0 | if (tablesext) { |
847 | 0 | yytbl_data_compress (yynxt_tbl); |
848 | 0 | if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0) |
849 | 0 | flexerror (_("Could not write yynxt_tbl")); |
850 | 0 | } |
851 | 0 | yytbl_data_destroy (yynxt_tbl); |
852 | 0 | yynxt_tbl = NULL; |
853 | | /* End generating yy_nxt */ |
854 | | |
855 | | /* Begin generating yy_chk */ |
856 | 0 | ptype = optimize_pack(tblend + 1); |
857 | 0 | out_str ("m4_define([[M4_HOOK_CHK_TYPE]], [[%s]])", ptype->name); |
858 | 0 | out_dec ("m4_define([[M4_HOOK_CHK_SIZE]], [[%d]])", tblend + 1); |
859 | 0 | outn ("m4_define([[M4_HOOK_CHK_BODY]], [[m4_dnl"); |
860 | | |
861 | 0 | yychk_tbl = calloc (1, sizeof (struct yytbl_data)); |
862 | 0 | yytbl_data_init (yychk_tbl, YYTD_ID_CHK); |
863 | 0 | yychk_tbl->td_lolen = (flex_uint32_t) (tblend + 1); |
864 | 0 | yychk_tbl->td_data = yychk_data = |
865 | 0 | calloc(yychk_tbl->td_lolen, sizeof (flex_int32_t)); |
866 | |
|
867 | 0 | for (i = 1; i <= tblend; ++i) { |
868 | 0 | if (chk[i] == 0) |
869 | 0 | ++nummt; |
870 | |
|
871 | 0 | mkdata (chk[i]); |
872 | 0 | yychk_data[i] = chk[i]; |
873 | 0 | } |
874 | |
|
875 | 0 | dataend (NULL); |
876 | 0 | outn ("]])"); |
877 | 0 | footprint += ptype->width * (tblend + 1); |
878 | |
|
879 | 0 | if (tablesext) { |
880 | 0 | yytbl_data_compress (yychk_tbl); |
881 | 0 | if (yytbl_data_fwrite (&tableswr, yychk_tbl) < 0) |
882 | 0 | flexerror (_("Could not write yychk_tbl")); |
883 | 0 | } |
884 | 0 | yytbl_data_destroy (yychk_tbl); |
885 | 0 | yychk_tbl = NULL; |
886 | | /* End generating yy_chk */ |
887 | |
|
888 | 0 | free(acc_array); |
889 | 0 | } |
890 | | |
891 | | |
892 | | void visible_define (const char *symname) |
893 | 0 | { |
894 | 0 | out_m4_define(symname, NULL); |
895 | 0 | comment(symname); |
896 | 0 | outc ('\n'); |
897 | 0 | } |
898 | | |
899 | | void visible_define_str (const char *symname, const char *val) |
900 | 0 | { |
901 | 0 | char buf[128]; |
902 | 0 | out_m4_define(symname, val); |
903 | 0 | snprintf(buf, sizeof(buf), "%s = %s", symname, val); |
904 | 0 | comment(buf); |
905 | 0 | outc ('\n'); |
906 | 0 | } |
907 | | |
908 | | void visible_define_int (const char *symname, const int val) |
909 | 0 | { |
910 | 0 | char nbuf[24], buf[128]; |
911 | 0 | snprintf(nbuf, sizeof(nbuf), "%d", val); |
912 | 0 | out_m4_define(symname, nbuf); |
913 | 0 | snprintf(buf, sizeof(buf), "%s = %d", symname, val); |
914 | 0 | comment(buf); |
915 | 0 | outc ('\n'); |
916 | 0 | } |
917 | | |
918 | | /* make_tables - generate transition tables |
919 | | */ |
920 | | |
921 | | void make_tables (void) |
922 | 0 | { |
923 | 0 | char buf[128]; |
924 | 0 | int i; |
925 | 0 | struct yytbl_data *yynultrans_tbl = NULL; |
926 | | |
927 | | /* This is where we REALLY begin generating the tables. */ |
928 | |
|
929 | 0 | if (ctrl.fullspd) { |
930 | 0 | genctbl (); |
931 | 0 | if (tablesext) { |
932 | 0 | struct yytbl_data *tbl; |
933 | |
|
934 | 0 | tbl = mkctbl (); |
935 | 0 | yytbl_data_compress (tbl); |
936 | 0 | if (yytbl_data_fwrite (&tableswr, tbl) < 0) |
937 | 0 | flexerror (_("Could not write ftbl")); |
938 | 0 | yytbl_data_destroy (tbl); |
939 | |
|
940 | 0 | tbl = mkssltbl (); |
941 | 0 | yytbl_data_compress (tbl); |
942 | 0 | if (yytbl_data_fwrite (&tableswr, tbl) < 0) |
943 | 0 | flexerror (_("Could not write ssltbl")); |
944 | 0 | yytbl_data_destroy (tbl); |
945 | 0 | tbl = 0; |
946 | |
|
947 | 0 | if (ctrl.useecs) { |
948 | 0 | tbl = mkecstbl (); |
949 | 0 | yytbl_data_compress (tbl); |
950 | 0 | if (yytbl_data_fwrite (&tableswr, tbl) < 0) |
951 | 0 | flexerror (_ |
952 | 0 | ("Could not write ecstbl")); |
953 | 0 | yytbl_data_destroy (tbl); |
954 | 0 | tbl = 0; |
955 | 0 | } |
956 | 0 | } |
957 | 0 | } |
958 | 0 | else if (ctrl.fulltbl) { |
959 | 0 | genftbl (); |
960 | 0 | if (tablesext) { |
961 | 0 | struct yytbl_data *tbl; |
962 | | |
963 | | /* Alternately defined if !ctrl.ffullspd && !ctrl.fulltbl */ |
964 | 0 | struct packtype_t *ptype; |
965 | 0 | tbl = mkftbl (); |
966 | 0 | yytbl_data_compress (tbl); |
967 | 0 | ptype = optimize_pack(tbl->td_lolen); |
968 | 0 | out_str ("m4_define([[M4_HOOK_ACCEPT_TYPE]], [[%s]])", ptype->name); |
969 | 0 | if (yytbl_data_fwrite (&tableswr, tbl) < 0) |
970 | 0 | flexerror (_("Could not write ftbl")); |
971 | 0 | yytbl_data_destroy (tbl); |
972 | 0 | tbl = 0; |
973 | |
|
974 | 0 | if (ctrl.useecs) { |
975 | 0 | tbl = mkecstbl (); |
976 | 0 | yytbl_data_compress (tbl); |
977 | 0 | if (yytbl_data_fwrite (&tableswr, tbl) < 0) |
978 | 0 | flexerror (_ |
979 | 0 | ("Could not write ecstbl")); |
980 | 0 | yytbl_data_destroy (tbl); |
981 | 0 | tbl = 0; |
982 | 0 | } |
983 | 0 | } |
984 | 0 | } |
985 | 0 | else { |
986 | 0 | gentabs (); |
987 | 0 | } |
988 | |
|
989 | 0 | snprintf(buf, sizeof(buf), "footprint: %ld bytes\n", footprint); |
990 | 0 | comment(buf); |
991 | 0 | snprintf(buf, sizeof(buf), "tblend: %d\n", tblend); |
992 | 0 | comment(buf); |
993 | 0 | snprintf(buf, sizeof(buf), "numecs: %d\n", numecs); |
994 | 0 | comment(buf); |
995 | 0 | snprintf(buf, sizeof(buf), "num_rules: %d\n", num_rules); |
996 | 0 | comment(buf); |
997 | 0 | snprintf(buf, sizeof(buf), "lastdfa: %d\n", lastdfa); |
998 | 0 | comment(buf); |
999 | 0 | outc ('\n'); |
1000 | | |
1001 | | // Only at this point do we know if the automaton has backups. |
1002 | | // Some m4 conditionals require this information. |
1003 | |
|
1004 | 0 | comment("m4 controls begin\n"); |
1005 | |
|
1006 | 0 | if (num_backing_up > 0) |
1007 | 0 | visible_define ( "M4_MODE_HAS_BACKING_UP"); |
1008 | | |
1009 | | // These are used for NUL transitions |
1010 | 0 | if ((num_backing_up > 0 && !reject) && (!nultrans || ctrl.fullspd || ctrl.fulltbl)) |
1011 | 0 | visible_define ( "M4_MODE_NEED_YY_CP"); |
1012 | 0 | if ((num_backing_up > 0 && !reject) && (ctrl.fullspd || ctrl.fulltbl)) |
1013 | 0 | visible_define ( "M4_MODE_NULTRANS_WRAP"); |
1014 | |
|
1015 | 0 | comment("m4 controls end\n"); |
1016 | 0 | out ("\n"); |
1017 | |
|
1018 | 0 | if (ctrl.do_yylineno) { |
1019 | |
|
1020 | 0 | geneoltbl (); |
1021 | |
|
1022 | 0 | if (tablesext) { |
1023 | 0 | struct yytbl_data *tbl; |
1024 | |
|
1025 | 0 | tbl = mkeoltbl (); |
1026 | 0 | yytbl_data_compress (tbl); |
1027 | 0 | if (yytbl_data_fwrite (&tableswr, tbl) < 0) |
1028 | 0 | flexerror (_("Could not write eoltbl")); |
1029 | 0 | yytbl_data_destroy (tbl); |
1030 | 0 | tbl = 0; |
1031 | 0 | } |
1032 | 0 | } |
1033 | |
|
1034 | 0 | if (nultrans) { |
1035 | 0 | flex_int32_t *yynultrans_data = 0; |
1036 | | |
1037 | | /* Begin generating yy_NUL_trans */ |
1038 | 0 | out_str ("m4_define([[M4_HOOK_NULTRANS_TYPE]], [[%s]])", (ctrl.fullspd) ? "struct yy_trans_info*" : "M4_HOOK_INT32"); |
1039 | 0 | out_dec ("m4_define([[M4_HOOK_NULTRANS_SIZE]], [[%d]])", lastdfa + 1); |
1040 | 0 | outn ("m4_define([[M4_HOOK_NULTRANS_BODY]], [[m4_dnl"); |
1041 | |
|
1042 | 0 | yynultrans_tbl = calloc(1, sizeof (struct yytbl_data)); |
1043 | 0 | yytbl_data_init (yynultrans_tbl, YYTD_ID_NUL_TRANS); |
1044 | | // Performance kludge for C. Gives a small improvement |
1045 | | // in table loading time. |
1046 | 0 | if (ctrl.fullspd && ctrl.have_state_entry_format) |
1047 | 0 | yynultrans_tbl->td_flags |= YYTD_PTRANS; |
1048 | 0 | yynultrans_tbl->td_lolen = (flex_uint32_t) (lastdfa + 1); |
1049 | 0 | yynultrans_tbl->td_data = yynultrans_data = |
1050 | 0 | calloc(yynultrans_tbl->td_lolen, |
1051 | 0 | sizeof (flex_int32_t)); |
1052 | |
|
1053 | 0 | for (i = 1; i <= lastdfa; ++i) { |
1054 | 0 | if ((yynultrans_tbl->td_flags & YYTD_PTRANS) != 0) { |
1055 | | // Only works in very C-like languages |
1056 | 0 | out_dec (" &yy_transition[%d],\n", |
1057 | 0 | base[i]); |
1058 | 0 | yynultrans_data[i] = base[i]; |
1059 | 0 | } |
1060 | 0 | else { |
1061 | | // This will work anywhere |
1062 | 0 | mkdata (nultrans[i]); |
1063 | 0 | yynultrans_data[i] = nultrans[i]; |
1064 | 0 | } |
1065 | 0 | } |
1066 | |
|
1067 | 0 | dataend (NULL); |
1068 | 0 | outn("]])"); |
1069 | 0 | footprint += (lastdfa + 1) * (ctrl.fullspd ? sizeof(struct yy_trans_info *) : sizeof(int32_t)); |
1070 | 0 | if (tablesext) { |
1071 | 0 | yytbl_data_compress (yynultrans_tbl); |
1072 | 0 | if (yytbl_data_fwrite (&tableswr, yynultrans_tbl) < |
1073 | 0 | 0) |
1074 | 0 | flexerror (_ |
1075 | 0 | ("Could not write yynultrans_tbl")); |
1076 | 0 | } |
1077 | |
|
1078 | 0 | if (yynultrans_tbl != NULL) { |
1079 | 0 | yytbl_data_destroy (yynultrans_tbl); |
1080 | 0 | yynultrans_tbl = NULL; |
1081 | 0 | } |
1082 | | |
1083 | | /* End generating yy_NUL_trans */ |
1084 | 0 | } |
1085 | |
|
1086 | 0 | if (ctrl.ddebug) { /* Spit out table mapping rules to line numbers. */ |
1087 | | /* Policy choice: we don't include this space |
1088 | | * in the table metering. |
1089 | | */ |
1090 | 0 | struct packtype_t *ptype = optimize_pack(num_rules); |
1091 | 0 | out_str ("m4_define([[M4_HOOK_DEBUGTABLE_TYPE]], [[%s]])", ptype->name); |
1092 | 0 | out_dec ("m4_define([[M4_HOOK_DEBUGTABLE_SIZE]], [[%d]])", num_rules); |
1093 | 0 | outn ("m4_define([[M4_HOOK_DEBUGTABLE_BODY]], [[m4_dnl"); |
1094 | |
|
1095 | 0 | for (i = 1; i < num_rules; ++i) |
1096 | 0 | mkdata (rule_linenum[i]); |
1097 | | dataend (NULL); |
1098 | 0 | outn("]])"); |
1099 | 0 | } |
1100 | 0 | } |