1228072Sbapt/* gen - actual generation (writing) of flex scanners */
2228072Sbapt
3228072Sbapt/*  Copyright (c) 1990 The Regents of the University of California. */
4228072Sbapt/*  All rights reserved. */
5228072Sbapt
6228072Sbapt/*  This code is derived from software contributed to Berkeley by */
7228072Sbapt/*  Vern Paxson. */
8228072Sbapt
9228072Sbapt/*  The United States Government has rights in this work pursuant */
10228072Sbapt/*  to contract no. DE-AC03-76SF00098 between the United States */
11228072Sbapt/*  Department of Energy and the University of California. */
12228072Sbapt
13228072Sbapt/*  This file is part of flex. */
14228072Sbapt
15228072Sbapt/*  Redistribution and use in source and binary forms, with or without */
16228072Sbapt/*  modification, are permitted provided that the following conditions */
17228072Sbapt/*  are met: */
18228072Sbapt
19228072Sbapt/*  1. Redistributions of source code must retain the above copyright */
20228072Sbapt/*     notice, this list of conditions and the following disclaimer. */
21228072Sbapt/*  2. Redistributions in binary form must reproduce the above copyright */
22228072Sbapt/*     notice, this list of conditions and the following disclaimer in the */
23228072Sbapt/*     documentation and/or other materials provided with the distribution. */
24228072Sbapt
25228072Sbapt/*  Neither the name of the University nor the names of its contributors */
26228072Sbapt/*  may be used to endorse or promote products derived from this software */
27228072Sbapt/*  without specific prior written permission. */
28228072Sbapt
29228072Sbapt/*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
30228072Sbapt/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
31228072Sbapt/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
32228072Sbapt/*  PURPOSE. */
33228072Sbapt
34228072Sbapt#include "flexdef.h"
35228072Sbapt#include "tables.h"
36228072Sbapt
37228072Sbapt
38228072Sbapt/* declare functions that have forward references */
39228072Sbapt
40228072Sbaptvoid gen_next_state PROTO ((int));
41228072Sbaptvoid genecs PROTO ((void));
42228072Sbaptvoid indent_put2s PROTO ((const char *, const char *));
43228072Sbaptvoid indent_puts PROTO ((const char *));
44228072Sbapt
45228072Sbapt
46228072Sbaptstatic int indent_level = 0;	/* each level is 8 spaces */
47228072Sbapt
48228072Sbapt#define indent_up() (++indent_level)
49228072Sbapt#define indent_down() (--indent_level)
50228072Sbapt#define set_indent(indent_val) indent_level = indent_val
51228072Sbapt
52228072Sbapt/* Almost everything is done in terms of arrays starting at 1, so provide
53228072Sbapt * a null entry for the zero element of all C arrays.  (The exception
54228072Sbapt * to this is that the fast table representation generally uses the
55228072Sbapt * 0 elements of its arrays, too.)
56228072Sbapt */
57228072Sbapt
58228072Sbaptstatic const char *get_int16_decl (void)
59228072Sbapt{
60228072Sbapt	return (gentables)
61228072Sbapt		? "static yyconst flex_int16_t %s[%d] =\n    {   0,\n"
62228072Sbapt		: "static yyconst flex_int16_t * %s = 0;\n";
63228072Sbapt}
64228072Sbapt
65228072Sbapt
66228072Sbaptstatic const char *get_int32_decl (void)
67228072Sbapt{
68228072Sbapt	return (gentables)
69228072Sbapt		? "static yyconst flex_int32_t %s[%d] =\n    {   0,\n"
70228072Sbapt		: "static yyconst flex_int32_t * %s = 0;\n";
71228072Sbapt}
72228072Sbapt
73228072Sbaptstatic const char *get_state_decl (void)
74228072Sbapt{
75228072Sbapt	return (gentables)
76228072Sbapt		? "static yyconst yy_state_type %s[%d] =\n    {   0,\n"
77228072Sbapt		: "static yyconst yy_state_type * %s = 0;\n";
78228072Sbapt}
79228072Sbapt
80228072Sbapt/* Indent to the current level. */
81228072Sbapt
82228072Sbaptvoid do_indent ()
83228072Sbapt{
84250874Sjkim	int i = indent_level * 8;
85228072Sbapt
86228072Sbapt	while (i >= 8) {
87228072Sbapt		outc ('\t');
88228072Sbapt		i -= 8;
89228072Sbapt	}
90228072Sbapt
91228072Sbapt	while (i > 0) {
92228072Sbapt		outc (' ');
93228072Sbapt		--i;
94228072Sbapt	}
95228072Sbapt}
96228072Sbapt
97228072Sbapt
98228072Sbapt/** Make the table for possible eol matches.
99228072Sbapt *  @return the newly allocated rule_can_match_eol table
100228072Sbapt */
101228072Sbaptstatic struct yytbl_data *mkeoltbl (void)
102228072Sbapt{
103228072Sbapt	int     i;
104228072Sbapt	flex_int8_t *tdata = 0;
105228072Sbapt	struct yytbl_data *tbl;
106228072Sbapt
107228072Sbapt	tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
108228072Sbapt	yytbl_data_init (tbl, YYTD_ID_RULE_CAN_MATCH_EOL);
109228072Sbapt	tbl->td_flags = YYTD_DATA8;
110228072Sbapt	tbl->td_lolen = num_rules + 1;
111228072Sbapt	tbl->td_data = tdata =
112228072Sbapt		(flex_int8_t *) calloc (tbl->td_lolen, sizeof (flex_int8_t));
113228072Sbapt
114228072Sbapt	for (i = 1; i <= num_rules; i++)
115228072Sbapt		tdata[i] = rule_has_nl[i] ? 1 : 0;
116228072Sbapt
117228072Sbapt	buf_prints (&yydmap_buf,
118228072Sbapt		    "\t{YYTD_ID_RULE_CAN_MATCH_EOL, (void**)&yy_rule_can_match_eol, sizeof(%s)},\n",
119228072Sbapt		    "flex_int32_t");
120228072Sbapt	return tbl;
121228072Sbapt}
122228072Sbapt
123228072Sbapt/* Generate the table for possible eol matches. */
124250875Sjkimstatic void geneoltbl (void)
125228072Sbapt{
126228072Sbapt	int     i;
127228072Sbapt
128228072Sbapt	outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[[");
129228072Sbapt	outn ("/* Table of booleans, true if rule could match eol. */");
130228072Sbapt	out_str_dec (get_int32_decl (), "yy_rule_can_match_eol",
131228072Sbapt		     num_rules + 1);
132228072Sbapt
133228072Sbapt	if (gentables) {
134228072Sbapt		for (i = 1; i <= num_rules; i++) {
135228072Sbapt			out_dec ("%d, ", rule_has_nl[i] ? 1 : 0);
136228072Sbapt			/* format nicely, 20 numbers per line. */
137228072Sbapt			if ((i % 20) == 19)
138228072Sbapt				out ("\n    ");
139228072Sbapt		}
140228072Sbapt		out ("    };\n");
141228072Sbapt	}
142228072Sbapt	outn ("]])");
143228072Sbapt}
144228072Sbapt
145228072Sbapt
146228072Sbapt/* Generate the code to keep backing-up information. */
147228072Sbapt
148228072Sbaptvoid gen_backing_up ()
149228072Sbapt{
150228072Sbapt	if (reject || num_backing_up == 0)
151228072Sbapt		return;
152228072Sbapt
153228072Sbapt	if (fullspd)
154228072Sbapt		indent_puts ("if ( yy_current_state[-1].yy_nxt )");
155228072Sbapt	else
156228072Sbapt		indent_puts ("if ( yy_accept[yy_current_state] )");
157228072Sbapt
158228072Sbapt	indent_up ();
159228072Sbapt	indent_puts ("{");
160228072Sbapt	indent_puts ("YY_G(yy_last_accepting_state) = yy_current_state;");
161228072Sbapt	indent_puts ("YY_G(yy_last_accepting_cpos) = yy_cp;");
162228072Sbapt	indent_puts ("}");
163228072Sbapt	indent_down ();
164228072Sbapt}
165228072Sbapt
166228072Sbapt
167228072Sbapt/* Generate the code to perform the backing up. */
168228072Sbapt
169228072Sbaptvoid gen_bu_action ()
170228072Sbapt{
171228072Sbapt	if (reject || num_backing_up == 0)
172228072Sbapt		return;
173228072Sbapt
174228072Sbapt	set_indent (3);
175228072Sbapt
176228072Sbapt	indent_puts ("case 0: /* must back up */");
177228072Sbapt	indent_puts ("/* undo the effects of YY_DO_BEFORE_ACTION */");
178228072Sbapt	indent_puts ("*yy_cp = YY_G(yy_hold_char);");
179228072Sbapt
180228072Sbapt	if (fullspd || fulltbl)
181228072Sbapt		indent_puts ("yy_cp = YY_G(yy_last_accepting_cpos) + 1;");
182228072Sbapt	else
183228072Sbapt		/* Backing-up info for compressed tables is taken \after/
184228072Sbapt		 * yy_cp has been incremented for the next state.
185228072Sbapt		 */
186228072Sbapt		indent_puts ("yy_cp = YY_G(yy_last_accepting_cpos);");
187228072Sbapt
188228072Sbapt	indent_puts ("yy_current_state = YY_G(yy_last_accepting_state);");
189228072Sbapt	indent_puts ("goto yy_find_action;");
190228072Sbapt	outc ('\n');
191228072Sbapt
192228072Sbapt	set_indent (0);
193228072Sbapt}
194228072Sbapt
195228072Sbapt/** mkctbl - make full speed compressed transition table
196228072Sbapt * This is an array of structs; each struct a pair of integers.
197228072Sbapt * You should call mkssltbl() immediately after this.
198228072Sbapt * Then, I think, mkecstbl(). Arrrg.
199228072Sbapt * @return the newly allocated trans table
200228072Sbapt */
201228072Sbapt
202228072Sbaptstatic struct yytbl_data *mkctbl (void)
203228072Sbapt{
204250874Sjkim	int i;
205228072Sbapt	struct yytbl_data *tbl = 0;
206228072Sbapt	flex_int32_t *tdata = 0, curr = 0;
207228072Sbapt	int     end_of_buffer_action = num_rules + 1;
208228072Sbapt
209228072Sbapt	buf_prints (&yydmap_buf,
210228072Sbapt		    "\t{YYTD_ID_TRANSITION, (void**)&yy_transition, sizeof(%s)},\n",
211228072Sbapt		    ((tblend + numecs + 1) >= INT16_MAX
212228072Sbapt		     || long_align) ? "flex_int32_t" : "flex_int16_t");
213228072Sbapt
214228072Sbapt	tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
215228072Sbapt	yytbl_data_init (tbl, YYTD_ID_TRANSITION);
216228072Sbapt	tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT;
217228072Sbapt	tbl->td_hilen = 0;
218228072Sbapt	tbl->td_lolen = tblend + numecs + 1;	/* number of structs */
219228072Sbapt
220228072Sbapt	tbl->td_data = tdata =
221228072Sbapt		(flex_int32_t *) calloc (tbl->td_lolen * 2, sizeof (flex_int32_t));
222228072Sbapt
223228072Sbapt	/* We want the transition to be represented as the offset to the
224228072Sbapt	 * next state, not the actual state number, which is what it currently
225228072Sbapt	 * is.  The offset is base[nxt[i]] - (base of current state)].  That's
226228072Sbapt	 * just the difference between the starting points of the two involved
227228072Sbapt	 * states (to - from).
228228072Sbapt	 *
229228072Sbapt	 * First, though, we need to find some way to put in our end-of-buffer
230228072Sbapt	 * flags and states.  We do this by making a state with absolutely no
231228072Sbapt	 * transitions.  We put it at the end of the table.
232228072Sbapt	 */
233228072Sbapt
234228072Sbapt	/* We need to have room in nxt/chk for two more slots: One for the
235228072Sbapt	 * action and one for the end-of-buffer transition.  We now *assume*
236228072Sbapt	 * that we're guaranteed the only character we'll try to index this
237228072Sbapt	 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
238228072Sbapt	 * there's room for jam entries for other characters.
239228072Sbapt	 */
240228072Sbapt
241228072Sbapt	while (tblend + 2 >= current_max_xpairs)
242228072Sbapt		expand_nxt_chk ();
243228072Sbapt
244228072Sbapt	while (lastdfa + 1 >= current_max_dfas)
245228072Sbapt		increase_max_dfas ();
246228072Sbapt
247228072Sbapt	base[lastdfa + 1] = tblend + 2;
248228072Sbapt	nxt[tblend + 1] = end_of_buffer_action;
249228072Sbapt	chk[tblend + 1] = numecs + 1;
250228072Sbapt	chk[tblend + 2] = 1;	/* anything but EOB */
251228072Sbapt
252228072Sbapt	/* So that "make test" won't show arb. differences. */
253228072Sbapt	nxt[tblend + 2] = 0;
254228072Sbapt
255228072Sbapt	/* Make sure every state has an end-of-buffer transition and an
256228072Sbapt	 * action #.
257228072Sbapt	 */
258228072Sbapt	for (i = 0; i <= lastdfa; ++i) {
259228072Sbapt		int     anum = dfaacc[i].dfaacc_state;
260228072Sbapt		int     offset = base[i];
261228072Sbapt
262228072Sbapt		chk[offset] = EOB_POSITION;
263228072Sbapt		chk[offset - 1] = ACTION_POSITION;
264228072Sbapt		nxt[offset - 1] = anum;	/* action number */
265228072Sbapt	}
266228072Sbapt
267228072Sbapt	for (i = 0; i <= tblend; ++i) {
268228072Sbapt		if (chk[i] == EOB_POSITION) {
269228072Sbapt			tdata[curr++] = 0;
270228072Sbapt			tdata[curr++] = base[lastdfa + 1] - i;
271228072Sbapt		}
272228072Sbapt
273228072Sbapt		else if (chk[i] == ACTION_POSITION) {
274228072Sbapt			tdata[curr++] = 0;
275228072Sbapt			tdata[curr++] = nxt[i];
276228072Sbapt		}
277228072Sbapt
278228072Sbapt		else if (chk[i] > numecs || chk[i] == 0) {
279228072Sbapt			tdata[curr++] = 0;
280228072Sbapt			tdata[curr++] = 0;
281228072Sbapt		}
282228072Sbapt		else {		/* verify, transition */
283228072Sbapt
284228072Sbapt			tdata[curr++] = chk[i];
285228072Sbapt			tdata[curr++] = base[nxt[i]] - (i - chk[i]);
286228072Sbapt		}
287228072Sbapt	}
288228072Sbapt
289228072Sbapt
290228072Sbapt	/* Here's the final, end-of-buffer state. */
291228072Sbapt	tdata[curr++] = chk[tblend + 1];
292228072Sbapt	tdata[curr++] = nxt[tblend + 1];
293228072Sbapt
294228072Sbapt	tdata[curr++] = chk[tblend + 2];
295228072Sbapt	tdata[curr++] = nxt[tblend + 2];
296228072Sbapt
297228072Sbapt	return tbl;
298228072Sbapt}
299228072Sbapt
300228072Sbapt
301228072Sbapt/** Make start_state_list table.
302228072Sbapt *  @return the newly allocated start_state_list table
303228072Sbapt */
304228072Sbaptstatic struct yytbl_data *mkssltbl (void)
305228072Sbapt{
306228072Sbapt	struct yytbl_data *tbl = 0;
307228072Sbapt	flex_int32_t *tdata = 0;
308228072Sbapt	flex_int32_t i;
309228072Sbapt
310228072Sbapt	tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
311228072Sbapt	yytbl_data_init (tbl, YYTD_ID_START_STATE_LIST);
312228072Sbapt	tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS;
313228072Sbapt	tbl->td_hilen = 0;
314228072Sbapt	tbl->td_lolen = lastsc * 2 + 1;
315228072Sbapt
316228072Sbapt	tbl->td_data = tdata =
317228072Sbapt		(flex_int32_t *) calloc (tbl->td_lolen, sizeof (flex_int32_t));
318228072Sbapt
319228072Sbapt	for (i = 0; i <= lastsc * 2; ++i)
320228072Sbapt		tdata[i] = base[i];
321228072Sbapt
322228072Sbapt	buf_prints (&yydmap_buf,
323228072Sbapt		    "\t{YYTD_ID_START_STATE_LIST, (void**)&yy_start_state_list, sizeof(%s)},\n",
324228072Sbapt		    "struct yy_trans_info*");
325228072Sbapt
326228072Sbapt	return tbl;
327228072Sbapt}
328228072Sbapt
329228072Sbapt
330228072Sbapt
331228072Sbapt/* genctbl - generates full speed compressed transition table */
332228072Sbapt
333228072Sbaptvoid genctbl ()
334228072Sbapt{
335250874Sjkim	int i;
336228072Sbapt	int     end_of_buffer_action = num_rules + 1;
337228072Sbapt
338228072Sbapt	/* Table of verify for transition and offset to next state. */
339228072Sbapt	if (gentables)
340228072Sbapt		out_dec ("static yyconst struct yy_trans_info yy_transition[%d] =\n    {\n", tblend + numecs + 1);
341228072Sbapt	else
342228072Sbapt		outn ("static yyconst struct yy_trans_info *yy_transition = 0;");
343228072Sbapt
344228072Sbapt	/* We want the transition to be represented as the offset to the
345228072Sbapt	 * next state, not the actual state number, which is what it currently
346228072Sbapt	 * is.  The offset is base[nxt[i]] - (base of current state)].  That's
347228072Sbapt	 * just the difference between the starting points of the two involved
348228072Sbapt	 * states (to - from).
349228072Sbapt	 *
350228072Sbapt	 * First, though, we need to find some way to put in our end-of-buffer
351228072Sbapt	 * flags and states.  We do this by making a state with absolutely no
352228072Sbapt	 * transitions.  We put it at the end of the table.
353228072Sbapt	 */
354228072Sbapt
355228072Sbapt	/* We need to have room in nxt/chk for two more slots: One for the
356228072Sbapt	 * action and one for the end-of-buffer transition.  We now *assume*
357228072Sbapt	 * that we're guaranteed the only character we'll try to index this
358228072Sbapt	 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
359228072Sbapt	 * there's room for jam entries for other characters.
360228072Sbapt	 */
361228072Sbapt
362228072Sbapt	while (tblend + 2 >= current_max_xpairs)
363228072Sbapt		expand_nxt_chk ();
364228072Sbapt
365228072Sbapt	while (lastdfa + 1 >= current_max_dfas)
366228072Sbapt		increase_max_dfas ();
367228072Sbapt
368228072Sbapt	base[lastdfa + 1] = tblend + 2;
369228072Sbapt	nxt[tblend + 1] = end_of_buffer_action;
370228072Sbapt	chk[tblend + 1] = numecs + 1;
371228072Sbapt	chk[tblend + 2] = 1;	/* anything but EOB */
372228072Sbapt
373228072Sbapt	/* So that "make test" won't show arb. differences. */
374228072Sbapt	nxt[tblend + 2] = 0;
375228072Sbapt
376228072Sbapt	/* Make sure every state has an end-of-buffer transition and an
377228072Sbapt	 * action #.
378228072Sbapt	 */
379228072Sbapt	for (i = 0; i <= lastdfa; ++i) {
380228072Sbapt		int     anum = dfaacc[i].dfaacc_state;
381228072Sbapt		int     offset = base[i];
382228072Sbapt
383228072Sbapt		chk[offset] = EOB_POSITION;
384228072Sbapt		chk[offset - 1] = ACTION_POSITION;
385228072Sbapt		nxt[offset - 1] = anum;	/* action number */
386228072Sbapt	}
387228072Sbapt
388228072Sbapt	for (i = 0; i <= tblend; ++i) {
389228072Sbapt		if (chk[i] == EOB_POSITION)
390228072Sbapt			transition_struct_out (0, base[lastdfa + 1] - i);
391228072Sbapt
392228072Sbapt		else if (chk[i] == ACTION_POSITION)
393228072Sbapt			transition_struct_out (0, nxt[i]);
394228072Sbapt
395228072Sbapt		else if (chk[i] > numecs || chk[i] == 0)
396228072Sbapt			transition_struct_out (0, 0);	/* unused slot */
397228072Sbapt
398228072Sbapt		else		/* verify, transition */
399228072Sbapt			transition_struct_out (chk[i],
400228072Sbapt					       base[nxt[i]] - (i -
401228072Sbapt							       chk[i]));
402228072Sbapt	}
403228072Sbapt
404228072Sbapt
405228072Sbapt	/* Here's the final, end-of-buffer state. */
406228072Sbapt	transition_struct_out (chk[tblend + 1], nxt[tblend + 1]);
407228072Sbapt	transition_struct_out (chk[tblend + 2], nxt[tblend + 2]);
408228072Sbapt
409228072Sbapt	if (gentables)
410228072Sbapt		outn ("    };\n");
411228072Sbapt
412228072Sbapt	/* Table of pointers to start states. */
413228072Sbapt	if (gentables)
414228072Sbapt		out_dec ("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1);
415228072Sbapt	else
416228072Sbapt		outn ("static yyconst struct yy_trans_info **yy_start_state_list =0;");
417228072Sbapt
418228072Sbapt	if (gentables) {
419228072Sbapt		outn ("    {");
420228072Sbapt
421228072Sbapt		for (i = 0; i <= lastsc * 2; ++i)
422228072Sbapt			out_dec ("    &yy_transition[%d],\n", base[i]);
423228072Sbapt
424228072Sbapt		dataend ();
425228072Sbapt	}
426228072Sbapt
427228072Sbapt	if (useecs)
428228072Sbapt		genecs ();
429228072Sbapt}
430228072Sbapt
431228072Sbapt
432228072Sbapt/* mkecstbl - Make equivalence-class tables.  */
433228072Sbapt
434250875Sjkimstatic struct yytbl_data *mkecstbl (void)
435228072Sbapt{
436250874Sjkim	int i;
437228072Sbapt	struct yytbl_data *tbl = 0;
438228072Sbapt	flex_int32_t *tdata = 0;
439228072Sbapt
440228072Sbapt	tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
441228072Sbapt	yytbl_data_init (tbl, YYTD_ID_EC);
442228072Sbapt	tbl->td_flags |= YYTD_DATA32;
443228072Sbapt	tbl->td_hilen = 0;
444228072Sbapt	tbl->td_lolen = csize;
445228072Sbapt
446228072Sbapt	tbl->td_data = tdata =
447228072Sbapt		(flex_int32_t *) calloc (tbl->td_lolen, sizeof (flex_int32_t));
448228072Sbapt
449228072Sbapt	for (i = 1; i < csize; ++i) {
450228072Sbapt		ecgroup[i] = ABS (ecgroup[i]);
451228072Sbapt		tdata[i] = ecgroup[i];
452228072Sbapt	}
453228072Sbapt
454228072Sbapt	buf_prints (&yydmap_buf,
455228072Sbapt		    "\t{YYTD_ID_EC, (void**)&yy_ec, sizeof(%s)},\n",
456228072Sbapt		    "flex_int32_t");
457228072Sbapt
458228072Sbapt	return tbl;
459228072Sbapt}
460228072Sbapt
461228072Sbapt/* Generate equivalence-class tables. */
462228072Sbapt
463228072Sbaptvoid genecs ()
464228072Sbapt{
465250874Sjkim	int i, j;
466228072Sbapt	int     numrows;
467228072Sbapt
468228072Sbapt	out_str_dec (get_int32_decl (), "yy_ec", csize);
469228072Sbapt
470228072Sbapt	for (i = 1; i < csize; ++i) {
471228072Sbapt		ecgroup[i] = ABS (ecgroup[i]);
472228072Sbapt		mkdata (ecgroup[i]);
473228072Sbapt	}
474228072Sbapt
475228072Sbapt	dataend ();
476228072Sbapt
477228072Sbapt	if (trace) {
478228072Sbapt		fputs (_("\n\nEquivalence Classes:\n\n"), stderr);
479228072Sbapt
480228072Sbapt		numrows = csize / 8;
481228072Sbapt
482228072Sbapt		for (j = 0; j < numrows; ++j) {
483228072Sbapt			for (i = j; i < csize; i = i + numrows) {
484228072Sbapt				fprintf (stderr, "%4s = %-2d",
485228072Sbapt					 readable_form (i), ecgroup[i]);
486228072Sbapt
487228072Sbapt				putc (' ', stderr);
488228072Sbapt			}
489228072Sbapt
490228072Sbapt			putc ('\n', stderr);
491228072Sbapt		}
492228072Sbapt	}
493228072Sbapt}
494228072Sbapt
495228072Sbapt
496228072Sbapt/* Generate the code to find the action number. */
497228072Sbapt
498228072Sbaptvoid gen_find_action ()
499228072Sbapt{
500228072Sbapt	if (fullspd)
501228072Sbapt		indent_puts ("yy_act = yy_current_state[-1].yy_nxt;");
502228072Sbapt
503228072Sbapt	else if (fulltbl)
504228072Sbapt		indent_puts ("yy_act = yy_accept[yy_current_state];");
505228072Sbapt
506228072Sbapt	else if (reject) {
507228072Sbapt		indent_puts ("yy_current_state = *--YY_G(yy_state_ptr);");
508228072Sbapt		indent_puts ("YY_G(yy_lp) = yy_accept[yy_current_state];");
509228072Sbapt
510250874Sjkim		outn ("goto find_rule; /* avoid `defined but not used' warning */");
511228072Sbapt		outn ("find_rule: /* we branch to this label when backing up */");
512228072Sbapt
513228072Sbapt		indent_puts
514228072Sbapt			("for ( ; ; ) /* until we find what rule we matched */");
515228072Sbapt
516228072Sbapt		indent_up ();
517228072Sbapt
518228072Sbapt		indent_puts ("{");
519228072Sbapt
520228072Sbapt		indent_puts
521228072Sbapt			("if ( YY_G(yy_lp) && YY_G(yy_lp) < yy_accept[yy_current_state + 1] )");
522228072Sbapt		indent_up ();
523228072Sbapt		indent_puts ("{");
524228072Sbapt		indent_puts ("yy_act = yy_acclist[YY_G(yy_lp)];");
525228072Sbapt
526228072Sbapt		if (variable_trailing_context_rules) {
527228072Sbapt			indent_puts
528228072Sbapt				("if ( yy_act & YY_TRAILING_HEAD_MASK ||");
529228072Sbapt			indent_puts ("     YY_G(yy_looking_for_trail_begin) )");
530228072Sbapt			indent_up ();
531228072Sbapt			indent_puts ("{");
532228072Sbapt
533228072Sbapt			indent_puts
534228072Sbapt				("if ( yy_act == YY_G(yy_looking_for_trail_begin) )");
535228072Sbapt			indent_up ();
536228072Sbapt			indent_puts ("{");
537228072Sbapt			indent_puts ("YY_G(yy_looking_for_trail_begin) = 0;");
538228072Sbapt			indent_puts ("yy_act &= ~YY_TRAILING_HEAD_MASK;");
539228072Sbapt			indent_puts ("break;");
540228072Sbapt			indent_puts ("}");
541228072Sbapt			indent_down ();
542228072Sbapt
543228072Sbapt			indent_puts ("}");
544228072Sbapt			indent_down ();
545228072Sbapt
546228072Sbapt			indent_puts
547228072Sbapt				("else if ( yy_act & YY_TRAILING_MASK )");
548228072Sbapt			indent_up ();
549228072Sbapt			indent_puts ("{");
550228072Sbapt			indent_puts
551228072Sbapt				("YY_G(yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK;");
552228072Sbapt			indent_puts
553228072Sbapt				("YY_G(yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK;");
554228072Sbapt
555228072Sbapt			if (real_reject) {
556228072Sbapt				/* Remember matched text in case we back up
557228072Sbapt				 * due to REJECT.
558228072Sbapt				 */
559228072Sbapt				indent_puts
560228072Sbapt					("YY_G(yy_full_match) = yy_cp;");
561228072Sbapt				indent_puts
562228072Sbapt					("YY_G(yy_full_state) = YY_G(yy_state_ptr);");
563228072Sbapt				indent_puts ("YY_G(yy_full_lp) = YY_G(yy_lp);");
564228072Sbapt			}
565228072Sbapt
566228072Sbapt			indent_puts ("}");
567228072Sbapt			indent_down ();
568228072Sbapt
569228072Sbapt			indent_puts ("else");
570228072Sbapt			indent_up ();
571228072Sbapt			indent_puts ("{");
572228072Sbapt			indent_puts ("YY_G(yy_full_match) = yy_cp;");
573228072Sbapt			indent_puts
574228072Sbapt				("YY_G(yy_full_state) = YY_G(yy_state_ptr);");
575228072Sbapt			indent_puts ("YY_G(yy_full_lp) = YY_G(yy_lp);");
576228072Sbapt			indent_puts ("break;");
577228072Sbapt			indent_puts ("}");
578228072Sbapt			indent_down ();
579228072Sbapt
580228072Sbapt			indent_puts ("++YY_G(yy_lp);");
581228072Sbapt			indent_puts ("goto find_rule;");
582228072Sbapt		}
583228072Sbapt
584228072Sbapt		else {
585228072Sbapt			/* Remember matched text in case we back up due to
586228072Sbapt			 * trailing context plus REJECT.
587228072Sbapt			 */
588228072Sbapt			indent_up ();
589228072Sbapt			indent_puts ("{");
590228072Sbapt			indent_puts ("YY_G(yy_full_match) = yy_cp;");
591228072Sbapt			indent_puts ("break;");
592228072Sbapt			indent_puts ("}");
593228072Sbapt			indent_down ();
594228072Sbapt		}
595228072Sbapt
596228072Sbapt		indent_puts ("}");
597228072Sbapt		indent_down ();
598228072Sbapt
599228072Sbapt		indent_puts ("--yy_cp;");
600228072Sbapt
601228072Sbapt		/* We could consolidate the following two lines with those at
602228072Sbapt		 * the beginning, but at the cost of complaints that we're
603228072Sbapt		 * branching inside a loop.
604228072Sbapt		 */
605228072Sbapt		indent_puts ("yy_current_state = *--YY_G(yy_state_ptr);");
606228072Sbapt		indent_puts ("YY_G(yy_lp) = yy_accept[yy_current_state];");
607228072Sbapt
608228072Sbapt		indent_puts ("}");
609228072Sbapt
610228072Sbapt		indent_down ();
611228072Sbapt	}
612228072Sbapt
613228072Sbapt	else {			/* compressed */
614228072Sbapt		indent_puts ("yy_act = yy_accept[yy_current_state];");
615228072Sbapt
616228072Sbapt		if (interactive && !reject) {
617228072Sbapt			/* Do the guaranteed-needed backing up to figure out
618228072Sbapt			 * the match.
619228072Sbapt			 */
620228072Sbapt			indent_puts ("if ( yy_act == 0 )");
621228072Sbapt			indent_up ();
622228072Sbapt			indent_puts ("{ /* have to back up */");
623228072Sbapt			indent_puts
624228072Sbapt				("yy_cp = YY_G(yy_last_accepting_cpos);");
625228072Sbapt			indent_puts
626228072Sbapt				("yy_current_state = YY_G(yy_last_accepting_state);");
627228072Sbapt			indent_puts
628228072Sbapt				("yy_act = yy_accept[yy_current_state];");
629228072Sbapt			indent_puts ("}");
630228072Sbapt			indent_down ();
631228072Sbapt		}
632228072Sbapt	}
633228072Sbapt}
634228072Sbapt
635228072Sbapt/* mkftbl - make the full table and return the struct .
636228072Sbapt * you should call mkecstbl() after this.
637228072Sbapt */
638228072Sbapt
639228072Sbaptstruct yytbl_data *mkftbl (void)
640228072Sbapt{
641250874Sjkim	int i;
642228072Sbapt	int     end_of_buffer_action = num_rules + 1;
643228072Sbapt	struct yytbl_data *tbl;
644228072Sbapt	flex_int32_t *tdata = 0;
645228072Sbapt
646228072Sbapt	tbl = (struct yytbl_data *) calloc (1, sizeof (struct yytbl_data));
647228072Sbapt	yytbl_data_init (tbl, YYTD_ID_ACCEPT);
648228072Sbapt	tbl->td_flags |= YYTD_DATA32;
649228072Sbapt	tbl->td_hilen = 0;	/* it's a one-dimensional array */
650228072Sbapt	tbl->td_lolen = lastdfa + 1;
651228072Sbapt
652228072Sbapt	tbl->td_data = tdata =
653228072Sbapt		(flex_int32_t *) calloc (tbl->td_lolen, sizeof (flex_int32_t));
654228072Sbapt
655228072Sbapt	dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
656228072Sbapt
657228072Sbapt	for (i = 1; i <= lastdfa; ++i) {
658250874Sjkim		int anum = dfaacc[i].dfaacc_state;
659228072Sbapt
660228072Sbapt		tdata[i] = anum;
661228072Sbapt
662228072Sbapt		if (trace && anum)
663228072Sbapt			fprintf (stderr, _("state # %d accepts: [%d]\n"),
664228072Sbapt				 i, anum);
665228072Sbapt	}
666228072Sbapt
667228072Sbapt	buf_prints (&yydmap_buf,
668228072Sbapt		    "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n",
669228072Sbapt		    long_align ? "flex_int32_t" : "flex_int16_t");
670228072Sbapt	return tbl;
671228072Sbapt}
672228072Sbapt
673228072Sbapt
674228072Sbapt/* genftbl - generate full transition table */
675228072Sbapt
676228072Sbaptvoid genftbl ()
677228072Sbapt{
678250874Sjkim	int i;
679228072Sbapt	int     end_of_buffer_action = num_rules + 1;
680228072Sbapt
681228072Sbapt	out_str_dec (long_align ? get_int32_decl () : get_int16_decl (),
682228072Sbapt		     "yy_accept", lastdfa + 1);
683228072Sbapt
684228072Sbapt	dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
685228072Sbapt
686228072Sbapt	for (i = 1; i <= lastdfa; ++i) {
687250874Sjkim		int anum = dfaacc[i].dfaacc_state;
688228072Sbapt
689228072Sbapt		mkdata (anum);
690228072Sbapt
691228072Sbapt		if (trace && anum)
692228072Sbapt			fprintf (stderr, _("state # %d accepts: [%d]\n"),
693228072Sbapt				 i, anum);
694228072Sbapt	}
695228072Sbapt
696228072Sbapt	dataend ();
697228072Sbapt
698228072Sbapt	if (useecs)
699228072Sbapt		genecs ();
700228072Sbapt
701228072Sbapt	/* Don't have to dump the actual full table entries - they were
702228072Sbapt	 * created on-the-fly.
703228072Sbapt	 */
704228072Sbapt}
705228072Sbapt
706228072Sbapt
707228072Sbapt/* Generate the code to find the next compressed-table state. */
708228072Sbapt
709228072Sbaptvoid gen_next_compressed_state (char_map)
710228072Sbapt     char   *char_map;
711228072Sbapt{
712250874Sjkim	indent_put2s ("YY_CHAR yy_c = %s;", char_map);
713228072Sbapt
714228072Sbapt	/* Save the backing-up info \before/ computing the next state
715228072Sbapt	 * because we always compute one more state than needed - we
716228072Sbapt	 * always proceed until we reach a jam state
717228072Sbapt	 */
718228072Sbapt	gen_backing_up ();
719228072Sbapt
720228072Sbapt	indent_puts
721228072Sbapt		("while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )");
722228072Sbapt	indent_up ();
723228072Sbapt	indent_puts ("{");
724228072Sbapt	indent_puts ("yy_current_state = (int) yy_def[yy_current_state];");
725228072Sbapt
726228072Sbapt	if (usemecs) {
727228072Sbapt		/* We've arrange it so that templates are never chained
728228072Sbapt		 * to one another.  This means we can afford to make a
729228072Sbapt		 * very simple test to see if we need to convert to
730228072Sbapt		 * yy_c's meta-equivalence class without worrying
731228072Sbapt		 * about erroneously looking up the meta-equivalence
732228072Sbapt		 * class twice
733228072Sbapt		 */
734228072Sbapt		do_indent ();
735228072Sbapt
736228072Sbapt		/* lastdfa + 2 is the beginning of the templates */
737228072Sbapt		out_dec ("if ( yy_current_state >= %d )\n", lastdfa + 2);
738228072Sbapt
739228072Sbapt		indent_up ();
740228072Sbapt		indent_puts ("yy_c = yy_meta[(unsigned int) yy_c];");
741228072Sbapt		indent_down ();
742228072Sbapt	}
743228072Sbapt
744228072Sbapt	indent_puts ("}");
745228072Sbapt	indent_down ();
746228072Sbapt
747228072Sbapt	indent_puts
748228072Sbapt		("yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];");
749228072Sbapt}
750228072Sbapt
751228072Sbapt
752228072Sbapt/* Generate the code to find the next match. */
753228072Sbapt
754228072Sbaptvoid gen_next_match ()
755228072Sbapt{
756228072Sbapt	/* NOTE - changes in here should be reflected in gen_next_state() and
757228072Sbapt	 * gen_NUL_trans().
758228072Sbapt	 */
759228072Sbapt	char   *char_map = useecs ?
760228072Sbapt		"yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)";
761228072Sbapt
762228072Sbapt	char   *char_map_2 = useecs ?
763228072Sbapt		"yy_ec[YY_SC_TO_UI(*++yy_cp)] " : "YY_SC_TO_UI(*++yy_cp)";
764228072Sbapt
765228072Sbapt	if (fulltbl) {
766228072Sbapt		if (gentables)
767228072Sbapt			indent_put2s
768228072Sbapt				("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )",
769228072Sbapt				 char_map);
770228072Sbapt		else
771228072Sbapt			indent_put2s
772228072Sbapt				("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN +  %s ]) > 0 )",
773228072Sbapt				 char_map);
774228072Sbapt
775228072Sbapt		indent_up ();
776228072Sbapt
777228072Sbapt		if (num_backing_up > 0) {
778228072Sbapt			indent_puts ("{");
779228072Sbapt			gen_backing_up ();
780228072Sbapt			outc ('\n');
781228072Sbapt		}
782228072Sbapt
783228072Sbapt		indent_puts ("++yy_cp;");
784228072Sbapt
785228072Sbapt		if (num_backing_up > 0)
786228072Sbapt
787228072Sbapt			indent_puts ("}");
788228072Sbapt
789228072Sbapt		indent_down ();
790228072Sbapt
791228072Sbapt		outc ('\n');
792228072Sbapt		indent_puts ("yy_current_state = -yy_current_state;");
793228072Sbapt	}
794228072Sbapt
795228072Sbapt	else if (fullspd) {
796228072Sbapt		indent_puts ("{");
797228072Sbapt		indent_puts
798250874Sjkim			("yyconst struct yy_trans_info *yy_trans_info;\n");
799250874Sjkim		indent_puts ("YY_CHAR yy_c;\n");
800228072Sbapt		indent_put2s ("for ( yy_c = %s;", char_map);
801228072Sbapt		indent_puts
802228072Sbapt			("      (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->");
803228072Sbapt		indent_puts ("yy_verify == yy_c;");
804228072Sbapt		indent_put2s ("      yy_c = %s )", char_map_2);
805228072Sbapt
806228072Sbapt		indent_up ();
807228072Sbapt
808228072Sbapt		if (num_backing_up > 0)
809228072Sbapt			indent_puts ("{");
810228072Sbapt
811228072Sbapt		indent_puts ("yy_current_state += yy_trans_info->yy_nxt;");
812228072Sbapt
813228072Sbapt		if (num_backing_up > 0) {
814228072Sbapt			outc ('\n');
815228072Sbapt			gen_backing_up ();
816228072Sbapt			indent_puts ("}");
817228072Sbapt		}
818228072Sbapt
819228072Sbapt		indent_down ();
820228072Sbapt		indent_puts ("}");
821228072Sbapt	}
822228072Sbapt
823228072Sbapt	else {			/* compressed */
824228072Sbapt		indent_puts ("do");
825228072Sbapt
826228072Sbapt		indent_up ();
827228072Sbapt		indent_puts ("{");
828228072Sbapt
829228072Sbapt		gen_next_state (false);
830228072Sbapt
831228072Sbapt		indent_puts ("++yy_cp;");
832228072Sbapt
833228072Sbapt
834228072Sbapt		indent_puts ("}");
835228072Sbapt		indent_down ();
836228072Sbapt
837228072Sbapt		do_indent ();
838228072Sbapt
839228072Sbapt		if (interactive)
840228072Sbapt			out_dec ("while ( yy_base[yy_current_state] != %d );\n", jambase);
841228072Sbapt		else
842228072Sbapt			out_dec ("while ( yy_current_state != %d );\n",
843228072Sbapt				 jamstate);
844228072Sbapt
845228072Sbapt		if (!reject && !interactive) {
846228072Sbapt			/* Do the guaranteed-needed backing up to figure out
847228072Sbapt			 * the match.
848228072Sbapt			 */
849228072Sbapt			indent_puts
850228072Sbapt				("yy_cp = YY_G(yy_last_accepting_cpos);");
851228072Sbapt			indent_puts
852228072Sbapt				("yy_current_state = YY_G(yy_last_accepting_state);");
853228072Sbapt		}
854228072Sbapt	}
855228072Sbapt}
856228072Sbapt
857228072Sbapt
858228072Sbapt/* Generate the code to find the next state. */
859228072Sbapt
860228072Sbaptvoid gen_next_state (worry_about_NULs)
861228072Sbapt     int worry_about_NULs;
862228072Sbapt{				/* NOTE - changes in here should be reflected in gen_next_match() */
863228072Sbapt	char    char_map[256];
864228072Sbapt
865228072Sbapt	if (worry_about_NULs && !nultrans) {
866228072Sbapt		if (useecs)
867228072Sbapt			snprintf (char_map, sizeof(char_map),
868228072Sbapt					"(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)",
869228072Sbapt					NUL_ec);
870228072Sbapt		else
871228072Sbapt            snprintf (char_map, sizeof(char_map),
872228072Sbapt					"(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)",
873228072Sbapt					NUL_ec);
874228072Sbapt	}
875228072Sbapt
876228072Sbapt	else
877228072Sbapt		strcpy (char_map, useecs ?
878250128Sjkim			"yy_ec[YY_SC_TO_UI(*yy_cp)] " :
879228072Sbapt			"YY_SC_TO_UI(*yy_cp)");
880228072Sbapt
881228072Sbapt	if (worry_about_NULs && nultrans) {
882228072Sbapt		if (!fulltbl && !fullspd)
883228072Sbapt			/* Compressed tables back up *before* they match. */
884228072Sbapt			gen_backing_up ();
885228072Sbapt
886228072Sbapt		indent_puts ("if ( *yy_cp )");
887228072Sbapt		indent_up ();
888228072Sbapt		indent_puts ("{");
889228072Sbapt	}
890228072Sbapt
891228072Sbapt	if (fulltbl) {
892228072Sbapt		if (gentables)
893228072Sbapt			indent_put2s
894228072Sbapt				("yy_current_state = yy_nxt[yy_current_state][%s];",
895228072Sbapt				 char_map);
896228072Sbapt		else
897228072Sbapt			indent_put2s
898228072Sbapt				("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s];",
899228072Sbapt				 char_map);
900228072Sbapt	}
901228072Sbapt
902228072Sbapt	else if (fullspd)
903228072Sbapt		indent_put2s
904228072Sbapt			("yy_current_state += yy_current_state[%s].yy_nxt;",
905228072Sbapt			 char_map);
906228072Sbapt
907228072Sbapt	else
908228072Sbapt		gen_next_compressed_state (char_map);
909228072Sbapt
910228072Sbapt	if (worry_about_NULs && nultrans) {
911228072Sbapt
912228072Sbapt		indent_puts ("}");
913228072Sbapt		indent_down ();
914228072Sbapt		indent_puts ("else");
915228072Sbapt		indent_up ();
916228072Sbapt		indent_puts
917228072Sbapt			("yy_current_state = yy_NUL_trans[yy_current_state];");
918228072Sbapt		indent_down ();
919228072Sbapt	}
920228072Sbapt
921228072Sbapt	if (fullspd || fulltbl)
922228072Sbapt		gen_backing_up ();
923228072Sbapt
924228072Sbapt	if (reject)
925228072Sbapt		indent_puts ("*YY_G(yy_state_ptr)++ = yy_current_state;");
926228072Sbapt}
927228072Sbapt
928228072Sbapt
929228072Sbapt/* Generate the code to make a NUL transition. */
930228072Sbapt
931228072Sbaptvoid gen_NUL_trans ()
932228072Sbapt{				/* NOTE - changes in here should be reflected in gen_next_match() */
933228072Sbapt	/* Only generate a definition for "yy_cp" if we'll generate code
934228072Sbapt	 * that uses it.  Otherwise lint and the like complain.
935228072Sbapt	 */
936228072Sbapt	int     need_backing_up = (num_backing_up > 0 && !reject);
937228072Sbapt
938228072Sbapt	if (need_backing_up && (!nultrans || fullspd || fulltbl))
939228072Sbapt		/* We're going to need yy_cp lying around for the call
940228072Sbapt		 * below to gen_backing_up().
941228072Sbapt		 */
942250874Sjkim		indent_puts ("char *yy_cp = YY_G(yy_c_buf_p);");
943228072Sbapt
944228072Sbapt	outc ('\n');
945228072Sbapt
946228072Sbapt	if (nultrans) {
947228072Sbapt		indent_puts
948228072Sbapt			("yy_current_state = yy_NUL_trans[yy_current_state];");
949228072Sbapt		indent_puts ("yy_is_jam = (yy_current_state == 0);");
950228072Sbapt	}
951228072Sbapt
952228072Sbapt	else if (fulltbl) {
953228072Sbapt		do_indent ();
954228072Sbapt		if (gentables)
955228072Sbapt			out_dec ("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec);
956228072Sbapt		else
957228072Sbapt			out_dec ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %d];\n", NUL_ec);
958228072Sbapt		indent_puts ("yy_is_jam = (yy_current_state <= 0);");
959228072Sbapt	}
960228072Sbapt
961228072Sbapt	else if (fullspd) {
962228072Sbapt		do_indent ();
963250874Sjkim		out_dec ("int yy_c = %d;\n", NUL_ec);
964228072Sbapt
965228072Sbapt		indent_puts
966250874Sjkim			("yyconst struct yy_trans_info *yy_trans_info;\n");
967228072Sbapt		indent_puts
968228072Sbapt			("yy_trans_info = &yy_current_state[(unsigned int) yy_c];");
969228072Sbapt		indent_puts ("yy_current_state += yy_trans_info->yy_nxt;");
970228072Sbapt
971228072Sbapt		indent_puts
972228072Sbapt			("yy_is_jam = (yy_trans_info->yy_verify != yy_c);");
973228072Sbapt	}
974228072Sbapt
975228072Sbapt	else {
976228072Sbapt		char    NUL_ec_str[20];
977228072Sbapt
978228072Sbapt		snprintf (NUL_ec_str, sizeof(NUL_ec_str), "%d", NUL_ec);
979228072Sbapt		gen_next_compressed_state (NUL_ec_str);
980228072Sbapt
981228072Sbapt		do_indent ();
982228072Sbapt		out_dec ("yy_is_jam = (yy_current_state == %d);\n",
983228072Sbapt			 jamstate);
984228072Sbapt
985228072Sbapt		if (reject) {
986228072Sbapt			/* Only stack this state if it's a transition we
987228072Sbapt			 * actually make.  If we stack it on a jam, then
988228072Sbapt			 * the state stack and yy_c_buf_p get out of sync.
989228072Sbapt			 */
990228072Sbapt			indent_puts ("if ( ! yy_is_jam )");
991228072Sbapt			indent_up ();
992228072Sbapt			indent_puts
993228072Sbapt				("*YY_G(yy_state_ptr)++ = yy_current_state;");
994228072Sbapt			indent_down ();
995228072Sbapt		}
996228072Sbapt	}
997228072Sbapt
998228072Sbapt	/* If we've entered an accepting state, back up; note that
999228072Sbapt	 * compressed tables have *already* done such backing up, so
1000228072Sbapt	 * we needn't bother with it again.
1001228072Sbapt	 */
1002228072Sbapt	if (need_backing_up && (fullspd || fulltbl)) {
1003228072Sbapt		outc ('\n');
1004228072Sbapt		indent_puts ("if ( ! yy_is_jam )");
1005228072Sbapt		indent_up ();
1006228072Sbapt		indent_puts ("{");
1007228072Sbapt		gen_backing_up ();
1008228072Sbapt		indent_puts ("}");
1009228072Sbapt		indent_down ();
1010228072Sbapt	}
1011228072Sbapt}
1012228072Sbapt
1013228072Sbapt
1014228072Sbapt/* Generate the code to find the start state. */
1015228072Sbapt
1016228072Sbaptvoid gen_start_state ()
1017228072Sbapt{
1018228072Sbapt	if (fullspd) {
1019228072Sbapt		if (bol_needed) {
1020228072Sbapt			indent_puts
1021228072Sbapt				("yy_current_state = yy_start_state_list[YY_G(yy_start) + YY_AT_BOL()];");
1022228072Sbapt		}
1023228072Sbapt		else
1024228072Sbapt			indent_puts
1025228072Sbapt				("yy_current_state = yy_start_state_list[YY_G(yy_start)];");
1026228072Sbapt	}
1027228072Sbapt
1028228072Sbapt	else {
1029228072Sbapt		indent_puts ("yy_current_state = YY_G(yy_start);");
1030228072Sbapt
1031228072Sbapt		if (bol_needed)
1032228072Sbapt			indent_puts ("yy_current_state += YY_AT_BOL();");
1033228072Sbapt
1034228072Sbapt		if (reject) {
1035228072Sbapt			/* Set up for storing up states. */
1036228072Sbapt			outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[[");
1037228072Sbapt			indent_puts
1038228072Sbapt				("YY_G(yy_state_ptr) = YY_G(yy_state_buf);");
1039228072Sbapt			indent_puts
1040228072Sbapt				("*YY_G(yy_state_ptr)++ = yy_current_state;");
1041228072Sbapt			outn ("]])");
1042228072Sbapt		}
1043228072Sbapt	}
1044228072Sbapt}
1045228072Sbapt
1046228072Sbapt
1047228072Sbapt/* gentabs - generate data statements for the transition tables */
1048228072Sbapt
1049228072Sbaptvoid gentabs ()
1050228072Sbapt{
1051228072Sbapt	int     i, j, k, *accset, nacc, *acc_array, total_states;
1052228072Sbapt	int     end_of_buffer_action = num_rules + 1;
1053228072Sbapt	struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0,
1054228072Sbapt		*yydef_tbl = 0, *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl=0;
1055228072Sbapt	flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0,
1056228072Sbapt		*yynxt_data = 0, *yychk_data = 0, *yyacclist_data=0;
1057228072Sbapt	flex_int32_t yybase_curr = 0, yyacclist_curr=0,yyacc_curr=0;
1058228072Sbapt
1059228072Sbapt	acc_array = allocate_integer_array (current_max_dfas);
1060228072Sbapt	nummt = 0;
1061228072Sbapt
1062228072Sbapt	/* The compressed table format jams by entering the "jam state",
1063228072Sbapt	 * losing information about the previous state in the process.
1064228072Sbapt	 * In order to recover the previous state, we effectively need
1065228072Sbapt	 * to keep backing-up information.
1066228072Sbapt	 */
1067228072Sbapt	++num_backing_up;
1068228072Sbapt
1069228072Sbapt	if (reject) {
1070228072Sbapt		/* Write out accepting list and pointer list.
1071228072Sbapt
1072228072Sbapt		 * First we generate the "yy_acclist" array.  In the process,
1073228072Sbapt		 * we compute the indices that will go into the "yy_accept"
1074228072Sbapt		 * array, and save the indices in the dfaacc array.
1075228072Sbapt		 */
1076228072Sbapt		int     EOB_accepting_list[2];
1077228072Sbapt
1078228072Sbapt		/* Set up accepting structures for the End Of Buffer state. */
1079228072Sbapt		EOB_accepting_list[0] = 0;
1080228072Sbapt		EOB_accepting_list[1] = end_of_buffer_action;
1081228072Sbapt		accsiz[end_of_buffer_state] = 1;
1082228072Sbapt		dfaacc[end_of_buffer_state].dfaacc_set =
1083228072Sbapt			EOB_accepting_list;
1084228072Sbapt
1085228072Sbapt		out_str_dec (long_align ? get_int32_decl () :
1086228072Sbapt			     get_int16_decl (), "yy_acclist", MAX (numas,
1087228072Sbapt								   1) + 1);
1088228072Sbapt
1089228072Sbapt        buf_prints (&yydmap_buf,
1090228072Sbapt                "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n",
1091228072Sbapt                long_align ? "flex_int32_t" : "flex_int16_t");
1092228072Sbapt
1093228072Sbapt        yyacclist_tbl = (struct yytbl_data*)calloc(1,sizeof(struct yytbl_data));
1094228072Sbapt        yytbl_data_init (yyacclist_tbl, YYTD_ID_ACCLIST);
1095228072Sbapt        yyacclist_tbl->td_lolen  = MAX(numas,1) + 1;
1096228072Sbapt        yyacclist_tbl->td_data = yyacclist_data =
1097228072Sbapt            (flex_int32_t *) calloc (yyacclist_tbl->td_lolen, sizeof (flex_int32_t));
1098228072Sbapt        yyacclist_curr = 1;
1099228072Sbapt
1100228072Sbapt		j = 1;		/* index into "yy_acclist" array */
1101228072Sbapt
1102228072Sbapt		for (i = 1; i <= lastdfa; ++i) {
1103228072Sbapt			acc_array[i] = j;
1104228072Sbapt
1105228072Sbapt			if (accsiz[i] != 0) {
1106228072Sbapt				accset = dfaacc[i].dfaacc_set;
1107228072Sbapt				nacc = accsiz[i];
1108228072Sbapt
1109228072Sbapt				if (trace)
1110228072Sbapt					fprintf (stderr,
1111228072Sbapt						 _("state # %d accepts: "),
1112228072Sbapt						 i);
1113228072Sbapt
1114228072Sbapt				for (k = 1; k <= nacc; ++k) {
1115228072Sbapt					int     accnum = accset[k];
1116228072Sbapt
1117228072Sbapt					++j;
1118228072Sbapt
1119228072Sbapt					if (variable_trailing_context_rules
1120228072Sbapt					    && !(accnum &
1121228072Sbapt						 YY_TRAILING_HEAD_MASK)
1122228072Sbapt					    && accnum > 0
1123228072Sbapt					    && accnum <= num_rules
1124228072Sbapt					    && rule_type[accnum] ==
1125228072Sbapt					    RULE_VARIABLE) {
1126228072Sbapt						/* Special hack to flag
1127228072Sbapt						 * accepting number as part
1128228072Sbapt						 * of trailing context rule.
1129228072Sbapt						 */
1130228072Sbapt						accnum |= YY_TRAILING_MASK;
1131228072Sbapt					}
1132228072Sbapt
1133228072Sbapt					mkdata (accnum);
1134228072Sbapt                    yyacclist_data[yyacclist_curr++] = accnum;
1135228072Sbapt
1136228072Sbapt					if (trace) {
1137228072Sbapt						fprintf (stderr, "[%d]",
1138228072Sbapt							 accset[k]);
1139228072Sbapt
1140228072Sbapt						if (k < nacc)
1141228072Sbapt							fputs (", ",
1142228072Sbapt							       stderr);
1143228072Sbapt						else
1144228072Sbapt							putc ('\n',
1145228072Sbapt							      stderr);
1146228072Sbapt					}
1147228072Sbapt				}
1148228072Sbapt			}
1149228072Sbapt		}
1150228072Sbapt
1151228072Sbapt		/* add accepting number for the "jam" state */
1152228072Sbapt		acc_array[i] = j;
1153228072Sbapt
1154228072Sbapt		dataend ();
1155228072Sbapt        if (tablesext) {
1156228072Sbapt            yytbl_data_compress (yyacclist_tbl);
1157228072Sbapt            if (yytbl_data_fwrite (&tableswr, yyacclist_tbl) < 0)
1158228072Sbapt                flexerror (_("Could not write yyacclist_tbl"));
1159228072Sbapt            yytbl_data_destroy (yyacclist_tbl);
1160228072Sbapt            yyacclist_tbl = NULL;
1161228072Sbapt        }
1162228072Sbapt	}
1163228072Sbapt
1164228072Sbapt	else {
1165228072Sbapt		dfaacc[end_of_buffer_state].dfaacc_state =
1166228072Sbapt			end_of_buffer_action;
1167228072Sbapt
1168228072Sbapt		for (i = 1; i <= lastdfa; ++i)
1169228072Sbapt			acc_array[i] = dfaacc[i].dfaacc_state;
1170228072Sbapt
1171228072Sbapt		/* add accepting number for jam state */
1172228072Sbapt		acc_array[i] = 0;
1173228072Sbapt	}
1174228072Sbapt
1175228072Sbapt	/* Begin generating yy_accept */
1176228072Sbapt
1177228072Sbapt	/* Spit out "yy_accept" array.  If we're doing "reject", it'll be
1178228072Sbapt	 * pointers into the "yy_acclist" array.  Otherwise it's actual
1179228072Sbapt	 * accepting numbers.  In either case, we just dump the numbers.
1180228072Sbapt	 */
1181228072Sbapt
1182228072Sbapt	/* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays
1183228072Sbapt	 * beginning at 0 and for "jam" state.
1184228072Sbapt	 */
1185228072Sbapt	k = lastdfa + 2;
1186228072Sbapt
1187228072Sbapt	if (reject)
1188228072Sbapt		/* We put a "cap" on the table associating lists of accepting
1189228072Sbapt		 * numbers with state numbers.  This is needed because we tell
1190228072Sbapt		 * where the end of an accepting list is by looking at where
1191228072Sbapt		 * the list for the next state starts.
1192228072Sbapt		 */
1193228072Sbapt		++k;
1194228072Sbapt
1195228072Sbapt	out_str_dec (long_align ? get_int32_decl () : get_int16_decl (),
1196228072Sbapt		     "yy_accept", k);
1197228072Sbapt
1198228072Sbapt	buf_prints (&yydmap_buf,
1199228072Sbapt		    "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n",
1200228072Sbapt		    long_align ? "flex_int32_t" : "flex_int16_t");
1201228072Sbapt
1202228072Sbapt	yyacc_tbl =
1203228072Sbapt		(struct yytbl_data *) calloc (1,
1204228072Sbapt					      sizeof (struct yytbl_data));
1205228072Sbapt	yytbl_data_init (yyacc_tbl, YYTD_ID_ACCEPT);
1206228072Sbapt	yyacc_tbl->td_lolen = k;
1207228072Sbapt	yyacc_tbl->td_data = yyacc_data =
1208228072Sbapt		(flex_int32_t *) calloc (yyacc_tbl->td_lolen, sizeof (flex_int32_t));
1209228072Sbapt    yyacc_curr=1;
1210228072Sbapt
1211228072Sbapt	for (i = 1; i <= lastdfa; ++i) {
1212228072Sbapt		mkdata (acc_array[i]);
1213228072Sbapt		yyacc_data[yyacc_curr++] = acc_array[i];
1214228072Sbapt
1215228072Sbapt		if (!reject && trace && acc_array[i])
1216228072Sbapt			fprintf (stderr, _("state # %d accepts: [%d]\n"),
1217228072Sbapt				 i, acc_array[i]);
1218228072Sbapt	}
1219228072Sbapt
1220228072Sbapt	/* Add entry for "jam" state. */
1221228072Sbapt	mkdata (acc_array[i]);
1222228072Sbapt	yyacc_data[yyacc_curr++] = acc_array[i];
1223228072Sbapt
1224228072Sbapt	if (reject) {
1225228072Sbapt		/* Add "cap" for the list. */
1226228072Sbapt		mkdata (acc_array[i]);
1227228072Sbapt		yyacc_data[yyacc_curr++] = acc_array[i];
1228228072Sbapt	}
1229228072Sbapt
1230228072Sbapt	dataend ();
1231228072Sbapt	if (tablesext) {
1232228072Sbapt		yytbl_data_compress (yyacc_tbl);
1233228072Sbapt		if (yytbl_data_fwrite (&tableswr, yyacc_tbl) < 0)
1234228072Sbapt			flexerror (_("Could not write yyacc_tbl"));
1235228072Sbapt		yytbl_data_destroy (yyacc_tbl);
1236228072Sbapt		yyacc_tbl = NULL;
1237228072Sbapt	}
1238228072Sbapt	/* End generating yy_accept */
1239228072Sbapt
1240228072Sbapt	if (useecs) {
1241228072Sbapt
1242228072Sbapt		genecs ();
1243228072Sbapt		if (tablesext) {
1244228072Sbapt			struct yytbl_data *tbl;
1245228072Sbapt
1246228072Sbapt			tbl = mkecstbl ();
1247228072Sbapt			yytbl_data_compress (tbl);
1248228072Sbapt			if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1249228072Sbapt				flexerror (_("Could not write ecstbl"));
1250228072Sbapt			yytbl_data_destroy (tbl);
1251228072Sbapt			tbl = 0;
1252228072Sbapt		}
1253228072Sbapt	}
1254228072Sbapt
1255228072Sbapt	if (usemecs) {
1256228072Sbapt		/* Begin generating yy_meta */
1257228072Sbapt		/* Write out meta-equivalence classes (used to index
1258228072Sbapt		 * templates with).
1259228072Sbapt		 */
1260228072Sbapt		flex_int32_t *yymecs_data = 0;
1261228072Sbapt		yymeta_tbl =
1262228072Sbapt			(struct yytbl_data *) calloc (1,
1263228072Sbapt						      sizeof (struct
1264228072Sbapt							      yytbl_data));
1265228072Sbapt		yytbl_data_init (yymeta_tbl, YYTD_ID_META);
1266228072Sbapt		yymeta_tbl->td_lolen = numecs + 1;
1267228072Sbapt		yymeta_tbl->td_data = yymecs_data =
1268228072Sbapt			(flex_int32_t *) calloc (yymeta_tbl->td_lolen,
1269228072Sbapt					    sizeof (flex_int32_t));
1270228072Sbapt
1271228072Sbapt		if (trace)
1272228072Sbapt			fputs (_("\n\nMeta-Equivalence Classes:\n"),
1273228072Sbapt			       stderr);
1274228072Sbapt
1275228072Sbapt		out_str_dec (get_int32_decl (), "yy_meta", numecs + 1);
1276228072Sbapt		buf_prints (&yydmap_buf,
1277228072Sbapt			    "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n",
1278228072Sbapt			    "flex_int32_t");
1279228072Sbapt
1280228072Sbapt		for (i = 1; i <= numecs; ++i) {
1281228072Sbapt			if (trace)
1282228072Sbapt				fprintf (stderr, "%d = %d\n",
1283228072Sbapt					 i, ABS (tecbck[i]));
1284228072Sbapt
1285228072Sbapt			mkdata (ABS (tecbck[i]));
1286228072Sbapt			yymecs_data[i] = ABS (tecbck[i]);
1287228072Sbapt		}
1288228072Sbapt
1289228072Sbapt		dataend ();
1290228072Sbapt		if (tablesext) {
1291228072Sbapt			yytbl_data_compress (yymeta_tbl);
1292228072Sbapt			if (yytbl_data_fwrite (&tableswr, yymeta_tbl) < 0)
1293228072Sbapt				flexerror (_
1294228072Sbapt					   ("Could not write yymeta_tbl"));
1295228072Sbapt			yytbl_data_destroy (yymeta_tbl);
1296228072Sbapt			yymeta_tbl = NULL;
1297228072Sbapt		}
1298228072Sbapt		/* End generating yy_meta */
1299228072Sbapt	}
1300228072Sbapt
1301228072Sbapt	total_states = lastdfa + numtemps;
1302228072Sbapt
1303228072Sbapt	/* Begin generating yy_base */
1304228072Sbapt	out_str_dec ((tblend >= INT16_MAX || long_align) ?
1305228072Sbapt		     get_int32_decl () : get_int16_decl (),
1306228072Sbapt		     "yy_base", total_states + 1);
1307228072Sbapt
1308228072Sbapt	buf_prints (&yydmap_buf,
1309228072Sbapt		    "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n",
1310228072Sbapt		    (tblend >= INT16_MAX
1311228072Sbapt		     || long_align) ? "flex_int32_t" : "flex_int16_t");
1312228072Sbapt	yybase_tbl =
1313228072Sbapt		(struct yytbl_data *) calloc (1,
1314228072Sbapt					      sizeof (struct yytbl_data));
1315228072Sbapt	yytbl_data_init (yybase_tbl, YYTD_ID_BASE);
1316228072Sbapt	yybase_tbl->td_lolen = total_states + 1;
1317228072Sbapt	yybase_tbl->td_data = yybase_data =
1318228072Sbapt		(flex_int32_t *) calloc (yybase_tbl->td_lolen,
1319228072Sbapt				    sizeof (flex_int32_t));
1320228072Sbapt	yybase_curr = 1;
1321228072Sbapt
1322228072Sbapt	for (i = 1; i <= lastdfa; ++i) {
1323250874Sjkim		int d = def[i];
1324228072Sbapt
1325228072Sbapt		if (base[i] == JAMSTATE)
1326228072Sbapt			base[i] = jambase;
1327228072Sbapt
1328228072Sbapt		if (d == JAMSTATE)
1329228072Sbapt			def[i] = jamstate;
1330228072Sbapt
1331228072Sbapt		else if (d < 0) {
1332228072Sbapt			/* Template reference. */
1333228072Sbapt			++tmpuses;
1334228072Sbapt			def[i] = lastdfa - d + 1;
1335228072Sbapt		}
1336228072Sbapt
1337228072Sbapt		mkdata (base[i]);
1338228072Sbapt		yybase_data[yybase_curr++] = base[i];
1339228072Sbapt	}
1340228072Sbapt
1341228072Sbapt	/* Generate jam state's base index. */
1342228072Sbapt	mkdata (base[i]);
1343228072Sbapt	yybase_data[yybase_curr++] = base[i];
1344228072Sbapt
1345228072Sbapt	for (++i /* skip jam state */ ; i <= total_states; ++i) {
1346228072Sbapt		mkdata (base[i]);
1347228072Sbapt		yybase_data[yybase_curr++] = base[i];
1348228072Sbapt		def[i] = jamstate;
1349228072Sbapt	}
1350228072Sbapt
1351228072Sbapt	dataend ();
1352228072Sbapt	if (tablesext) {
1353228072Sbapt		yytbl_data_compress (yybase_tbl);
1354228072Sbapt		if (yytbl_data_fwrite (&tableswr, yybase_tbl) < 0)
1355228072Sbapt			flexerror (_("Could not write yybase_tbl"));
1356228072Sbapt		yytbl_data_destroy (yybase_tbl);
1357228072Sbapt		yybase_tbl = NULL;
1358228072Sbapt	}
1359228072Sbapt	/* End generating yy_base */
1360228072Sbapt
1361228072Sbapt
1362228072Sbapt	/* Begin generating yy_def */
1363228072Sbapt	out_str_dec ((total_states >= INT16_MAX || long_align) ?
1364228072Sbapt		     get_int32_decl () : get_int16_decl (),
1365228072Sbapt		     "yy_def", total_states + 1);
1366228072Sbapt
1367228072Sbapt	buf_prints (&yydmap_buf,
1368228072Sbapt		    "\t{YYTD_ID_DEF, (void**)&yy_def, sizeof(%s)},\n",
1369228072Sbapt		    (total_states >= INT16_MAX
1370228072Sbapt		     || long_align) ? "flex_int32_t" : "flex_int16_t");
1371228072Sbapt
1372228072Sbapt	yydef_tbl =
1373228072Sbapt		(struct yytbl_data *) calloc (1,
1374228072Sbapt					      sizeof (struct yytbl_data));
1375228072Sbapt	yytbl_data_init (yydef_tbl, YYTD_ID_DEF);
1376228072Sbapt	yydef_tbl->td_lolen = total_states + 1;
1377228072Sbapt	yydef_tbl->td_data = yydef_data =
1378228072Sbapt		(flex_int32_t *) calloc (yydef_tbl->td_lolen, sizeof (flex_int32_t));
1379228072Sbapt
1380228072Sbapt	for (i = 1; i <= total_states; ++i) {
1381228072Sbapt		mkdata (def[i]);
1382228072Sbapt		yydef_data[i] = def[i];
1383228072Sbapt	}
1384228072Sbapt
1385228072Sbapt	dataend ();
1386228072Sbapt	if (tablesext) {
1387228072Sbapt		yytbl_data_compress (yydef_tbl);
1388228072Sbapt		if (yytbl_data_fwrite (&tableswr, yydef_tbl) < 0)
1389228072Sbapt			flexerror (_("Could not write yydef_tbl"));
1390228072Sbapt		yytbl_data_destroy (yydef_tbl);
1391228072Sbapt		yydef_tbl = NULL;
1392228072Sbapt	}
1393228072Sbapt	/* End generating yy_def */
1394228072Sbapt
1395228072Sbapt
1396228072Sbapt	/* Begin generating yy_nxt */
1397228072Sbapt	out_str_dec ((total_states >= INT16_MAX || long_align) ?
1398228072Sbapt		     get_int32_decl () : get_int16_decl (), "yy_nxt",
1399228072Sbapt		     tblend + 1);
1400228072Sbapt
1401228072Sbapt	buf_prints (&yydmap_buf,
1402228072Sbapt		    "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n",
1403228072Sbapt		    (total_states >= INT16_MAX
1404228072Sbapt		     || long_align) ? "flex_int32_t" : "flex_int16_t");
1405228072Sbapt
1406228072Sbapt	yynxt_tbl =
1407228072Sbapt		(struct yytbl_data *) calloc (1,
1408228072Sbapt					      sizeof (struct yytbl_data));
1409228072Sbapt	yytbl_data_init (yynxt_tbl, YYTD_ID_NXT);
1410228072Sbapt	yynxt_tbl->td_lolen = tblend + 1;
1411228072Sbapt	yynxt_tbl->td_data = yynxt_data =
1412228072Sbapt		(flex_int32_t *) calloc (yynxt_tbl->td_lolen, sizeof (flex_int32_t));
1413228072Sbapt
1414228072Sbapt	for (i = 1; i <= tblend; ++i) {
1415228072Sbapt		/* Note, the order of the following test is important.
1416228072Sbapt		 * If chk[i] is 0, then nxt[i] is undefined.
1417228072Sbapt		 */
1418228072Sbapt		if (chk[i] == 0 || nxt[i] == 0)
1419228072Sbapt			nxt[i] = jamstate;	/* new state is the JAM state */
1420228072Sbapt
1421228072Sbapt		mkdata (nxt[i]);
1422228072Sbapt		yynxt_data[i] = nxt[i];
1423228072Sbapt	}
1424228072Sbapt
1425228072Sbapt	dataend ();
1426228072Sbapt	if (tablesext) {
1427228072Sbapt		yytbl_data_compress (yynxt_tbl);
1428228072Sbapt		if (yytbl_data_fwrite (&tableswr, yynxt_tbl) < 0)
1429228072Sbapt			flexerror (_("Could not write yynxt_tbl"));
1430228072Sbapt		yytbl_data_destroy (yynxt_tbl);
1431228072Sbapt		yynxt_tbl = NULL;
1432228072Sbapt	}
1433228072Sbapt	/* End generating yy_nxt */
1434228072Sbapt
1435228072Sbapt	/* Begin generating yy_chk */
1436228072Sbapt	out_str_dec ((total_states >= INT16_MAX || long_align) ?
1437228072Sbapt		     get_int32_decl () : get_int16_decl (), "yy_chk",
1438228072Sbapt		     tblend + 1);
1439228072Sbapt
1440228072Sbapt	buf_prints (&yydmap_buf,
1441228072Sbapt		    "\t{YYTD_ID_CHK, (void**)&yy_chk, sizeof(%s)},\n",
1442228072Sbapt		    (total_states >= INT16_MAX
1443228072Sbapt		     || long_align) ? "flex_int32_t" : "flex_int16_t");
1444228072Sbapt
1445228072Sbapt	yychk_tbl =
1446228072Sbapt		(struct yytbl_data *) calloc (1,
1447228072Sbapt					      sizeof (struct yytbl_data));
1448228072Sbapt	yytbl_data_init (yychk_tbl, YYTD_ID_CHK);
1449228072Sbapt	yychk_tbl->td_lolen = tblend + 1;
1450228072Sbapt	yychk_tbl->td_data = yychk_data =
1451228072Sbapt		(flex_int32_t *) calloc (yychk_tbl->td_lolen, sizeof (flex_int32_t));
1452228072Sbapt
1453228072Sbapt	for (i = 1; i <= tblend; ++i) {
1454228072Sbapt		if (chk[i] == 0)
1455228072Sbapt			++nummt;
1456228072Sbapt
1457228072Sbapt		mkdata (chk[i]);
1458228072Sbapt		yychk_data[i] = chk[i];
1459228072Sbapt	}
1460228072Sbapt
1461228072Sbapt	dataend ();
1462228072Sbapt	if (tablesext) {
1463228072Sbapt		yytbl_data_compress (yychk_tbl);
1464228072Sbapt		if (yytbl_data_fwrite (&tableswr, yychk_tbl) < 0)
1465228072Sbapt			flexerror (_("Could not write yychk_tbl"));
1466228072Sbapt		yytbl_data_destroy (yychk_tbl);
1467228072Sbapt		yychk_tbl = NULL;
1468228072Sbapt	}
1469228072Sbapt	/* End generating yy_chk */
1470228072Sbapt
1471228072Sbapt	flex_free ((void *) acc_array);
1472228072Sbapt}
1473228072Sbapt
1474228072Sbapt
1475228072Sbapt/* Write out a formatted string (with a secondary string argument) at the
1476228072Sbapt * current indentation level, adding a final newline.
1477228072Sbapt */
1478228072Sbapt
1479228072Sbaptvoid indent_put2s (fmt, arg)
1480228072Sbapt     const char *fmt, *arg;
1481228072Sbapt{
1482228072Sbapt	do_indent ();
1483228072Sbapt	out_str (fmt, arg);
1484228072Sbapt	outn ("");
1485228072Sbapt}
1486228072Sbapt
1487228072Sbapt
1488228072Sbapt/* Write out a string at the current indentation level, adding a final
1489228072Sbapt * newline.
1490228072Sbapt */
1491228072Sbapt
1492228072Sbaptvoid indent_puts (str)
1493228072Sbapt     const char *str;
1494228072Sbapt{
1495228072Sbapt	do_indent ();
1496228072Sbapt	outn (str);
1497228072Sbapt}
1498228072Sbapt
1499228072Sbapt
1500228072Sbapt/* make_tables - generate transition tables and finishes generating output file
1501228072Sbapt */
1502228072Sbapt
1503228072Sbaptvoid make_tables ()
1504228072Sbapt{
1505250874Sjkim	int i;
1506228072Sbapt	int     did_eof_rule = false;
1507228072Sbapt	struct yytbl_data *yynultrans_tbl;
1508228072Sbapt
1509228072Sbapt
1510228072Sbapt	skelout ();		/* %% [2.0] - break point in skel */
1511228072Sbapt
1512228072Sbapt	/* First, take care of YY_DO_BEFORE_ACTION depending on yymore
1513228072Sbapt	 * being used.
1514228072Sbapt	 */
1515228072Sbapt	set_indent (1);
1516228072Sbapt
1517228072Sbapt	if (yymore_used && !yytext_is_array) {
1518228072Sbapt		indent_puts ("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\");
1519228072Sbapt		indent_puts
1520228072Sbapt			("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\");
1521228072Sbapt	}
1522228072Sbapt
1523228072Sbapt	else
1524228072Sbapt		indent_puts ("yyleng = (size_t) (yy_cp - yy_bp); \\");
1525228072Sbapt
1526228072Sbapt	/* Now also deal with copying yytext_ptr to yytext if needed. */
1527228072Sbapt	skelout ();		/* %% [3.0] - break point in skel */
1528228072Sbapt	if (yytext_is_array) {
1529228072Sbapt		if (yymore_used)
1530228072Sbapt			indent_puts
1531228072Sbapt				("if ( yyleng + YY_G(yy_more_offset) >= YYLMAX ) \\");
1532228072Sbapt		else
1533228072Sbapt			indent_puts ("if ( yyleng >= YYLMAX ) \\");
1534228072Sbapt
1535228072Sbapt		indent_up ();
1536228072Sbapt		indent_puts
1537228072Sbapt			("YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\");
1538228072Sbapt		indent_down ();
1539228072Sbapt
1540228072Sbapt		if (yymore_used) {
1541228072Sbapt			indent_puts
1542228072Sbapt				("yy_flex_strncpy( &yytext[YY_G(yy_more_offset)], YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\");
1543228072Sbapt			indent_puts ("yyleng += YY_G(yy_more_offset); \\");
1544228072Sbapt			indent_puts
1545228072Sbapt				("YY_G(yy_prev_more_offset) = YY_G(yy_more_offset); \\");
1546228072Sbapt			indent_puts ("YY_G(yy_more_offset) = 0; \\");
1547228072Sbapt		}
1548228072Sbapt		else {
1549228072Sbapt			indent_puts
1550228072Sbapt				("yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\");
1551228072Sbapt		}
1552228072Sbapt	}
1553228072Sbapt
1554228072Sbapt	set_indent (0);
1555228072Sbapt
1556228072Sbapt	skelout ();		/* %% [4.0] - break point in skel */
1557228072Sbapt
1558228072Sbapt
1559228072Sbapt	/* This is where we REALLY begin generating the tables. */
1560228072Sbapt
1561228072Sbapt	out_dec ("#define YY_NUM_RULES %d\n", num_rules);
1562228072Sbapt	out_dec ("#define YY_END_OF_BUFFER %d\n", num_rules + 1);
1563228072Sbapt
1564228072Sbapt	if (fullspd) {
1565228072Sbapt		/* Need to define the transet type as a size large
1566228072Sbapt		 * enough to hold the biggest offset.
1567228072Sbapt		 */
1568228072Sbapt		int     total_table_size = tblend + numecs + 1;
1569228072Sbapt		char   *trans_offset_type =
1570228072Sbapt			(total_table_size >= INT16_MAX || long_align) ?
1571228072Sbapt			"flex_int32_t" : "flex_int16_t";
1572228072Sbapt
1573228072Sbapt		set_indent (0);
1574228072Sbapt		indent_puts ("struct yy_trans_info");
1575228072Sbapt		indent_up ();
1576228072Sbapt		indent_puts ("{");
1577228072Sbapt
1578228072Sbapt		/* We require that yy_verify and yy_nxt must be of the same size int. */
1579228072Sbapt		indent_put2s ("%s yy_verify;", trans_offset_type);
1580228072Sbapt
1581228072Sbapt		/* In cases where its sister yy_verify *is* a "yes, there is
1582228072Sbapt		 * a transition", yy_nxt is the offset (in records) to the
1583228072Sbapt		 * next state.  In most cases where there is no transition,
1584228072Sbapt		 * the value of yy_nxt is irrelevant.  If yy_nxt is the -1th
1585228072Sbapt		 * record of a state, though, then yy_nxt is the action number
1586228072Sbapt		 * for that state.
1587228072Sbapt		 */
1588228072Sbapt
1589228072Sbapt		indent_put2s ("%s yy_nxt;", trans_offset_type);
1590228072Sbapt		indent_puts ("};");
1591228072Sbapt		indent_down ();
1592228072Sbapt	}
1593228072Sbapt	else {
1594228072Sbapt		/* We generate a bogus 'struct yy_trans_info' data type
1595228072Sbapt		 * so we can guarantee that it is always declared in the skel.
1596228072Sbapt		 * This is so we can compile "sizeof(struct yy_trans_info)"
1597228072Sbapt		 * in any scanner.
1598228072Sbapt		 */
1599228072Sbapt		indent_puts
1600228072Sbapt			("/* This struct is not used in this scanner,");
1601228072Sbapt		indent_puts ("   but its presence is necessary. */");
1602228072Sbapt		indent_puts ("struct yy_trans_info");
1603228072Sbapt		indent_up ();
1604228072Sbapt		indent_puts ("{");
1605228072Sbapt		indent_puts ("flex_int32_t yy_verify;");
1606228072Sbapt		indent_puts ("flex_int32_t yy_nxt;");
1607228072Sbapt		indent_puts ("};");
1608228072Sbapt		indent_down ();
1609228072Sbapt	}
1610228072Sbapt
1611228072Sbapt	if (fullspd) {
1612228072Sbapt		genctbl ();
1613228072Sbapt		if (tablesext) {
1614228072Sbapt			struct yytbl_data *tbl;
1615228072Sbapt
1616228072Sbapt			tbl = mkctbl ();
1617228072Sbapt			yytbl_data_compress (tbl);
1618228072Sbapt			if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1619228072Sbapt				flexerror (_("Could not write ftbl"));
1620228072Sbapt			yytbl_data_destroy (tbl);
1621228072Sbapt
1622228072Sbapt			tbl = mkssltbl ();
1623228072Sbapt			yytbl_data_compress (tbl);
1624228072Sbapt			if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1625228072Sbapt				flexerror (_("Could not write ssltbl"));
1626228072Sbapt			yytbl_data_destroy (tbl);
1627228072Sbapt			tbl = 0;
1628228072Sbapt
1629228072Sbapt			if (useecs) {
1630228072Sbapt				tbl = mkecstbl ();
1631228072Sbapt				yytbl_data_compress (tbl);
1632228072Sbapt				if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1633228072Sbapt					flexerror (_
1634228072Sbapt						   ("Could not write ecstbl"));
1635228072Sbapt				yytbl_data_destroy (tbl);
1636228072Sbapt				tbl = 0;
1637228072Sbapt			}
1638228072Sbapt		}
1639228072Sbapt	}
1640228072Sbapt	else if (fulltbl) {
1641228072Sbapt		genftbl ();
1642228072Sbapt		if (tablesext) {
1643228072Sbapt			struct yytbl_data *tbl;
1644228072Sbapt
1645228072Sbapt			tbl = mkftbl ();
1646228072Sbapt			yytbl_data_compress (tbl);
1647228072Sbapt			if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1648228072Sbapt				flexerror (_("Could not write ftbl"));
1649228072Sbapt			yytbl_data_destroy (tbl);
1650228072Sbapt			tbl = 0;
1651228072Sbapt
1652228072Sbapt			if (useecs) {
1653228072Sbapt				tbl = mkecstbl ();
1654228072Sbapt				yytbl_data_compress (tbl);
1655228072Sbapt				if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1656228072Sbapt					flexerror (_
1657228072Sbapt						   ("Could not write ecstbl"));
1658228072Sbapt				yytbl_data_destroy (tbl);
1659228072Sbapt				tbl = 0;
1660228072Sbapt			}
1661228072Sbapt		}
1662228072Sbapt	}
1663228072Sbapt	else
1664228072Sbapt		gentabs ();
1665228072Sbapt
1666228072Sbapt	if (do_yylineno) {
1667228072Sbapt
1668228072Sbapt		geneoltbl ();
1669228072Sbapt
1670228072Sbapt		if (tablesext) {
1671228072Sbapt			struct yytbl_data *tbl;
1672228072Sbapt
1673228072Sbapt			tbl = mkeoltbl ();
1674228072Sbapt			yytbl_data_compress (tbl);
1675228072Sbapt			if (yytbl_data_fwrite (&tableswr, tbl) < 0)
1676228072Sbapt				flexerror (_("Could not write eoltbl"));
1677228072Sbapt			yytbl_data_destroy (tbl);
1678228072Sbapt			tbl = 0;
1679228072Sbapt		}
1680228072Sbapt	}
1681228072Sbapt
1682228072Sbapt	/* Definitions for backing up.  We don't need them if REJECT
1683228072Sbapt	 * is being used because then we use an alternative backin-up
1684228072Sbapt	 * technique instead.
1685228072Sbapt	 */
1686228072Sbapt	if (num_backing_up > 0 && !reject) {
1687228072Sbapt		if (!C_plus_plus && !reentrant) {
1688228072Sbapt			indent_puts
1689228072Sbapt				("static yy_state_type yy_last_accepting_state;");
1690228072Sbapt			indent_puts
1691228072Sbapt				("static char *yy_last_accepting_cpos;\n");
1692228072Sbapt		}
1693228072Sbapt	}
1694228072Sbapt
1695228072Sbapt	if (nultrans) {
1696228072Sbapt		flex_int32_t *yynultrans_data = 0;
1697228072Sbapt
1698228072Sbapt		/* Begin generating yy_NUL_trans */
1699228072Sbapt		out_str_dec (get_state_decl (), "yy_NUL_trans",
1700228072Sbapt			     lastdfa + 1);
1701228072Sbapt		buf_prints (&yydmap_buf,
1702228072Sbapt			    "\t{YYTD_ID_NUL_TRANS, (void**)&yy_NUL_trans, sizeof(%s)},\n",
1703228072Sbapt			    (fullspd) ? "struct yy_trans_info*" :
1704228072Sbapt			    "flex_int32_t");
1705228072Sbapt
1706228072Sbapt		yynultrans_tbl =
1707228072Sbapt			(struct yytbl_data *) calloc (1,
1708228072Sbapt						      sizeof (struct
1709228072Sbapt							      yytbl_data));
1710228072Sbapt		yytbl_data_init (yynultrans_tbl, YYTD_ID_NUL_TRANS);
1711228072Sbapt		if (fullspd)
1712228072Sbapt			yynultrans_tbl->td_flags |= YYTD_PTRANS;
1713228072Sbapt		yynultrans_tbl->td_lolen = lastdfa + 1;
1714228072Sbapt		yynultrans_tbl->td_data = yynultrans_data =
1715228072Sbapt			(flex_int32_t *) calloc (yynultrans_tbl->td_lolen,
1716228072Sbapt					    sizeof (flex_int32_t));
1717228072Sbapt
1718228072Sbapt		for (i = 1; i <= lastdfa; ++i) {
1719228072Sbapt			if (fullspd) {
1720228072Sbapt				out_dec ("    &yy_transition[%d],\n",
1721228072Sbapt					 base[i]);
1722228072Sbapt				yynultrans_data[i] = base[i];
1723228072Sbapt			}
1724228072Sbapt			else {
1725228072Sbapt				mkdata (nultrans[i]);
1726228072Sbapt				yynultrans_data[i] = nultrans[i];
1727228072Sbapt			}
1728228072Sbapt		}
1729228072Sbapt
1730228072Sbapt		dataend ();
1731228072Sbapt		if (tablesext) {
1732228072Sbapt			yytbl_data_compress (yynultrans_tbl);
1733228072Sbapt			if (yytbl_data_fwrite (&tableswr, yynultrans_tbl) <
1734228072Sbapt			    0)
1735228072Sbapt				flexerror (_
1736228072Sbapt					   ("Could not write yynultrans_tbl"));
1737228072Sbapt			yytbl_data_destroy (yynultrans_tbl);
1738228072Sbapt			yynultrans_tbl = NULL;
1739228072Sbapt		}
1740228072Sbapt		/* End generating yy_NUL_trans */
1741228072Sbapt	}
1742228072Sbapt
1743228072Sbapt	if (!C_plus_plus && !reentrant) {
1744228072Sbapt		indent_puts ("extern int yy_flex_debug;");
1745228072Sbapt		indent_put2s ("int yy_flex_debug = %s;\n",
1746228072Sbapt			      ddebug ? "1" : "0");
1747228072Sbapt	}
1748228072Sbapt
1749228072Sbapt	if (ddebug) {		/* Spit out table mapping rules to line numbers. */
1750228072Sbapt		out_str_dec (long_align ? get_int32_decl () :
1751228072Sbapt			     get_int16_decl (), "yy_rule_linenum",
1752228072Sbapt			     num_rules);
1753228072Sbapt		for (i = 1; i < num_rules; ++i)
1754228072Sbapt			mkdata (rule_linenum[i]);
1755228072Sbapt		dataend ();
1756228072Sbapt	}
1757228072Sbapt
1758228072Sbapt	if (reject) {
1759228072Sbapt		outn ("m4_ifdef( [[M4_YY_USES_REJECT]],\n[[");
1760228072Sbapt		/* Declare state buffer variables. */
1761228072Sbapt		if (!C_plus_plus && !reentrant) {
1762228072Sbapt			outn ("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;");
1763228072Sbapt			outn ("static char *yy_full_match;");
1764228072Sbapt			outn ("static int yy_lp;");
1765228072Sbapt		}
1766228072Sbapt
1767228072Sbapt		if (variable_trailing_context_rules) {
1768228072Sbapt			if (!C_plus_plus && !reentrant) {
1769228072Sbapt				outn ("static int yy_looking_for_trail_begin = 0;");
1770228072Sbapt				outn ("static int yy_full_lp;");
1771228072Sbapt				outn ("static int *yy_full_state;");
1772228072Sbapt			}
1773228072Sbapt
1774228072Sbapt			out_hex ("#define YY_TRAILING_MASK 0x%x\n",
1775228072Sbapt				 (unsigned int) YY_TRAILING_MASK);
1776228072Sbapt			out_hex ("#define YY_TRAILING_HEAD_MASK 0x%x\n",
1777228072Sbapt				 (unsigned int) YY_TRAILING_HEAD_MASK);
1778228072Sbapt		}
1779228072Sbapt
1780228072Sbapt		outn ("#define REJECT \\");
1781228072Sbapt		outn ("{ \\");
1782228072Sbapt		outn ("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */ \\");
1783228072Sbapt		outn ("yy_cp = YY_G(yy_full_match); /* restore poss. backed-over text */ \\");
1784228072Sbapt
1785228072Sbapt		if (variable_trailing_context_rules) {
1786228072Sbapt			outn ("YY_G(yy_lp) = YY_G(yy_full_lp); /* restore orig. accepting pos. */ \\");
1787228072Sbapt			outn ("YY_G(yy_state_ptr) = YY_G(yy_full_state); /* restore orig. state */ \\");
1788228072Sbapt			outn ("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\");
1789228072Sbapt		}
1790228072Sbapt
1791228072Sbapt		outn ("++YY_G(yy_lp); \\");
1792228072Sbapt		outn ("goto find_rule; \\");
1793228072Sbapt
1794228072Sbapt		outn ("}");
1795228072Sbapt		outn ("]])\n");
1796228072Sbapt	}
1797228072Sbapt
1798228072Sbapt	else {
1799228072Sbapt		outn ("/* The intent behind this definition is that it'll catch");
1800228072Sbapt		outn (" * any uses of REJECT which flex missed.");
1801228072Sbapt		outn (" */");
1802228072Sbapt		outn ("#define REJECT reject_used_but_not_detected");
1803228072Sbapt	}
1804228072Sbapt
1805228072Sbapt	if (yymore_used) {
1806228072Sbapt		if (!C_plus_plus) {
1807228072Sbapt			if (yytext_is_array) {
1808228072Sbapt				if (!reentrant){
1809228072Sbapt    				indent_puts ("static int yy_more_offset = 0;");
1810228072Sbapt                    indent_puts ("static int yy_prev_more_offset = 0;");
1811228072Sbapt                }
1812228072Sbapt			}
1813228072Sbapt			else if (!reentrant) {
1814228072Sbapt				indent_puts
1815228072Sbapt					("static int yy_more_flag = 0;");
1816228072Sbapt				indent_puts
1817228072Sbapt					("static int yy_more_len = 0;");
1818228072Sbapt			}
1819228072Sbapt		}
1820228072Sbapt
1821228072Sbapt		if (yytext_is_array) {
1822228072Sbapt			indent_puts
1823228072Sbapt				("#define yymore() (YY_G(yy_more_offset) = yy_flex_strlen( yytext M4_YY_CALL_LAST_ARG))");
1824228072Sbapt			indent_puts ("#define YY_NEED_STRLEN");
1825228072Sbapt			indent_puts ("#define YY_MORE_ADJ 0");
1826228072Sbapt			indent_puts
1827228072Sbapt				("#define YY_RESTORE_YY_MORE_OFFSET \\");
1828228072Sbapt			indent_up ();
1829228072Sbapt			indent_puts ("{ \\");
1830228072Sbapt			indent_puts
1831228072Sbapt				("YY_G(yy_more_offset) = YY_G(yy_prev_more_offset); \\");
1832228072Sbapt			indent_puts ("yyleng -= YY_G(yy_more_offset); \\");
1833228072Sbapt			indent_puts ("}");
1834228072Sbapt			indent_down ();
1835228072Sbapt		}
1836228072Sbapt		else {
1837228072Sbapt			indent_puts
1838228072Sbapt				("#define yymore() (YY_G(yy_more_flag) = 1)");
1839228072Sbapt			indent_puts
1840228072Sbapt				("#define YY_MORE_ADJ YY_G(yy_more_len)");
1841228072Sbapt			indent_puts ("#define YY_RESTORE_YY_MORE_OFFSET");
1842228072Sbapt		}
1843228072Sbapt	}
1844228072Sbapt
1845228072Sbapt	else {
1846228072Sbapt		indent_puts
1847228072Sbapt			("#define yymore() yymore_used_but_not_detected");
1848228072Sbapt		indent_puts ("#define YY_MORE_ADJ 0");
1849228072Sbapt		indent_puts ("#define YY_RESTORE_YY_MORE_OFFSET");
1850228072Sbapt	}
1851228072Sbapt
1852228072Sbapt	if (!C_plus_plus) {
1853228072Sbapt		if (yytext_is_array) {
1854228072Sbapt			outn ("#ifndef YYLMAX");
1855228072Sbapt			outn ("#define YYLMAX 8192");
1856228072Sbapt			outn ("#endif\n");
1857228072Sbapt			if (!reentrant){
1858228072Sbapt                outn ("char yytext[YYLMAX];");
1859228072Sbapt                outn ("char *yytext_ptr;");
1860228072Sbapt            }
1861228072Sbapt		}
1862228072Sbapt
1863228072Sbapt		else {
1864228072Sbapt			if(! reentrant)
1865228072Sbapt                outn ("char *yytext;");
1866228072Sbapt		}
1867228072Sbapt	}
1868228072Sbapt
1869228072Sbapt	out (&action_array[defs1_offset]);
1870228072Sbapt
1871228072Sbapt	line_directive_out (stdout, 0);
1872228072Sbapt
1873228072Sbapt	skelout ();		/* %% [5.0] - break point in skel */
1874228072Sbapt
1875228072Sbapt	if (!C_plus_plus) {
1876228072Sbapt		if (use_read) {
1877228072Sbapt			outn ("\terrno=0; \\");
1878228072Sbapt			outn ("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\");
1879228072Sbapt			outn ("\t{ \\");
1880228072Sbapt			outn ("\t\tif( errno != EINTR) \\");
1881228072Sbapt			outn ("\t\t{ \\");
1882228072Sbapt			outn ("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
1883228072Sbapt			outn ("\t\t\tbreak; \\");
1884228072Sbapt			outn ("\t\t} \\");
1885228072Sbapt			outn ("\t\terrno=0; \\");
1886228072Sbapt			outn ("\t\tclearerr(yyin); \\");
1887228072Sbapt			outn ("\t}\\");
1888228072Sbapt		}
1889228072Sbapt
1890228072Sbapt		else {
1891228072Sbapt			outn ("\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\");
1892228072Sbapt			outn ("\t\t{ \\");
1893228072Sbapt			outn ("\t\tint c = '*'; \\");
1894250125Sjkim			outn ("\t\tsize_t n; \\");
1895228072Sbapt			outn ("\t\tfor ( n = 0; n < max_size && \\");
1896228072Sbapt			outn ("\t\t\t     (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\");
1897228072Sbapt			outn ("\t\t\tbuf[n] = (char) c; \\");
1898228072Sbapt			outn ("\t\tif ( c == '\\n' ) \\");
1899228072Sbapt			outn ("\t\t\tbuf[n++] = (char) c; \\");
1900228072Sbapt			outn ("\t\tif ( c == EOF && ferror( yyin ) ) \\");
1901228072Sbapt			outn ("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
1902228072Sbapt			outn ("\t\tresult = n; \\");
1903228072Sbapt			outn ("\t\t} \\");
1904228072Sbapt			outn ("\telse \\");
1905228072Sbapt			outn ("\t\t{ \\");
1906228072Sbapt			outn ("\t\terrno=0; \\");
1907228072Sbapt			outn ("\t\twhile ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\");
1908228072Sbapt			outn ("\t\t\t{ \\");
1909228072Sbapt			outn ("\t\t\tif( errno != EINTR) \\");
1910228072Sbapt			outn ("\t\t\t\t{ \\");
1911228072Sbapt			outn ("\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
1912228072Sbapt			outn ("\t\t\t\tbreak; \\");
1913228072Sbapt			outn ("\t\t\t\t} \\");
1914228072Sbapt			outn ("\t\t\terrno=0; \\");
1915228072Sbapt			outn ("\t\t\tclearerr(yyin); \\");
1916228072Sbapt			outn ("\t\t\t} \\");
1917228072Sbapt			outn ("\t\t}\\");
1918228072Sbapt		}
1919228072Sbapt	}
1920228072Sbapt
1921228072Sbapt	skelout ();		/* %% [6.0] - break point in skel */
1922228072Sbapt
1923228072Sbapt	indent_puts ("#define YY_RULE_SETUP \\");
1924228072Sbapt	indent_up ();
1925228072Sbapt	if (bol_needed) {
1926228072Sbapt		indent_puts ("if ( yyleng > 0 ) \\");
1927228072Sbapt		indent_up ();
1928228072Sbapt		indent_puts ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \\");
1929228072Sbapt		indent_puts ("\t\t(yytext[yyleng - 1] == '\\n'); \\");
1930228072Sbapt		indent_down ();
1931228072Sbapt	}
1932228072Sbapt	indent_puts ("YY_USER_ACTION");
1933228072Sbapt	indent_down ();
1934228072Sbapt
1935228072Sbapt	skelout ();		/* %% [7.0] - break point in skel */
1936228072Sbapt
1937228072Sbapt	/* Copy prolog to output file. */
1938228072Sbapt	out (&action_array[prolog_offset]);
1939228072Sbapt
1940228072Sbapt	line_directive_out (stdout, 0);
1941228072Sbapt
1942228072Sbapt	skelout ();		/* %% [8.0] - break point in skel */
1943228072Sbapt
1944228072Sbapt	set_indent (2);
1945228072Sbapt
1946228072Sbapt	if (yymore_used && !yytext_is_array) {
1947228072Sbapt		indent_puts ("YY_G(yy_more_len) = 0;");
1948228072Sbapt		indent_puts ("if ( YY_G(yy_more_flag) )");
1949228072Sbapt		indent_up ();
1950228072Sbapt		indent_puts ("{");
1951228072Sbapt		indent_puts
1952228072Sbapt			("YY_G(yy_more_len) = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);");
1953228072Sbapt		indent_puts ("YY_G(yy_more_flag) = 0;");
1954228072Sbapt		indent_puts ("}");
1955228072Sbapt		indent_down ();
1956228072Sbapt	}
1957228072Sbapt
1958228072Sbapt	skelout ();		/* %% [9.0] - break point in skel */
1959228072Sbapt
1960228072Sbapt	gen_start_state ();
1961228072Sbapt
1962228072Sbapt	/* Note, don't use any indentation. */
1963228072Sbapt	outn ("yy_match:");
1964228072Sbapt	gen_next_match ();
1965228072Sbapt
1966228072Sbapt	skelout ();		/* %% [10.0] - break point in skel */
1967228072Sbapt	set_indent (2);
1968228072Sbapt	gen_find_action ();
1969228072Sbapt
1970228072Sbapt	skelout ();		/* %% [11.0] - break point in skel */
1971228072Sbapt	outn ("m4_ifdef( [[M4_YY_USE_LINENO]],[[");
1972228072Sbapt	indent_puts
1973228072Sbapt		("if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )");
1974228072Sbapt	indent_up ();
1975228072Sbapt	indent_puts ("{");
1976250128Sjkim	indent_puts ("yy_size_t yyl;");
1977228072Sbapt	do_indent ();
1978228072Sbapt	out_str ("for ( yyl = %s; yyl < yyleng; ++yyl )\n",
1979228072Sbapt		 yymore_used ? (yytext_is_array ? "YY_G(yy_prev_more_offset)" :
1980228072Sbapt				"YY_G(yy_more_len)") : "0");
1981228072Sbapt	indent_up ();
1982228072Sbapt	indent_puts ("if ( yytext[yyl] == '\\n' )");
1983228072Sbapt	indent_up ();
1984228072Sbapt	indent_puts ("M4_YY_INCR_LINENO();");
1985228072Sbapt	indent_down ();
1986228072Sbapt	indent_down ();
1987228072Sbapt	indent_puts ("}");
1988228072Sbapt	indent_down ();
1989228072Sbapt	outn ("]])");
1990228072Sbapt
1991228072Sbapt	skelout ();		/* %% [12.0] - break point in skel */
1992228072Sbapt	if (ddebug) {
1993228072Sbapt		indent_puts ("if ( yy_flex_debug )");
1994228072Sbapt		indent_up ();
1995228072Sbapt
1996228072Sbapt		indent_puts ("{");
1997228072Sbapt		indent_puts ("if ( yy_act == 0 )");
1998228072Sbapt		indent_up ();
1999228072Sbapt		indent_puts (C_plus_plus ?
2000228072Sbapt			     "std::cerr << \"--scanner backing up\\n\";" :
2001228072Sbapt			     "fprintf( stderr, \"--scanner backing up\\n\" );");
2002228072Sbapt		indent_down ();
2003228072Sbapt
2004228072Sbapt		do_indent ();
2005228072Sbapt		out_dec ("else if ( yy_act < %d )\n", num_rules);
2006228072Sbapt		indent_up ();
2007228072Sbapt
2008228072Sbapt		if (C_plus_plus) {
2009228072Sbapt			indent_puts
2010228072Sbapt				("std::cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<");
2011228072Sbapt			indent_puts
2012228072Sbapt				("         \"(\\\"\" << yytext << \"\\\")\\n\";");
2013228072Sbapt		}
2014228072Sbapt		else {
2015228072Sbapt			indent_puts
2016228072Sbapt				("fprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\",");
2017228072Sbapt
2018228072Sbapt			indent_puts
2019228072Sbapt				("         (long)yy_rule_linenum[yy_act], yytext );");
2020228072Sbapt		}
2021228072Sbapt
2022228072Sbapt		indent_down ();
2023228072Sbapt
2024228072Sbapt		do_indent ();
2025228072Sbapt		out_dec ("else if ( yy_act == %d )\n", num_rules);
2026228072Sbapt		indent_up ();
2027228072Sbapt
2028228072Sbapt		if (C_plus_plus) {
2029228072Sbapt			indent_puts
2030228072Sbapt				("std::cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";");
2031228072Sbapt		}
2032228072Sbapt		else {
2033228072Sbapt			indent_puts
2034228072Sbapt				("fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\",");
2035228072Sbapt			indent_puts ("         yytext );");
2036228072Sbapt		}
2037228072Sbapt
2038228072Sbapt		indent_down ();
2039228072Sbapt
2040228072Sbapt		do_indent ();
2041228072Sbapt		out_dec ("else if ( yy_act == %d )\n", num_rules + 1);
2042228072Sbapt		indent_up ();
2043228072Sbapt
2044228072Sbapt		indent_puts (C_plus_plus ?
2045228072Sbapt			     "std::cerr << \"--(end of buffer or a NUL)\\n\";" :
2046228072Sbapt			     "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );");
2047228072Sbapt
2048228072Sbapt		indent_down ();
2049228072Sbapt
2050228072Sbapt		do_indent ();
2051228072Sbapt		outn ("else");
2052228072Sbapt		indent_up ();
2053228072Sbapt
2054228072Sbapt		if (C_plus_plus) {
2055228072Sbapt			indent_puts
2056228072Sbapt				("std::cerr << \"--EOF (start condition \" << YY_START << \")\\n\";");
2057228072Sbapt		}
2058228072Sbapt		else {
2059228072Sbapt			indent_puts
2060228072Sbapt				("fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );");
2061228072Sbapt		}
2062228072Sbapt
2063228072Sbapt		indent_down ();
2064228072Sbapt
2065228072Sbapt		indent_puts ("}");
2066228072Sbapt		indent_down ();
2067228072Sbapt	}
2068228072Sbapt
2069228072Sbapt	/* Copy actions to output file. */
2070228072Sbapt	skelout ();		/* %% [13.0] - break point in skel */
2071228072Sbapt	indent_up ();
2072228072Sbapt	gen_bu_action ();
2073228072Sbapt	out (&action_array[action_offset]);
2074228072Sbapt
2075228072Sbapt	line_directive_out (stdout, 0);
2076228072Sbapt
2077228072Sbapt	/* generate cases for any missing EOF rules */
2078228072Sbapt	for (i = 1; i <= lastsc; ++i)
2079228072Sbapt		if (!sceof[i]) {
2080228072Sbapt			do_indent ();
2081228072Sbapt			out_str ("case YY_STATE_EOF(%s):\n", scname[i]);
2082228072Sbapt			did_eof_rule = true;
2083228072Sbapt		}
2084228072Sbapt
2085228072Sbapt	if (did_eof_rule) {
2086228072Sbapt		indent_up ();
2087228072Sbapt		indent_puts ("yyterminate();");
2088228072Sbapt		indent_down ();
2089228072Sbapt	}
2090228072Sbapt
2091228072Sbapt
2092228072Sbapt	/* Generate code for handling NUL's, if needed. */
2093228072Sbapt
2094228072Sbapt	/* First, deal with backing up and setting up yy_cp if the scanner
2095228072Sbapt	 * finds that it should JAM on the NUL.
2096228072Sbapt	 */
2097228072Sbapt	skelout ();		/* %% [14.0] - break point in skel */
2098228072Sbapt	set_indent (4);
2099228072Sbapt
2100228072Sbapt	if (fullspd || fulltbl)
2101228072Sbapt		indent_puts ("yy_cp = YY_G(yy_c_buf_p);");
2102228072Sbapt
2103228072Sbapt	else {			/* compressed table */
2104228072Sbapt		if (!reject && !interactive) {
2105228072Sbapt			/* Do the guaranteed-needed backing up to figure
2106228072Sbapt			 * out the match.
2107228072Sbapt			 */
2108228072Sbapt			indent_puts
2109228072Sbapt				("yy_cp = YY_G(yy_last_accepting_cpos);");
2110228072Sbapt			indent_puts
2111228072Sbapt				("yy_current_state = YY_G(yy_last_accepting_state);");
2112228072Sbapt		}
2113228072Sbapt
2114228072Sbapt		else
2115228072Sbapt			/* Still need to initialize yy_cp, though
2116228072Sbapt			 * yy_current_state was set up by
2117228072Sbapt			 * yy_get_previous_state().
2118228072Sbapt			 */
2119228072Sbapt			indent_puts ("yy_cp = YY_G(yy_c_buf_p);");
2120228072Sbapt	}
2121228072Sbapt
2122228072Sbapt
2123228072Sbapt	/* Generate code for yy_get_previous_state(). */
2124228072Sbapt	set_indent (1);
2125228072Sbapt	skelout ();		/* %% [15.0] - break point in skel */
2126228072Sbapt
2127228072Sbapt	gen_start_state ();
2128228072Sbapt
2129228072Sbapt	set_indent (2);
2130228072Sbapt	skelout ();		/* %% [16.0] - break point in skel */
2131228072Sbapt	gen_next_state (true);
2132228072Sbapt
2133228072Sbapt	set_indent (1);
2134228072Sbapt	skelout ();		/* %% [17.0] - break point in skel */
2135228072Sbapt	gen_NUL_trans ();
2136228072Sbapt
2137228072Sbapt	skelout ();		/* %% [18.0] - break point in skel */
2138228072Sbapt	skelout ();		/* %% [19.0] - break point in skel */
2139228072Sbapt	/* Update BOL and yylineno inside of input(). */
2140228072Sbapt	if (bol_needed) {
2141228072Sbapt		indent_puts
2142228072Sbapt			("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\\n');");
2143228072Sbapt		if (do_yylineno) {
2144228072Sbapt			indent_puts
2145228072Sbapt				("if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )");
2146228072Sbapt			indent_up ();
2147228072Sbapt			indent_puts ("M4_YY_INCR_LINENO();");
2148228072Sbapt			indent_down ();
2149228072Sbapt		}
2150228072Sbapt	}
2151228072Sbapt
2152228072Sbapt	else if (do_yylineno) {
2153228072Sbapt		indent_puts ("if ( c == '\\n' )");
2154228072Sbapt		indent_up ();
2155228072Sbapt		indent_puts ("M4_YY_INCR_LINENO();");
2156228072Sbapt		indent_down ();
2157228072Sbapt	}
2158228072Sbapt
2159228072Sbapt	skelout ();
2160228072Sbapt
2161228072Sbapt	/* Copy remainder of input to output. */
2162228072Sbapt
2163228072Sbapt	line_directive_out (stdout, 1);
2164228072Sbapt
2165228072Sbapt	if (sectnum == 3) {
2166228072Sbapt		OUT_BEGIN_CODE ();
2167228072Sbapt		(void) flexscan ();	/* copy remainder of input to output */
2168228072Sbapt		OUT_END_CODE ();
2169228072Sbapt	}
2170228072Sbapt}
2171