1/*	$OpenBSD: gen.c,v 1.15 2015/11/19 23:28:03 tedu Exp $	*/
2
3/* gen - actual generation (writing) of flex scanners */
4
5/*  Copyright (c) 1990 The Regents of the University of California. */
6/*  All rights reserved. */
7
8/*  This code is derived from software contributed to Berkeley by */
9/*  Vern Paxson. */
10
11/*  The United States Government has rights in this work pursuant */
12/*  to contract no. DE-AC03-76SF00098 between the United States */
13/*  Department of Energy and the University of California. */
14
15/*  This file is part of flex. */
16
17/*  Redistribution and use in source and binary forms, with or without */
18/*  modification, are permitted provided that the following conditions */
19/*  are met: */
20
21/*  1. Redistributions of source code must retain the above copyright */
22/*     notice, this list of conditions and the following disclaimer. */
23/*  2. Redistributions in binary form must reproduce the above copyright */
24/*     notice, this list of conditions and the following disclaimer in the */
25/*     documentation and/or other materials provided with the distribution. */
26
27/*  Neither the name of the University nor the names of its contributors */
28/*  may be used to endorse or promote products derived from this software */
29/*  without specific prior written permission. */
30
31/*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
32/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
33/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
34/*  PURPOSE. */
35
36#include "flexdef.h"
37#include "tables.h"
38
39
40/* declare functions that have forward references */
41
42void gen_next_state PROTO((int));
43void genecs PROTO((void));
44void indent_put2s PROTO((const char *, const char *));
45void indent_puts PROTO((const char *));
46
47
48static int indent_level = 0;	/* each level is 8 spaces */
49
50#define indent_up() (++indent_level)
51#define indent_down() (--indent_level)
52#define set_indent(indent_val) indent_level = indent_val
53
54/* Almost everything is done in terms of arrays starting at 1, so provide
55 * a null entry for the zero element of all C arrays.  (The exception
56 * to this is that the fast table representation generally uses the
57 * 0 elements of its arrays, too.)
58 */
59
60static const char *
61get_int16_decl(void)
62{
63	return (gentables)
64	? "static yyconst flex_int16_t %s[%d] =\n    {   0,\n"
65	: "static yyconst flex_int16_t * %s = 0;\n";
66}
67
68
69static const char *
70get_int32_decl(void)
71{
72	return (gentables)
73	? "static yyconst flex_int32_t %s[%d] =\n    {   0,\n"
74	: "static yyconst flex_int32_t * %s = 0;\n";
75}
76
77static const char *
78get_state_decl(void)
79{
80	return (gentables)
81	? "static yyconst yy_state_type %s[%d] =\n    {   0,\n"
82	: "static yyconst yy_state_type * %s = 0;\n";
83}
84
85/* Indent to the current level. */
86
87void
88do_indent()
89{
90	int i = indent_level * 8;
91
92	while (i >= 8) {
93		outc('\t');
94		i -= 8;
95	}
96
97	while (i > 0) {
98		outc(' ');
99		--i;
100	}
101}
102
103
104/** Make the table for possible eol matches.
105 *  @return the newly allocated rule_can_match_eol table
106 */
107static struct yytbl_data *
108mkeoltbl(void)
109{
110	int i;
111	flex_int8_t *tdata = NULL;
112	struct yytbl_data *tbl;
113
114	tbl = calloc(1, sizeof(struct yytbl_data));
115	yytbl_data_init(tbl, YYTD_ID_RULE_CAN_MATCH_EOL);
116	tbl->td_flags = YYTD_DATA8;
117	tbl->td_lolen = num_rules + 1;
118	tbl->td_data = tdata =
119	    calloc(tbl->td_lolen, sizeof(flex_int8_t));
120
121	for (i = 1; i <= num_rules; i++)
122		tdata[i] = rule_has_nl[i] ? 1 : 0;
123
124	buf_prints(&yydmap_buf,
125	    "\t{YYTD_ID_RULE_CAN_MATCH_EOL, (void**)&yy_rule_can_match_eol, sizeof(%s)},\n",
126	    "flex_int32_t");
127	return tbl;
128}
129
130/* Generate the table for possible eol matches. */
131static void
132geneoltbl()
133{
134	int i;
135
136	outn("m4_ifdef( [[M4_YY_USE_LINENO]],[[");
137	outn("/* Table of booleans, true if rule could match eol. */");
138	out_str_dec(get_int32_decl(), "yy_rule_can_match_eol",
139	    num_rules + 1);
140
141	if (gentables) {
142		for (i = 1; i <= num_rules; i++) {
143			out_dec("%d, ", rule_has_nl[i] ? 1 : 0);
144			/* format nicely, 20 numbers per line. */
145			if ((i % 20) == 19)
146				out("\n    ");
147		}
148		out("    };\n");
149	}
150	outn("]])");
151}
152
153
154/* Generate the code to keep backing-up information. */
155
156void
157gen_backing_up()
158{
159	if (reject || num_backing_up == 0)
160		return;
161
162	if (fullspd)
163		indent_puts("if ( yy_current_state[-1].yy_nxt )");
164	else
165		indent_puts("if ( yy_accept[yy_current_state] )");
166
167	indent_up();
168	indent_puts("{");
169	indent_puts("YY_G(yy_last_accepting_state) = yy_current_state;");
170	indent_puts("YY_G(yy_last_accepting_cpos) = yy_cp;");
171	indent_puts("}");
172	indent_down();
173}
174
175
176/* Generate the code to perform the backing up. */
177
178void
179gen_bu_action()
180{
181	if (reject || num_backing_up == 0)
182		return;
183
184	set_indent(3);
185
186	indent_puts("case 0: /* must back up */");
187	indent_puts("/* undo the effects of YY_DO_BEFORE_ACTION */");
188	indent_puts("*yy_cp = YY_G(yy_hold_char);");
189
190	if (fullspd || fulltbl)
191		indent_puts("yy_cp = YY_G(yy_last_accepting_cpos) + 1;");
192	else
193		/*
194		 * Backing-up info for compressed tables is taken \after/
195		 * yy_cp has been incremented for the next state.
196		 */
197		indent_puts("yy_cp = YY_G(yy_last_accepting_cpos);");
198
199	indent_puts("yy_current_state = YY_G(yy_last_accepting_state);");
200	indent_puts("goto yy_find_action;");
201	outc('\n');
202
203	set_indent(0);
204}
205
206/** mkctbl - make full speed compressed transition table
207 * This is an array of structs; each struct a pair of integers.
208 * You should call mkssltbl() immediately after this.
209 * Then, I think, mkecstbl(). Arrrg.
210 * @return the newly allocated trans table
211 */
212
213static struct yytbl_data *
214mkctbl(void)
215{
216	int i;
217	struct yytbl_data *tbl = NULL;
218	flex_int32_t *tdata = NULL, curr = 0;
219	int end_of_buffer_action = num_rules + 1;
220
221	buf_prints(&yydmap_buf,
222	    "\t{YYTD_ID_TRANSITION, (void**)&yy_transition, sizeof(%s)},\n",
223	    ((tblend + numecs + 1) >= INT16_MAX
224		|| long_align) ? "flex_int32_t" : "flex_int16_t");
225
226	tbl = calloc(1, sizeof(struct yytbl_data));
227	yytbl_data_init(tbl, YYTD_ID_TRANSITION);
228	tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT;
229	tbl->td_hilen = 0;
230	tbl->td_lolen = tblend + numecs + 1;	/* number of structs */
231
232	tbl->td_data = tdata =
233	    calloc(tbl->td_lolen * 2, sizeof(flex_int32_t));
234
235	/*
236	 * We want the transition to be represented as the offset to the next
237	 * state, not the actual state number, which is what it currently is.
238	 * The offset is base[nxt[i]] - (base of current state)].  That's
239	 * just the difference between the starting points of the two
240	 * involved states (to - from).
241	 *
242	 * First, though, we need to find some way to put in our end-of-buffer
243	 * flags and states.  We do this by making a state with absolutely no
244	 * transitions.  We put it at the end of the table.
245	 */
246
247	/*
248	 * We need to have room in nxt/chk for two more slots: One for the
249	 * action and one for the end-of-buffer transition.  We now *assume*
250	 * that we're guaranteed the only character we'll try to index this
251	 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
252	 * there's room for jam entries for other characters.
253	 */
254
255	while (tblend + 2 >= current_max_xpairs)
256		expand_nxt_chk();
257
258	while (lastdfa + 1 >= current_max_dfas)
259		increase_max_dfas();
260
261	base[lastdfa + 1] = tblend + 2;
262	nxt[tblend + 1] = end_of_buffer_action;
263	chk[tblend + 1] = numecs + 1;
264	chk[tblend + 2] = 1;	/* anything but EOB */
265
266	/* So that "make test" won't show arb. differences. */
267	nxt[tblend + 2] = 0;
268
269	/*
270	 * Make sure every state has an end-of-buffer transition and an
271	 * action #.
272	 */
273	for (i = 0; i <= lastdfa; ++i) {
274		int anum = dfaacc[i].dfaacc_state;
275		int offset = base[i];
276
277		chk[offset] = EOB_POSITION;
278		chk[offset - 1] = ACTION_POSITION;
279		nxt[offset - 1] = anum;	/* action number */
280	}
281
282	for (i = 0; i <= tblend; ++i) {
283		if (chk[i] == EOB_POSITION) {
284			tdata[curr++] = 0;
285			tdata[curr++] = base[lastdfa + 1] - i;
286		} else if (chk[i] == ACTION_POSITION) {
287			tdata[curr++] = 0;
288			tdata[curr++] = nxt[i];
289		} else if (chk[i] > numecs || chk[i] == 0) {
290			tdata[curr++] = 0;
291			tdata[curr++] = 0;
292		} else {	/* verify, transition */
293
294			tdata[curr++] = chk[i];
295			tdata[curr++] = base[nxt[i]] - (i - chk[i]);
296		}
297	}
298
299
300	/* Here's the final, end-of-buffer state. */
301	tdata[curr++] = chk[tblend + 1];
302	tdata[curr++] = nxt[tblend + 1];
303
304	tdata[curr++] = chk[tblend + 2];
305	tdata[curr++] = nxt[tblend + 2];
306
307	return tbl;
308}
309
310
311/** Make start_state_list table.
312 *  @return the newly allocated start_state_list table
313 */
314static struct yytbl_data *
315mkssltbl(void)
316{
317	struct yytbl_data *tbl = NULL;
318	flex_int32_t *tdata = NULL;
319	flex_int32_t i;
320
321	tbl = calloc(1, sizeof(struct yytbl_data));
322	yytbl_data_init(tbl, YYTD_ID_START_STATE_LIST);
323	tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS;
324	tbl->td_hilen = 0;
325	tbl->td_lolen = lastsc * 2 + 1;
326
327	tbl->td_data = tdata =
328	    calloc(tbl->td_lolen, sizeof(flex_int32_t));
329
330	for (i = 0; i <= lastsc * 2; ++i)
331		tdata[i] = base[i];
332
333	buf_prints(&yydmap_buf,
334	    "\t{YYTD_ID_START_STATE_LIST, (void**)&yy_start_state_list, sizeof(%s)},\n",
335	    "struct yy_trans_info*");
336
337	return tbl;
338}
339
340
341
342/* genctbl - generates full speed compressed transition table */
343
344void
345genctbl()
346{
347	int i;
348	int end_of_buffer_action = num_rules + 1;
349
350	/* Table of verify for transition and offset to next state. */
351	if (gentables)
352		out_dec("static yyconst struct yy_trans_info yy_transition[%d] =\n    {\n", tblend + numecs + 1);
353	else
354		outn("static yyconst struct yy_trans_info *yy_transition = 0;");
355
356	/*
357	 * We want the transition to be represented as the offset to the next
358	 * state, not the actual state number, which is what it currently is.
359	 * The offset is base[nxt[i]] - (base of current state)].  That's
360	 * just the difference between the starting points of the two
361	 * involved states (to - from).
362	 *
363	 * First, though, we need to find some way to put in our end-of-buffer
364	 * flags and states.  We do this by making a state with absolutely no
365	 * transitions.  We put it at the end of the table.
366	 */
367
368	/*
369	 * We need to have room in nxt/chk for two more slots: One for the
370	 * action and one for the end-of-buffer transition.  We now *assume*
371	 * that we're guaranteed the only character we'll try to index this
372	 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
373	 * there's room for jam entries for other characters.
374	 */
375
376	while (tblend + 2 >= current_max_xpairs)
377		expand_nxt_chk();
378
379	while (lastdfa + 1 >= current_max_dfas)
380		increase_max_dfas();
381
382	base[lastdfa + 1] = tblend + 2;
383	nxt[tblend + 1] = end_of_buffer_action;
384	chk[tblend + 1] = numecs + 1;
385	chk[tblend + 2] = 1;	/* anything but EOB */
386
387	/* So that "make test" won't show arb. differences. */
388	nxt[tblend + 2] = 0;
389
390	/*
391	 * Make sure every state has an end-of-buffer transition and an
392	 * action #.
393	 */
394	for (i = 0; i <= lastdfa; ++i) {
395		int anum = dfaacc[i].dfaacc_state;
396		int offset = base[i];
397
398		chk[offset] = EOB_POSITION;
399		chk[offset - 1] = ACTION_POSITION;
400		nxt[offset - 1] = anum;	/* action number */
401	}
402
403	for (i = 0; i <= tblend; ++i) {
404		if (chk[i] == EOB_POSITION)
405			transition_struct_out(0, base[lastdfa + 1] - i);
406
407		else if (chk[i] == ACTION_POSITION)
408			transition_struct_out(0, nxt[i]);
409
410		else if (chk[i] > numecs || chk[i] == 0)
411			transition_struct_out(0, 0);	/* unused slot */
412
413		else		/* verify, transition */
414			transition_struct_out(chk[i],
415			    base[nxt[i]] - (i -
416				chk[i]));
417	}
418
419
420	/* Here's the final, end-of-buffer state. */
421	transition_struct_out(chk[tblend + 1], nxt[tblend + 1]);
422	transition_struct_out(chk[tblend + 2], nxt[tblend + 2]);
423
424	if (gentables)
425		outn("    };\n");
426
427	/* Table of pointers to start states. */
428	if (gentables)
429		out_dec("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1);
430	else
431		outn("static yyconst struct yy_trans_info **yy_start_state_list =0;");
432
433	if (gentables) {
434		outn("    {");
435
436		for (i = 0; i <= lastsc * 2; ++i)
437			out_dec("    &yy_transition[%d],\n", base[i]);
438
439		dataend();
440	}
441	if (useecs)
442		genecs();
443}
444
445
446/* mkecstbl - Make equivalence-class tables.  */
447
448struct yytbl_data *
449mkecstbl(void)
450{
451	int i;
452	struct yytbl_data *tbl = NULL;
453	flex_int32_t *tdata = NULL;
454
455	tbl = calloc(1, sizeof(struct yytbl_data));
456	yytbl_data_init(tbl, YYTD_ID_EC);
457	tbl->td_flags |= YYTD_DATA32;
458	tbl->td_hilen = 0;
459	tbl->td_lolen = csize;
460
461	tbl->td_data = tdata =
462	    calloc(tbl->td_lolen, sizeof(flex_int32_t));
463
464	for (i = 1; i < csize; ++i) {
465		ecgroup[i] = ABS(ecgroup[i]);
466		tdata[i] = ecgroup[i];
467	}
468
469	buf_prints(&yydmap_buf,
470	    "\t{YYTD_ID_EC, (void**)&yy_ec, sizeof(%s)},\n",
471	    "flex_int32_t");
472
473	return tbl;
474}
475
476/* Generate equivalence-class tables. */
477
478void
479genecs()
480{
481	int i, j;
482	int numrows;
483
484	out_str_dec(get_int32_decl(), "yy_ec", csize);
485
486	for (i = 1; i < csize; ++i) {
487		ecgroup[i] = ABS(ecgroup[i]);
488		mkdata(ecgroup[i]);
489	}
490
491	dataend();
492
493	if (trace) {
494		fputs(_("\n\nEquivalence Classes:\n\n"), stderr);
495
496		numrows = csize / 8;
497
498		for (j = 0; j < numrows; ++j) {
499			for (i = j; i < csize; i = i + numrows) {
500				fprintf(stderr, "%4s = %-2d",
501				    readable_form(i), ecgroup[i]);
502
503				putc(' ', stderr);
504			}
505
506			putc('\n', stderr);
507		}
508	}
509}
510
511
512/* Generate the code to find the action number. */
513
514void
515gen_find_action()
516{
517	if (fullspd)
518		indent_puts("yy_act = yy_current_state[-1].yy_nxt;");
519
520	else if (fulltbl)
521		indent_puts("yy_act = yy_accept[yy_current_state];");
522
523	else if (reject) {
524		indent_puts("yy_current_state = *--YY_G(yy_state_ptr);");
525		indent_puts("YY_G(yy_lp) = yy_accept[yy_current_state];");
526
527		outn("find_rule: /* we branch to this label when backing up */");
528
529		indent_puts
530		    ("for ( ; ; ) /* until we find what rule we matched */");
531
532		indent_up();
533
534		indent_puts("{");
535
536		indent_puts
537		    ("if ( YY_G(yy_lp) && YY_G(yy_lp) < yy_accept[yy_current_state + 1] )");
538		indent_up();
539		indent_puts("{");
540		indent_puts("yy_act = yy_acclist[YY_G(yy_lp)];");
541
542		if (variable_trailing_context_rules) {
543			indent_puts
544			    ("if ( yy_act & YY_TRAILING_HEAD_MASK ||");
545			indent_puts("     YY_G(yy_looking_for_trail_begin) )");
546			indent_up();
547			indent_puts("{");
548
549			indent_puts
550			    ("if ( yy_act == YY_G(yy_looking_for_trail_begin) )");
551			indent_up();
552			indent_puts("{");
553			indent_puts("YY_G(yy_looking_for_trail_begin) = 0;");
554			indent_puts("yy_act &= ~YY_TRAILING_HEAD_MASK;");
555			indent_puts("break;");
556			indent_puts("}");
557			indent_down();
558
559			indent_puts("}");
560			indent_down();
561
562			indent_puts
563			    ("else if ( yy_act & YY_TRAILING_MASK )");
564			indent_up();
565			indent_puts("{");
566			indent_puts
567			    ("YY_G(yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK;");
568			indent_puts
569			    ("YY_G(yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK;");
570
571			if (real_reject) {
572				/*
573				 * Remember matched text in case we back up
574				 * due to REJECT.
575				 */
576				indent_puts
577				    ("YY_G(yy_full_match) = yy_cp;");
578				indent_puts
579				    ("YY_G(yy_full_state) = YY_G(yy_state_ptr);");
580				indent_puts("YY_G(yy_full_lp) = YY_G(yy_lp);");
581			}
582			indent_puts("}");
583			indent_down();
584
585			indent_puts("else");
586			indent_up();
587			indent_puts("{");
588			indent_puts("YY_G(yy_full_match) = yy_cp;");
589			indent_puts
590			    ("YY_G(yy_full_state) = YY_G(yy_state_ptr);");
591			indent_puts("YY_G(yy_full_lp) = YY_G(yy_lp);");
592			indent_puts("break;");
593			indent_puts("}");
594			indent_down();
595
596			indent_puts("++YY_G(yy_lp);");
597			indent_puts("goto find_rule;");
598		} else {
599			/*
600			 * Remember matched text in case we back up due to
601			 * trailing context plus REJECT.
602			 */
603			indent_up();
604			indent_puts("{");
605			indent_puts("YY_G(yy_full_match) = yy_cp;");
606			indent_puts("break;");
607			indent_puts("}");
608			indent_down();
609		}
610
611		indent_puts("}");
612		indent_down();
613
614		indent_puts("--yy_cp;");
615
616		/*
617		 * We could consolidate the following two lines with those at
618		 * the beginning, but at the cost of complaints that we're
619		 * branching inside a loop.
620		 */
621		indent_puts("yy_current_state = *--YY_G(yy_state_ptr);");
622		indent_puts("YY_G(yy_lp) = yy_accept[yy_current_state];");
623
624		indent_puts("}");
625
626		indent_down();
627	} else {		/* compressed */
628		indent_puts("yy_act = yy_accept[yy_current_state];");
629
630		if (interactive && !reject) {
631			/*
632			 * Do the guaranteed-needed backing up to figure out
633			 * the match.
634			 */
635			indent_puts("if ( yy_act == 0 )");
636			indent_up();
637			indent_puts("{ /* have to back up */");
638			indent_puts
639			    ("yy_cp = YY_G(yy_last_accepting_cpos);");
640			indent_puts
641			    ("yy_current_state = YY_G(yy_last_accepting_state);");
642			indent_puts
643			    ("yy_act = yy_accept[yy_current_state];");
644			indent_puts("}");
645			indent_down();
646		}
647	}
648}
649
650/* mkftbl - make the full table and return the struct .
651 * you should call mkecstbl() after this.
652 */
653
654struct yytbl_data *
655mkftbl(void)
656{
657	int i;
658	int end_of_buffer_action = num_rules + 1;
659	struct yytbl_data *tbl;
660	flex_int32_t *tdata = NULL;
661
662	tbl = calloc(1, sizeof(struct yytbl_data));
663	yytbl_data_init(tbl, YYTD_ID_ACCEPT);
664	tbl->td_flags |= YYTD_DATA32;
665	tbl->td_hilen = 0;	/* it's a one-dimensional array */
666	tbl->td_lolen = lastdfa + 1;
667
668	tbl->td_data = tdata =
669	    calloc(tbl->td_lolen, sizeof(flex_int32_t));
670
671	dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
672
673	for (i = 1; i <= lastdfa; ++i) {
674		int anum = dfaacc[i].dfaacc_state;
675
676		tdata[i] = anum;
677
678		if (trace && anum)
679			fprintf(stderr, _("state # %d accepts: [%d]\n"),
680			    i, anum);
681	}
682
683	buf_prints(&yydmap_buf,
684	    "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n",
685	    long_align ? "flex_int32_t" : "flex_int16_t");
686	return tbl;
687}
688
689
690/* genftbl - generate full transition table */
691
692void
693genftbl()
694{
695	int i;
696	int end_of_buffer_action = num_rules + 1;
697
698	out_str_dec(long_align ? get_int32_decl() : get_int16_decl(),
699	    "yy_accept", lastdfa + 1);
700
701	dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
702
703	for (i = 1; i <= lastdfa; ++i) {
704		int anum = dfaacc[i].dfaacc_state;
705
706		mkdata(anum);
707
708		if (trace && anum)
709			fprintf(stderr, _("state # %d accepts: [%d]\n"),
710			    i, anum);
711	}
712
713	dataend();
714
715	if (useecs)
716		genecs();
717
718	/*
719	 * Don't have to dump the actual full table entries - they were
720	 * created on-the-fly.
721	 */
722}
723
724
725/* Generate the code to find the next compressed-table state. */
726
727void
728gen_next_compressed_state(char_map)
729	char *char_map;
730{
731	indent_put2s("YY_CHAR yy_c = %s;", char_map);
732
733	/*
734	 * Save the backing-up info \before/ computing the next state because
735	 * we always compute one more state than needed - we always proceed
736	 * until we reach a jam state
737	 */
738	gen_backing_up();
739
740	indent_puts
741	    ("while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )");
742	indent_up();
743	indent_puts("{");
744	indent_puts("yy_current_state = (int) yy_def[yy_current_state];");
745
746	if (usemecs) {
747		/*
748		 * We've arrange it so that templates are never chained to
749		 * one another.  This means we can afford to make a very
750		 * simple test to see if we need to convert to yy_c's
751		 * meta-equivalence class without worrying about erroneously
752		 * looking up the meta-equivalence class twice
753		 */
754		do_indent();
755
756		/* lastdfa + 2 is the beginning of the templates */
757		out_dec("if ( yy_current_state >= %d )\n", lastdfa + 2);
758
759		indent_up();
760		indent_puts("yy_c = yy_meta[(unsigned int) yy_c];");
761		indent_down();
762	}
763	indent_puts("}");
764	indent_down();
765
766	indent_puts
767	    ("yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];");
768}
769
770
771/* Generate the code to find the next match. */
772
773void
774gen_next_match()
775{
776	/*
777	 * NOTE - changes in here should be reflected in gen_next_state() and
778	 * gen_NUL_trans().
779	 */
780	char *char_map = useecs ?
781	"yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)";
782
783	char *char_map_2 = useecs ?
784	"yy_ec[YY_SC_TO_UI(*++yy_cp)] " : "YY_SC_TO_UI(*++yy_cp)";
785
786	if (fulltbl) {
787		if (gentables)
788			indent_put2s
789			    ("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )",
790			    char_map);
791		else
792			indent_put2s
793			    ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN +  %s ]) > 0 )",
794			    char_map);
795
796		indent_up();
797
798		if (num_backing_up > 0) {
799			indent_puts("{");
800			gen_backing_up();
801			outc('\n');
802		}
803		indent_puts("++yy_cp;");
804
805		if (num_backing_up > 0)
806			indent_puts("}");
807
808		indent_down();
809
810		outc('\n');
811		indent_puts("yy_current_state = -yy_current_state;");
812	} else if (fullspd) {
813		indent_puts("{");
814		indent_puts
815		    ("yyconst struct yy_trans_info *yy_trans_info;\n");
816		indent_puts("YY_CHAR yy_c;\n");
817		indent_put2s("for ( yy_c = %s;", char_map);
818		indent_puts
819		    ("      (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->");
820		indent_puts("yy_verify == yy_c;");
821		indent_put2s("      yy_c = %s )", char_map_2);
822
823		indent_up();
824
825		if (num_backing_up > 0)
826			indent_puts("{");
827
828		indent_puts("yy_current_state += yy_trans_info->yy_nxt;");
829
830		if (num_backing_up > 0) {
831			outc('\n');
832			gen_backing_up();
833			indent_puts("}");
834		}
835		indent_down();
836		indent_puts("}");
837	} else {		/* compressed */
838		indent_puts("do");
839
840		indent_up();
841		indent_puts("{");
842
843		gen_next_state(false);
844
845		indent_puts("++yy_cp;");
846
847
848		indent_puts("}");
849		indent_down();
850
851		do_indent();
852
853		if (interactive)
854			out_dec("while ( yy_base[yy_current_state] != %d );\n", jambase);
855		else
856			out_dec("while ( yy_current_state != %d );\n",
857			    jamstate);
858
859		if (!reject && !interactive) {
860			/*
861			 * Do the guaranteed-needed backing up to figure out
862			 * the match.
863			 */
864			indent_puts
865			    ("yy_cp = YY_G(yy_last_accepting_cpos);");
866			indent_puts
867			    ("yy_current_state = YY_G(yy_last_accepting_state);");
868		}
869	}
870}
871
872
873/* Generate the code to find the next state. */
874
875void
876gen_next_state(worry_about_NULs)
877	int worry_about_NULs;
878{				/* NOTE - changes in here should be reflected
879				 * in gen_next_match() */
880	char char_map[256];
881
882	if (worry_about_NULs && !nultrans) {
883		if (useecs)
884			snprintf(char_map, sizeof(char_map),
885			    "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)",
886			    NUL_ec);
887		else
888			snprintf(char_map, sizeof(char_map),
889			    "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)",
890			    NUL_ec);
891	} else
892		strlcpy(char_map, useecs ?
893		    "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)",
894		    sizeof char_map);
895
896	if (worry_about_NULs && nultrans) {
897		if (!fulltbl && !fullspd)
898			/* Compressed tables back up *before* they match. */
899			gen_backing_up();
900
901		indent_puts("if ( *yy_cp )");
902		indent_up();
903		indent_puts("{");
904	}
905	if (fulltbl) {
906		if (gentables)
907			indent_put2s
908			    ("yy_current_state = yy_nxt[yy_current_state][%s];",
909			    char_map);
910		else
911			indent_put2s
912			    ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s];",
913			    char_map);
914	} else if (fullspd)
915		indent_put2s
916		    ("yy_current_state += yy_current_state[%s].yy_nxt;",
917		    char_map);
918
919	else
920		gen_next_compressed_state(char_map);
921
922	if (worry_about_NULs && nultrans) {
923
924		indent_puts("}");
925		indent_down();
926		indent_puts("else");
927		indent_up();
928		indent_puts
929		    ("yy_current_state = yy_NUL_trans[yy_current_state];");
930		indent_down();
931	}
932	if (fullspd || fulltbl)
933		gen_backing_up();
934
935	if (reject)
936		indent_puts("*YY_G(yy_state_ptr)++ = yy_current_state;");
937}
938
939
940/* Generate the code to make a NUL transition. */
941
942void
943gen_NUL_trans()
944{				/* NOTE - changes in here should be reflected
945				 * in gen_next_match() */
946	/*
947	 * Only generate a definition for "yy_cp" if we'll generate code that
948	 * uses it.  Otherwise lint and the like complain.
949	 */
950	int need_backing_up = (num_backing_up > 0 && !reject);
951
952	if (need_backing_up && (!nultrans || fullspd || fulltbl))
953		/*
954		 * We're going to need yy_cp lying around for the call below
955		 * to gen_backing_up().
956		 */
957		indent_puts("char *yy_cp = YY_G(yy_c_buf_p);");
958
959	outc('\n');
960
961	if (nultrans) {
962		indent_puts
963		    ("yy_current_state = yy_NUL_trans[yy_current_state];");
964		indent_puts("yy_is_jam = (yy_current_state == 0);");
965	} else if (fulltbl) {
966		do_indent();
967		if (gentables)
968			out_dec("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec);
969		else
970			out_dec("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %d];\n", NUL_ec);
971		indent_puts("yy_is_jam = (yy_current_state <= 0);");
972	} else if (fullspd) {
973		do_indent();
974		out_dec("int yy_c = %d;\n", NUL_ec);
975
976		indent_puts
977		    ("yyconst struct yy_trans_info *yy_trans_info;\n");
978		indent_puts
979		    ("yy_trans_info = &yy_current_state[(unsigned int) yy_c];");
980		indent_puts("yy_current_state += yy_trans_info->yy_nxt;");
981
982		indent_puts
983		    ("yy_is_jam = (yy_trans_info->yy_verify != yy_c);");
984	} else {
985		char NUL_ec_str[20];
986
987		snprintf(NUL_ec_str, sizeof(NUL_ec_str), "%d", NUL_ec);
988		gen_next_compressed_state(NUL_ec_str);
989
990		do_indent();
991		out_dec("yy_is_jam = (yy_current_state == %d);\n",
992		    jamstate);
993
994		if (reject) {
995			/*
996			 * Only stack this state if it's a transition we
997			 * actually make.  If we stack it on a jam, then the
998			 * state stack and yy_c_buf_p get out of sync.
999			 */
1000			indent_puts("if ( ! yy_is_jam )");
1001			indent_up();
1002			indent_puts
1003			    ("*YY_G(yy_state_ptr)++ = yy_current_state;");
1004			indent_down();
1005		}
1006	}
1007
1008	/*
1009	 * If we've entered an accepting state, back up; note that compressed
1010	 * tables have *already* done such backing up, so we needn't bother
1011	 * with it again.
1012	 */
1013	if (need_backing_up && (fullspd || fulltbl)) {
1014		outc('\n');
1015		indent_puts("if ( ! yy_is_jam )");
1016		indent_up();
1017		indent_puts("{");
1018		gen_backing_up();
1019		indent_puts("}");
1020		indent_down();
1021	}
1022}
1023
1024
1025/* Generate the code to find the start state. */
1026
1027void
1028gen_start_state()
1029{
1030	if (fullspd) {
1031		if (bol_needed) {
1032			indent_puts
1033			("yy_current_state = yy_start_state_list[YY_G(yy_start) + YY_AT_BOL()];");
1034		} else
1035			indent_puts
1036			    ("yy_current_state = yy_start_state_list[YY_G(yy_start)];");
1037	} else {
1038		indent_puts("yy_current_state = YY_G(yy_start);");
1039
1040		if (bol_needed)
1041			indent_puts("yy_current_state += YY_AT_BOL();");
1042
1043		if (reject) {
1044			/* Set up for storing up states. */
1045			outn("m4_ifdef( [[M4_YY_USES_REJECT]],\n[[");
1046			indent_puts
1047			    ("YY_G(yy_state_ptr) = YY_G(yy_state_buf);");
1048			indent_puts
1049			    ("*YY_G(yy_state_ptr)++ = yy_current_state;");
1050			outn("]])");
1051		}
1052	}
1053}
1054
1055
1056/* gentabs - generate data statements for the transition tables */
1057
1058void
1059gentabs()
1060{
1061	int i, j, k, *accset, nacc, *acc_array, total_states;
1062	int end_of_buffer_action = num_rules + 1;
1063	struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0, *yydef_tbl = 0,
1064	*yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl = 0;
1065	flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0, *yynxt_data = 0,
1066	*yychk_data = 0, *yyacclist_data = 0;
1067	flex_int32_t yybase_curr = 0, yyacclist_curr = 0, yyacc_curr = 0;
1068
1069	acc_array = allocate_integer_array(current_max_dfas);
1070	nummt = 0;
1071
1072	/*
1073	 * The compressed table format jams by entering the "jam state",
1074	 * losing information about the previous state in the process. In
1075	 * order to recover the previous state, we effectively need to keep
1076	 * backing-up information.
1077	 */
1078	++num_backing_up;
1079
1080	if (reject) {
1081		/*
1082		 * Write out accepting list and pointer list.
1083		 *
1084		 * First we generate the "yy_acclist" array.  In the process, we
1085		 * compute the indices that will go into the "yy_accept"
1086		 * array, and save the indices in the dfaacc array.
1087		 */
1088		int EOB_accepting_list[2];
1089
1090		/* Set up accepting structures for the End Of Buffer state. */
1091		EOB_accepting_list[0] = 0;
1092		EOB_accepting_list[1] = end_of_buffer_action;
1093		accsiz[end_of_buffer_state] = 1;
1094		dfaacc[end_of_buffer_state].dfaacc_set =
1095		    EOB_accepting_list;
1096
1097		out_str_dec(long_align ? get_int32_decl() :
1098		    get_int16_decl(), "yy_acclist", MAX(numas,
1099			1) + 1);
1100
1101		buf_prints(&yydmap_buf,
1102		    "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n",
1103		    long_align ? "flex_int32_t" : "flex_int16_t");
1104
1105		yyacclist_tbl = calloc(1, sizeof(struct yytbl_data));
1106		yytbl_data_init(yyacclist_tbl, YYTD_ID_ACCLIST);
1107		yyacclist_tbl->td_lolen = MAX(numas, 1) + 1;
1108		yyacclist_tbl->td_data = yyacclist_data =
1109		    calloc(yyacclist_tbl->td_lolen, sizeof(flex_int32_t));
1110		yyacclist_curr = 1;
1111
1112		j = 1;		/* index into "yy_acclist" array */
1113
1114		for (i = 1; i <= lastdfa; ++i) {
1115			acc_array[i] = j;
1116
1117			if (accsiz[i] != 0) {
1118				accset = dfaacc[i].dfaacc_set;
1119				nacc = accsiz[i];
1120
1121				if (trace)
1122					fprintf(stderr,
1123					    _("state # %d accepts: "),
1124					    i);
1125
1126				for (k = 1; k <= nacc; ++k) {
1127					int accnum = accset[k];
1128
1129					++j;
1130
1131					if (variable_trailing_context_rules
1132					    && !(accnum &
1133						YY_TRAILING_HEAD_MASK)
1134					    && accnum > 0
1135					    && accnum <= num_rules
1136					    && rule_type[accnum] ==
1137					    RULE_VARIABLE) {
1138						/*
1139						 * Special hack to flag
1140						 * accepting number as part
1141						 * of trailing context rule.
1142						 */
1143						accnum |= YY_TRAILING_MASK;
1144					}
1145					mkdata(accnum);
1146					yyacclist_data[yyacclist_curr++] = accnum;
1147
1148					if (trace) {
1149						fprintf(stderr, "[%d]",
1150						    accset[k]);
1151
1152						if (k < nacc)
1153							fputs(", ",
1154							    stderr);
1155						else
1156							putc('\n',
1157							    stderr);
1158					}
1159				}
1160			}
1161		}
1162
1163		/* add accepting number for the "jam" state */
1164		acc_array[i] = j;
1165
1166		dataend();
1167		if (tablesext) {
1168			yytbl_data_compress(yyacclist_tbl);
1169			if (yytbl_data_fwrite(&tableswr, yyacclist_tbl) < 0)
1170				flexerror(_("Could not write yyacclist_tbl"));
1171			yytbl_data_destroy(yyacclist_tbl);
1172			yyacclist_tbl = NULL;
1173		}
1174	} else {
1175		dfaacc[end_of_buffer_state].dfaacc_state =
1176		    end_of_buffer_action;
1177
1178		for (i = 1; i <= lastdfa; ++i)
1179			acc_array[i] = dfaacc[i].dfaacc_state;
1180
1181		/* add accepting number for jam state */
1182		acc_array[i] = 0;
1183	}
1184
1185	/* Begin generating yy_accept */
1186
1187	/*
1188	 * Spit out "yy_accept" array.  If we're doing "reject", it'll be
1189	 * pointers into the "yy_acclist" array.  Otherwise it's actual
1190	 * accepting numbers.  In either case, we just dump the numbers.
1191	 */
1192
1193	/*
1194	 * "lastdfa + 2" is the size of "yy_accept"; includes room for C
1195	 * arrays beginning at 0 and for "jam" state.
1196	 */
1197	k = lastdfa + 2;
1198
1199	if (reject)
1200		/*
1201		 * We put a "cap" on the table associating lists of accepting
1202		 * numbers with state numbers.  This is needed because we
1203		 * tell where the end of an accepting list is by looking at
1204		 * where the list for the next state starts.
1205		 */
1206		++k;
1207
1208	out_str_dec(long_align ? get_int32_decl() : get_int16_decl(),
1209	    "yy_accept", k);
1210
1211	buf_prints(&yydmap_buf,
1212	    "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n",
1213	    long_align ? "flex_int32_t" : "flex_int16_t");
1214
1215	yyacc_tbl = calloc(1, sizeof(struct yytbl_data));
1216	yytbl_data_init(yyacc_tbl, YYTD_ID_ACCEPT);
1217	yyacc_tbl->td_lolen = k;
1218	yyacc_tbl->td_data = yyacc_data =
1219	    calloc(yyacc_tbl->td_lolen, sizeof(flex_int32_t));
1220	yyacc_curr = 1;
1221
1222	for (i = 1; i <= lastdfa; ++i) {
1223		mkdata(acc_array[i]);
1224		yyacc_data[yyacc_curr++] = acc_array[i];
1225
1226		if (!reject && trace && acc_array[i])
1227			fprintf(stderr, _("state # %d accepts: [%d]\n"),
1228			    i, acc_array[i]);
1229	}
1230
1231	/* Add entry for "jam" state. */
1232	mkdata(acc_array[i]);
1233	yyacc_data[yyacc_curr++] = acc_array[i];
1234
1235	if (reject) {
1236		/* Add "cap" for the list. */
1237		mkdata(acc_array[i]);
1238		yyacc_data[yyacc_curr++] = acc_array[i];
1239	}
1240	dataend();
1241	if (tablesext) {
1242		yytbl_data_compress(yyacc_tbl);
1243		if (yytbl_data_fwrite(&tableswr, yyacc_tbl) < 0)
1244			flexerror(_("Could not write yyacc_tbl"));
1245		yytbl_data_destroy(yyacc_tbl);
1246		yyacc_tbl = NULL;
1247	}
1248	/* End generating yy_accept */
1249
1250	if (useecs) {
1251
1252		genecs();
1253		if (tablesext) {
1254			struct yytbl_data *tbl;
1255
1256			tbl = mkecstbl();
1257			yytbl_data_compress(tbl);
1258			if (yytbl_data_fwrite(&tableswr, tbl) < 0)
1259				flexerror(_("Could not write ecstbl"));
1260			yytbl_data_destroy(tbl);
1261			tbl = 0;
1262		}
1263	}
1264	if (usemecs) {
1265		/* Begin generating yy_meta */
1266		/*
1267		 * Write out meta-equivalence classes (used to index
1268		 * templates with).
1269		 */
1270		flex_int32_t *yymecs_data = NULL;
1271		yymeta_tbl = calloc(1, sizeof(struct yytbl_data));
1272		yytbl_data_init(yymeta_tbl, YYTD_ID_META);
1273		yymeta_tbl->td_lolen = numecs + 1;
1274		yymeta_tbl->td_data = yymecs_data =
1275		    calloc(yymeta_tbl->td_lolen,
1276		    sizeof(flex_int32_t));
1277
1278		if (trace)
1279			fputs(_("\n\nMeta-Equivalence Classes:\n"),
1280			    stderr);
1281
1282		out_str_dec(get_int32_decl(), "yy_meta", numecs + 1);
1283		buf_prints(&yydmap_buf,
1284		    "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n",
1285		    "flex_int32_t");
1286
1287		for (i = 1; i <= numecs; ++i) {
1288			if (trace)
1289				fprintf(stderr, "%d = %d\n",
1290				    i, ABS(tecbck[i]));
1291
1292			mkdata(ABS(tecbck[i]));
1293			yymecs_data[i] = ABS(tecbck[i]);
1294		}
1295
1296		dataend();
1297		if (tablesext) {
1298			yytbl_data_compress(yymeta_tbl);
1299			if (yytbl_data_fwrite(&tableswr, yymeta_tbl) < 0)
1300				flexerror(_
1301				    ("Could not write yymeta_tbl"));
1302			yytbl_data_destroy(yymeta_tbl);
1303			yymeta_tbl = NULL;
1304		}
1305		/* End generating yy_meta */
1306	}
1307	total_states = lastdfa + numtemps;
1308
1309	/* Begin generating yy_base */
1310	out_str_dec((tblend >= INT16_MAX || long_align) ?
1311	    get_int32_decl() : get_int16_decl(),
1312	    "yy_base", total_states + 1);
1313
1314	buf_prints(&yydmap_buf,
1315	    "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n",
1316	    (tblend >= INT16_MAX
1317		|| long_align) ? "flex_int32_t" : "flex_int16_t");
1318	yybase_tbl = calloc(1, sizeof(struct yytbl_data));
1319	yytbl_data_init(yybase_tbl, YYTD_ID_BASE);
1320	yybase_tbl->td_lolen = total_states + 1;
1321	yybase_tbl->td_data = yybase_data =
1322	    calloc(yybase_tbl->td_lolen,
1323	    sizeof(flex_int32_t));
1324	yybase_curr = 1;
1325
1326	for (i = 1; i <= lastdfa; ++i) {
1327		int d = def[i];
1328
1329		if (base[i] == JAMSTATE)
1330			base[i] = jambase;
1331
1332		if (d == JAMSTATE)
1333			def[i] = jamstate;
1334
1335		else if (d < 0) {
1336			/* Template reference. */
1337			++tmpuses;
1338			def[i] = lastdfa - d + 1;
1339		}
1340		mkdata(base[i]);
1341		yybase_data[yybase_curr++] = base[i];
1342	}
1343
1344	/* Generate jam state's base index. */
1345	mkdata(base[i]);
1346	yybase_data[yybase_curr++] = base[i];
1347
1348	for (++i /* skip jam state */ ; i <= total_states; ++i) {
1349		mkdata(base[i]);
1350		yybase_data[yybase_curr++] = base[i];
1351		def[i] = jamstate;
1352	}
1353
1354	dataend();
1355	if (tablesext) {
1356		yytbl_data_compress(yybase_tbl);
1357		if (yytbl_data_fwrite(&tableswr, yybase_tbl) < 0)
1358			flexerror(_("Could not write yybase_tbl"));
1359		yytbl_data_destroy(yybase_tbl);
1360		yybase_tbl = NULL;
1361	}
1362	/* End generating yy_base */
1363
1364
1365	/* Begin generating yy_def */
1366	out_str_dec((total_states >= INT16_MAX || long_align) ?
1367	    get_int32_decl() : get_int16_decl(),
1368	    "yy_def", total_states + 1);
1369
1370	buf_prints(&yydmap_buf,
1371	    "\t{YYTD_ID_DEF, (void**)&yy_def, sizeof(%s)},\n",
1372	    (total_states >= INT16_MAX
1373		|| long_align) ? "flex_int32_t" : "flex_int16_t");
1374
1375	yydef_tbl = calloc(1, sizeof(struct yytbl_data));
1376	yytbl_data_init(yydef_tbl, YYTD_ID_DEF);
1377	yydef_tbl->td_lolen = total_states + 1;
1378	yydef_tbl->td_data = yydef_data =
1379	    calloc(yydef_tbl->td_lolen, sizeof(flex_int32_t));
1380
1381	for (i = 1; i <= total_states; ++i) {
1382		mkdata(def[i]);
1383		yydef_data[i] = def[i];
1384	}
1385
1386	dataend();
1387	if (tablesext) {
1388		yytbl_data_compress(yydef_tbl);
1389		if (yytbl_data_fwrite(&tableswr, yydef_tbl) < 0)
1390			flexerror(_("Could not write yydef_tbl"));
1391		yytbl_data_destroy(yydef_tbl);
1392		yydef_tbl = NULL;
1393	}
1394	/* End generating yy_def */
1395
1396
1397	/* Begin generating yy_nxt */
1398	out_str_dec((total_states >= INT16_MAX || long_align) ?
1399	    get_int32_decl() : get_int16_decl(), "yy_nxt",
1400	    tblend + 1);
1401
1402	buf_prints(&yydmap_buf,
1403	    "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n",
1404	    (total_states >= INT16_MAX
1405		|| long_align) ? "flex_int32_t" : "flex_int16_t");
1406
1407	yynxt_tbl = calloc(1, sizeof(struct yytbl_data));
1408	yytbl_data_init(yynxt_tbl, YYTD_ID_NXT);
1409	yynxt_tbl->td_lolen = tblend + 1;
1410	yynxt_tbl->td_data = yynxt_data =
1411	    calloc(yynxt_tbl->td_lolen, sizeof(flex_int32_t));
1412
1413	for (i = 1; i <= tblend; ++i) {
1414		/*
1415		 * Note, the order of the following test is important. If
1416		 * chk[i] is 0, then nxt[i] is undefined.
1417		 */
1418		if (chk[i] == 0 || nxt[i] == 0)
1419			nxt[i] = jamstate;	/* new state is the JAM state */
1420
1421		mkdata(nxt[i]);
1422		yynxt_data[i] = nxt[i];
1423	}
1424
1425	dataend();
1426	if (tablesext) {
1427		yytbl_data_compress(yynxt_tbl);
1428		if (yytbl_data_fwrite(&tableswr, yynxt_tbl) < 0)
1429			flexerror(_("Could not write yynxt_tbl"));
1430		yytbl_data_destroy(yynxt_tbl);
1431		yynxt_tbl = NULL;
1432	}
1433	/* End generating yy_nxt */
1434
1435	/* Begin generating yy_chk */
1436	out_str_dec((total_states >= INT16_MAX || long_align) ?
1437	    get_int32_decl() : get_int16_decl(), "yy_chk",
1438	    tblend + 1);
1439
1440	buf_prints(&yydmap_buf,
1441	    "\t{YYTD_ID_CHK, (void**)&yy_chk, sizeof(%s)},\n",
1442	    (total_states >= INT16_MAX
1443		|| long_align) ? "flex_int32_t" : "flex_int16_t");
1444
1445	yychk_tbl = calloc(1, sizeof(struct yytbl_data));
1446	yytbl_data_init(yychk_tbl, YYTD_ID_CHK);
1447	yychk_tbl->td_lolen = tblend + 1;
1448	yychk_tbl->td_data = yychk_data =
1449	    calloc(yychk_tbl->td_lolen, sizeof(flex_int32_t));
1450
1451	for (i = 1; i <= tblend; ++i) {
1452		if (chk[i] == 0)
1453			++nummt;
1454
1455		mkdata(chk[i]);
1456		yychk_data[i] = chk[i];
1457	}
1458
1459	dataend();
1460	if (tablesext) {
1461		yytbl_data_compress(yychk_tbl);
1462		if (yytbl_data_fwrite(&tableswr, yychk_tbl) < 0)
1463			flexerror(_("Could not write yychk_tbl"));
1464		yytbl_data_destroy(yychk_tbl);
1465		yychk_tbl = NULL;
1466	}
1467	/* End generating yy_chk */
1468
1469	free(acc_array);
1470}
1471
1472
1473/* Write out a formatted string (with a secondary string argument) at the
1474 * current indentation level, adding a final newline.
1475 */
1476
1477void
1478indent_put2s(fmt, arg)
1479	const char *fmt, *arg;
1480{
1481	do_indent();
1482	out_str(fmt, arg);
1483	outn("");
1484}
1485
1486
1487/* Write out a string at the current indentation level, adding a final
1488 * newline.
1489 */
1490
1491void
1492indent_puts(str)
1493	const char *str;
1494{
1495	do_indent();
1496	outn(str);
1497}
1498
1499
1500/* make_tables - generate transition tables and finishes generating output file
1501 */
1502
1503void
1504make_tables()
1505{
1506	int i;
1507	int did_eof_rule = false;
1508	struct yytbl_data *yynultrans_tbl;
1509
1510
1511	skelout();		/* %% [2.0] - break point in skel */
1512
1513	/*
1514	 * First, take care of YY_DO_BEFORE_ACTION depending on yymore being
1515	 * used.
1516	 */
1517	set_indent(1);
1518
1519	if (yymore_used && !yytext_is_array) {
1520		indent_puts("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\");
1521		indent_puts
1522		    ("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\");
1523	} else
1524		indent_puts("yyleng = (size_t) (yy_cp - yy_bp); \\");
1525
1526	/* Now also deal with copying yytext_ptr to yytext if needed. */
1527	skelout();		/* %% [3.0] - break point in skel */
1528	if (yytext_is_array) {
1529		if (yymore_used)
1530			indent_puts
1531			    ("if ( yyleng + YY_G(yy_more_offset) >= YYLMAX ) \\");
1532		else
1533			indent_puts("if ( yyleng >= YYLMAX ) \\");
1534
1535		indent_up();
1536		indent_puts
1537		    ("YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\");
1538		indent_down();
1539
1540		if (yymore_used) {
1541			indent_puts
1542			    ("yy_flex_strncpy( &yytext[YY_G(yy_more_offset)], YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\");
1543			indent_puts("yyleng += YY_G(yy_more_offset); \\");
1544			indent_puts
1545			    ("YY_G(yy_prev_more_offset) = YY_G(yy_more_offset); \\");
1546			indent_puts("YY_G(yy_more_offset) = 0; \\");
1547		} else {
1548			indent_puts
1549			    ("yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\");
1550		}
1551	}
1552	set_indent(0);
1553
1554	skelout();		/* %% [4.0] - break point in skel */
1555
1556
1557	/* This is where we REALLY begin generating the tables. */
1558
1559	out_dec("#define YY_NUM_RULES %d\n", num_rules);
1560	out_dec("#define YY_END_OF_BUFFER %d\n", num_rules + 1);
1561
1562	if (fullspd) {
1563		/*
1564		 * Need to define the transet type as a size large enough to
1565		 * hold the biggest offset.
1566		 */
1567		int total_table_size = tblend + numecs + 1;
1568		char *trans_offset_type =
1569		(total_table_size >= INT16_MAX || long_align) ?
1570		"flex_int32_t" : "flex_int16_t";
1571
1572		set_indent(0);
1573		indent_puts("struct yy_trans_info");
1574		indent_up();
1575		indent_puts("{");
1576
1577		/*
1578		 * We require that yy_verify and yy_nxt must be of the same
1579		 * size int.
1580		 */
1581		indent_put2s("%s yy_verify;", trans_offset_type);
1582
1583		/*
1584		 * In cases where its sister yy_verify *is* a "yes, there is
1585		 * a transition", yy_nxt is the offset (in records) to the
1586		 * next state.  In most cases where there is no transition,
1587		 * the value of yy_nxt is irrelevant.  If yy_nxt is the -1th
1588		 * record of a state, though, then yy_nxt is the action
1589		 * number for that state.
1590		 */
1591
1592		indent_put2s("%s yy_nxt;", trans_offset_type);
1593		indent_puts("};");
1594		indent_down();
1595	} else {
1596		/*
1597		 * We generate a bogus 'struct yy_trans_info' data type so we
1598		 * can guarantee that it is always declared in the skel. This
1599		 * is so we can compile "sizeof(struct yy_trans_info)" in any
1600		 * scanner.
1601		 */
1602		indent_puts
1603		    ("/* This struct is not used in this scanner,");
1604		indent_puts("   but its presence is necessary. */");
1605		indent_puts("struct yy_trans_info");
1606		indent_up();
1607		indent_puts("{");
1608		indent_puts("flex_int32_t yy_verify;");
1609		indent_puts("flex_int32_t yy_nxt;");
1610		indent_puts("};");
1611		indent_down();
1612	}
1613
1614	if (fullspd) {
1615		genctbl();
1616		if (tablesext) {
1617			struct yytbl_data *tbl;
1618
1619			tbl = mkctbl();
1620			yytbl_data_compress(tbl);
1621			if (yytbl_data_fwrite(&tableswr, tbl) < 0)
1622				flexerror(_("Could not write ftbl"));
1623			yytbl_data_destroy(tbl);
1624
1625			tbl = mkssltbl();
1626			yytbl_data_compress(tbl);
1627			if (yytbl_data_fwrite(&tableswr, tbl) < 0)
1628				flexerror(_("Could not write ssltbl"));
1629			yytbl_data_destroy(tbl);
1630			tbl = 0;
1631
1632			if (useecs) {
1633				tbl = mkecstbl();
1634				yytbl_data_compress(tbl);
1635				if (yytbl_data_fwrite(&tableswr, tbl) < 0)
1636					flexerror(_
1637					    ("Could not write ecstbl"));
1638				yytbl_data_destroy(tbl);
1639				tbl = 0;
1640			}
1641		}
1642	} else if (fulltbl) {
1643		genftbl();
1644		if (tablesext) {
1645			struct yytbl_data *tbl;
1646
1647			tbl = mkftbl();
1648			yytbl_data_compress(tbl);
1649			if (yytbl_data_fwrite(&tableswr, tbl) < 0)
1650				flexerror(_("Could not write ftbl"));
1651			yytbl_data_destroy(tbl);
1652			tbl = 0;
1653
1654			if (useecs) {
1655				tbl = mkecstbl();
1656				yytbl_data_compress(tbl);
1657				if (yytbl_data_fwrite(&tableswr, tbl) < 0)
1658					flexerror(_
1659					    ("Could not write ecstbl"));
1660				yytbl_data_destroy(tbl);
1661				tbl = 0;
1662			}
1663		}
1664	} else
1665		gentabs();
1666
1667	if (do_yylineno) {
1668
1669		geneoltbl();
1670
1671		if (tablesext) {
1672			struct yytbl_data *tbl;
1673
1674			tbl = mkeoltbl();
1675			yytbl_data_compress(tbl);
1676			if (yytbl_data_fwrite(&tableswr, tbl) < 0)
1677				flexerror(_("Could not write eoltbl"));
1678			yytbl_data_destroy(tbl);
1679			tbl = 0;
1680		}
1681	}
1682	/*
1683	 * Definitions for backing up.  We don't need them if REJECT is being
1684	 * used because then we use an alternative backin-up technique
1685	 * instead.
1686	 */
1687	if (num_backing_up > 0 && !reject) {
1688		if (!C_plus_plus && !reentrant) {
1689			indent_puts
1690			    ("static yy_state_type yy_last_accepting_state;");
1691			indent_puts
1692			    ("static char *yy_last_accepting_cpos;\n");
1693		}
1694	}
1695	if (nultrans) {
1696		flex_int32_t *yynultrans_data = NULL;
1697
1698		/* Begin generating yy_NUL_trans */
1699		out_str_dec(get_state_decl(), "yy_NUL_trans",
1700		    lastdfa + 1);
1701		buf_prints(&yydmap_buf,
1702		    "\t{YYTD_ID_NUL_TRANS, (void**)&yy_NUL_trans, sizeof(%s)},\n",
1703		    (fullspd) ? "struct yy_trans_info*" :
1704		    "flex_int32_t");
1705
1706		yynultrans_tbl = calloc(1, sizeof(struct yytbl_data));
1707		yytbl_data_init(yynultrans_tbl, YYTD_ID_NUL_TRANS);
1708		if (fullspd)
1709			yynultrans_tbl->td_flags |= YYTD_PTRANS;
1710		yynultrans_tbl->td_lolen = lastdfa + 1;
1711		yynultrans_tbl->td_data = yynultrans_data =
1712		    calloc(yynultrans_tbl->td_lolen,
1713		    sizeof(flex_int32_t));
1714
1715		for (i = 1; i <= lastdfa; ++i) {
1716			if (fullspd) {
1717				out_dec("    &yy_transition[%d],\n",
1718				    base[i]);
1719				yynultrans_data[i] = base[i];
1720			} else {
1721				mkdata(nultrans[i]);
1722				yynultrans_data[i] = nultrans[i];
1723			}
1724		}
1725
1726		dataend();
1727		if (tablesext) {
1728			yytbl_data_compress(yynultrans_tbl);
1729			if (yytbl_data_fwrite(&tableswr, yynultrans_tbl) < 0)
1730				flexerror(_
1731				    ("Could not write yynultrans_tbl"));
1732			yytbl_data_destroy(yynultrans_tbl);
1733			yynultrans_tbl = NULL;
1734		}
1735		/* End generating yy_NUL_trans */
1736	}
1737	if (!C_plus_plus && !reentrant) {
1738		indent_puts("extern int yy_flex_debug;");
1739		indent_put2s("int yy_flex_debug = %s;\n",
1740		    ddebug ? "1" : "0");
1741	}
1742	if (ddebug) {		/* Spit out table mapping rules to line
1743				 * numbers. */
1744		out_str_dec(long_align ? get_int32_decl() :
1745		    get_int16_decl(), "yy_rule_linenum",
1746		    num_rules);
1747		for (i = 1; i < num_rules; ++i)
1748			mkdata(rule_linenum[i]);
1749		dataend();
1750	}
1751	if (reject) {
1752		outn("m4_ifdef( [[M4_YY_USES_REJECT]],\n[[");
1753		/* Declare state buffer variables. */
1754		if (!C_plus_plus && !reentrant) {
1755			outn("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;");
1756			outn("static char *yy_full_match;");
1757			outn("static int yy_lp;");
1758		}
1759		if (variable_trailing_context_rules) {
1760			if (!C_plus_plus && !reentrant) {
1761				outn("static int yy_looking_for_trail_begin = 0;");
1762				outn("static int yy_full_lp;");
1763				outn("static int *yy_full_state;");
1764			}
1765			out_hex("#define YY_TRAILING_MASK 0x%x\n",
1766			    (unsigned int) YY_TRAILING_MASK);
1767			out_hex("#define YY_TRAILING_HEAD_MASK 0x%x\n",
1768			    (unsigned int) YY_TRAILING_HEAD_MASK);
1769		}
1770		outn("#define REJECT \\");
1771		outn("{ \\");
1772		outn("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */ \\");
1773		outn("yy_cp = YY_G(yy_full_match); /* restore poss. backed-over text */ \\");
1774
1775		if (variable_trailing_context_rules) {
1776			outn("YY_G(yy_lp) = YY_G(yy_full_lp); /* restore orig. accepting pos. */ \\");
1777			outn("YY_G(yy_state_ptr) = YY_G(yy_full_state); /* restore orig. state */ \\");
1778			outn("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\");
1779		}
1780		outn("++YY_G(yy_lp); \\");
1781		outn("goto find_rule; \\");
1782
1783		outn("}");
1784		outn("]])\n");
1785	} else {
1786		outn("/* The intent behind this definition is that it'll catch");
1787		outn(" * any uses of REJECT which flex missed.");
1788		outn(" */");
1789		outn("#define REJECT reject_used_but_not_detected");
1790	}
1791
1792	if (yymore_used) {
1793		if (!C_plus_plus) {
1794			if (yytext_is_array) {
1795				if (!reentrant) {
1796					indent_puts("static int yy_more_offset = 0;");
1797					indent_puts("static int yy_prev_more_offset = 0;");
1798				}
1799			} else if (!reentrant) {
1800				indent_puts
1801				    ("static int yy_more_flag = 0;");
1802				indent_puts
1803				    ("static int yy_more_len = 0;");
1804			}
1805		}
1806		if (yytext_is_array) {
1807			indent_puts
1808			    ("#define yymore() (YY_G(yy_more_offset) = yy_flex_strlen( yytext M4_YY_CALL_LAST_ARG))");
1809			indent_puts("#define YY_NEED_STRLEN");
1810			indent_puts("#define YY_MORE_ADJ 0");
1811			indent_puts
1812			    ("#define YY_RESTORE_YY_MORE_OFFSET \\");
1813			indent_up();
1814			indent_puts("{ \\");
1815			indent_puts
1816			    ("YY_G(yy_more_offset) = YY_G(yy_prev_more_offset); \\");
1817			indent_puts("yyleng -= YY_G(yy_more_offset); \\");
1818			indent_puts("}");
1819			indent_down();
1820		} else {
1821			indent_puts
1822			    ("#define yymore() (YY_G(yy_more_flag) = 1)");
1823			indent_puts
1824			    ("#define YY_MORE_ADJ YY_G(yy_more_len)");
1825			indent_puts("#define YY_RESTORE_YY_MORE_OFFSET");
1826		}
1827	} else {
1828		indent_puts
1829		    ("#define yymore() yymore_used_but_not_detected");
1830		indent_puts("#define YY_MORE_ADJ 0");
1831		indent_puts("#define YY_RESTORE_YY_MORE_OFFSET");
1832	}
1833
1834	if (!C_plus_plus) {
1835		if (yytext_is_array) {
1836			outn("#ifndef YYLMAX");
1837			outn("#define YYLMAX 8192");
1838			outn("#endif\n");
1839			if (!reentrant) {
1840				outn("char yytext[YYLMAX];");
1841				outn("char *yytext_ptr;");
1842			}
1843		} else {
1844			if (!reentrant)
1845				outn("char *yytext;");
1846		}
1847	}
1848	out(&action_array[defs1_offset]);
1849
1850	line_directive_out(stdout, 0);
1851
1852	skelout();		/* %% [5.0] - break point in skel */
1853
1854	if (!C_plus_plus) {
1855		if (use_read) {
1856			outn("\terrno=0; \\");
1857			outn("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\");
1858			outn("\t{ \\");
1859			outn("\t\tif( errno != EINTR) \\");
1860			outn("\t\t{ \\");
1861			outn("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
1862			outn("\t\t\tbreak; \\");
1863			outn("\t\t} \\");
1864			outn("\t\terrno=0; \\");
1865			outn("\t\tclearerr(yyin); \\");
1866			outn("\t}\\");
1867		} else {
1868			outn("\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\");
1869			outn("\t\t{ \\");
1870			outn("\t\tint c = '*'; \\");
1871			outn("\t\tsize_t n; \\");
1872			outn("\t\tfor ( n = 0; n < max_size && \\");
1873			outn("\t\t\t     (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\");
1874			outn("\t\t\tbuf[n] = (char) c; \\");
1875			outn("\t\tif ( c == '\\n' ) \\");
1876			outn("\t\t\tbuf[n++] = (char) c; \\");
1877			outn("\t\tif ( c == EOF && ferror( yyin ) ) \\");
1878			outn("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
1879			outn("\t\tresult = n; \\");
1880			outn("\t\t} \\");
1881			outn("\telse \\");
1882			outn("\t\t{ \\");
1883			outn("\t\terrno=0; \\");
1884			outn("\t\twhile ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\");
1885			outn("\t\t\t{ \\");
1886			outn("\t\t\tif( errno != EINTR) \\");
1887			outn("\t\t\t\t{ \\");
1888			outn("\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\");
1889			outn("\t\t\t\tbreak; \\");
1890			outn("\t\t\t\t} \\");
1891			outn("\t\t\terrno=0; \\");
1892			outn("\t\t\tclearerr(yyin); \\");
1893			outn("\t\t\t} \\");
1894			outn("\t\t}\\");
1895		}
1896	}
1897	skelout();		/* %% [6.0] - break point in skel */
1898
1899	indent_puts("#define YY_RULE_SETUP \\");
1900	indent_up();
1901	if (bol_needed) {
1902		indent_puts("if ( yyleng > 0 ) \\");
1903		indent_up();
1904		indent_puts("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \\");
1905		indent_puts("\t\t(yytext[yyleng - 1] == '\\n'); \\");
1906		indent_down();
1907	}
1908	indent_puts("YY_USER_ACTION");
1909	indent_down();
1910
1911	skelout();		/* %% [7.0] - break point in skel */
1912
1913	/* Copy prolog to output file. */
1914	out(&action_array[prolog_offset]);
1915
1916	line_directive_out(stdout, 0);
1917
1918	skelout();		/* %% [8.0] - break point in skel */
1919
1920	set_indent(2);
1921
1922	if (yymore_used && !yytext_is_array) {
1923		indent_puts("YY_G(yy_more_len) = 0;");
1924		indent_puts("if ( YY_G(yy_more_flag) )");
1925		indent_up();
1926		indent_puts("{");
1927		indent_puts
1928		    ("YY_G(yy_more_len) = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);");
1929		indent_puts("YY_G(yy_more_flag) = 0;");
1930		indent_puts("}");
1931		indent_down();
1932	}
1933	skelout();		/* %% [9.0] - break point in skel */
1934
1935	gen_start_state();
1936
1937	/* Note, don't use any indentation. */
1938	outn("yy_match:");
1939	gen_next_match();
1940
1941	skelout();		/* %% [10.0] - break point in skel */
1942	set_indent(2);
1943	gen_find_action();
1944
1945	skelout();		/* %% [11.0] - break point in skel */
1946	outn("m4_ifdef( [[M4_YY_USE_LINENO]],[[");
1947	indent_puts
1948	    ("if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )");
1949	indent_up();
1950	indent_puts("{");
1951	indent_puts("yy_size_t yyl;");
1952	do_indent();
1953	out_str("for ( yyl = %s; yyl < yyleng; ++yyl )\n",
1954	    yymore_used ? (yytext_is_array ? "YY_G(yy_prev_more_offset)" :
1955		"YY_G(yy_more_len)") : "0");
1956	indent_up();
1957	indent_puts("if ( yytext[yyl] == '\\n' )");
1958	indent_up();
1959	indent_puts("M4_YY_INCR_LINENO();");
1960	indent_down();
1961	indent_down();
1962	indent_puts("}");
1963	indent_down();
1964	outn("]])");
1965
1966	skelout();		/* %% [12.0] - break point in skel */
1967	if (ddebug) {
1968		indent_puts("if ( yy_flex_debug )");
1969		indent_up();
1970
1971		indent_puts("{");
1972		indent_puts("if ( yy_act == 0 )");
1973		indent_up();
1974		indent_puts(C_plus_plus ?
1975		    "std::cerr << \"--scanner backing up\\n\";" :
1976		    "fprintf( stderr, \"--scanner backing up\\n\" );");
1977		indent_down();
1978
1979		do_indent();
1980		out_dec("else if ( yy_act < %d )\n", num_rules);
1981		indent_up();
1982
1983		if (C_plus_plus) {
1984			indent_puts
1985			    ("std::cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<");
1986			indent_puts
1987			    ("         \"(\\\"\" << yytext << \"\\\")\\n\";");
1988		} else {
1989			indent_puts
1990			    ("fprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\",");
1991
1992			indent_puts
1993			    ("         (long)yy_rule_linenum[yy_act], yytext );");
1994		}
1995
1996		indent_down();
1997
1998		do_indent();
1999		out_dec("else if ( yy_act == %d )\n", num_rules);
2000		indent_up();
2001
2002		if (C_plus_plus) {
2003			indent_puts
2004			    ("std::cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";");
2005		} else {
2006			indent_puts
2007			    ("fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\",");
2008			indent_puts("         yytext );");
2009		}
2010
2011		indent_down();
2012
2013		do_indent();
2014		out_dec("else if ( yy_act == %d )\n", num_rules + 1);
2015		indent_up();
2016
2017		indent_puts(C_plus_plus ?
2018		    "std::cerr << \"--(end of buffer or a NUL)\\n\";" :
2019		    "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );");
2020
2021		indent_down();
2022
2023		do_indent();
2024		outn("else");
2025		indent_up();
2026
2027		if (C_plus_plus) {
2028			indent_puts
2029			    ("std::cerr << \"--EOF (start condition \" << YY_START << \")\\n\";");
2030		} else {
2031			indent_puts
2032			    ("fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );");
2033		}
2034
2035		indent_down();
2036
2037		indent_puts("}");
2038		indent_down();
2039	}
2040	/* Copy actions to output file. */
2041	skelout();		/* %% [13.0] - break point in skel */
2042	indent_up();
2043	gen_bu_action();
2044	out(&action_array[action_offset]);
2045
2046	line_directive_out(stdout, 0);
2047
2048	/* generate cases for any missing EOF rules */
2049	for (i = 1; i <= lastsc; ++i)
2050		if (!sceof[i]) {
2051			do_indent();
2052			out_str("case YY_STATE_EOF(%s):\n", scname[i]);
2053			did_eof_rule = true;
2054		}
2055	if (did_eof_rule) {
2056		indent_up();
2057		indent_puts("yyterminate();");
2058		indent_down();
2059	}
2060	/* Generate code for handling NUL's, if needed. */
2061
2062	/*
2063	 * First, deal with backing up and setting up yy_cp if the scanner
2064	 * finds that it should JAM on the NUL.
2065	 */
2066	skelout();		/* %% [14.0] - break point in skel */
2067	set_indent(4);
2068
2069	if (fullspd || fulltbl)
2070		indent_puts("yy_cp = YY_G(yy_c_buf_p);");
2071
2072	else {			/* compressed table */
2073		if (!reject && !interactive) {
2074			/*
2075			 * Do the guaranteed-needed backing up to figure out
2076			 * the match.
2077			 */
2078			indent_puts
2079			    ("yy_cp = YY_G(yy_last_accepting_cpos);");
2080			indent_puts
2081			    ("yy_current_state = YY_G(yy_last_accepting_state);");
2082		} else
2083			/*
2084			 * Still need to initialize yy_cp, though
2085			 * yy_current_state was set up by
2086			 * yy_get_previous_state().
2087			 */
2088			indent_puts("yy_cp = YY_G(yy_c_buf_p);");
2089	}
2090
2091
2092	/* Generate code for yy_get_previous_state(). */
2093	set_indent(1);
2094	skelout();		/* %% [15.0] - break point in skel */
2095
2096	gen_start_state();
2097
2098	set_indent(2);
2099	skelout();		/* %% [16.0] - break point in skel */
2100	gen_next_state(true);
2101
2102	set_indent(1);
2103	skelout();		/* %% [17.0] - break point in skel */
2104	gen_NUL_trans();
2105
2106	skelout();		/* %% [18.0] - break point in skel */
2107	skelout();		/* %% [19.0] - break point in skel */
2108	/* Update BOL and yylineno inside of input(). */
2109	if (bol_needed) {
2110		indent_puts
2111		    ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\\n');");
2112		if (do_yylineno) {
2113			indent_puts
2114			    ("if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )");
2115			indent_up();
2116			indent_puts("M4_YY_INCR_LINENO();");
2117			indent_down();
2118		}
2119	} else if (do_yylineno) {
2120		indent_puts("if ( c == '\\n' )");
2121		indent_up();
2122		indent_puts("M4_YY_INCR_LINENO();");
2123		indent_down();
2124	}
2125	skelout();
2126
2127	/* Copy remainder of input to output. */
2128
2129	line_directive_out(stdout, 1);
2130
2131	if (sectnum == 3) {
2132		OUT_BEGIN_CODE();
2133		(void) flexscan();	/* copy remainder of input to output */
2134		OUT_END_CODE();
2135	}
2136}
2137