PageRenderTime 122ms CodeModel.GetById 28ms app.highlight 85ms RepoModel.GetById 1ms app.codeStats 0ms

/usr.bin/lex/gen.c

https://bitbucket.org/freebsd/freebsd-head/
C | 1629 lines | 1198 code | 254 blank | 177 comment | 165 complexity | 40df6a8a931d08b24e1ca0b6abd2e948 MD5 | raw file
   1/* gen - actual generation (writing) of flex scanners */
   2
   3/*-
   4 * Copyright (c) 1990 The Regents of the University of California.
   5 * All rights reserved.
   6 *
   7 * This code is derived from software contributed to Berkeley by
   8 * Vern Paxson.
   9 * 
  10 * The United States Government has rights in this work pursuant
  11 * to contract no. DE-AC03-76SF00098 between the United States
  12 * Department of Energy and the University of California.
  13 *
  14 * Redistribution and use in source and binary forms are permitted provided
  15 * that: (1) source distributions retain this entire copyright notice and
  16 * comment, and (2) distributions including binaries display the following
  17 * acknowledgement:  ``This product includes software developed by the
  18 * University of California, Berkeley and its contributors'' in the
  19 * documentation or other materials provided with the distribution and in
  20 * all advertising materials mentioning features or use of this software.
  21 * Neither the name of the University nor the names of its contributors may
  22 * be used to endorse or promote products derived from this software without
  23 * specific prior written permission.
  24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  25 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27 */
  28
  29/* $Header: /home/daffy/u0/vern/flex/RCS/gen.c,v 2.56 96/05/25 20:43:38 vern Exp $ */
  30#include <sys/cdefs.h>
  31__FBSDID("$FreeBSD$");
  32
  33#include "flexdef.h"
  34
  35
  36/* declare functions that have forward references */
  37
  38void gen_next_state PROTO((int));
  39void genecs PROTO((void));
  40void indent_put2s PROTO((char [], char []));
  41void indent_puts PROTO((char []));
  42
  43
  44static int indent_level = 0; /* each level is 8 spaces */
  45
  46#define indent_up() (++indent_level)
  47#define indent_down() (--indent_level)
  48#define set_indent(indent_val) indent_level = indent_val
  49
  50/* Almost everything is done in terms of arrays starting at 1, so provide
  51 * a null entry for the zero element of all C arrays.  (The exception
  52 * to this is that the fast table representation generally uses the
  53 * 0 elements of its arrays, too.)
  54 */
  55static char C_int_decl[] = "static yyconst int %s[%d] =\n    {   0,\n";
  56static char C_short_decl[] = "static yyconst short int %s[%d] =\n    {   0,\n";
  57static char C_long_decl[] = "static yyconst long int %s[%d] =\n    {   0,\n";
  58static char C_state_decl[] =
  59	"static yyconst yy_state_type %s[%d] =\n    {   0,\n";
  60
  61
  62/* Indent to the current level. */
  63
  64void do_indent()
  65	{
  66	int i = indent_level * 8;
  67
  68	while ( i >= 8 )
  69		{
  70		outc( '\t' );
  71		i -= 8;
  72		}
  73
  74	while ( i > 0 )
  75		{
  76		outc( ' ' );
  77		--i;
  78		}
  79	}
  80
  81
  82/* Generate the code to keep backing-up information. */
  83
  84void gen_backing_up()
  85	{
  86	if ( reject || num_backing_up == 0 )
  87		return;
  88
  89	if ( fullspd )
  90		indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
  91	else
  92		indent_puts( "if ( yy_accept[yy_current_state] )" );
  93
  94	indent_up();
  95	indent_puts( "{" );
  96	indent_puts( "yy_last_accepting_state = yy_current_state;" );
  97	indent_puts( "yy_last_accepting_cpos = yy_cp;" );
  98	indent_puts( "}" );
  99	indent_down();
 100	}
 101
 102
 103/* Generate the code to perform the backing up. */
 104
 105void gen_bu_action()
 106	{
 107	if ( reject || num_backing_up == 0 )
 108		return;
 109
 110	set_indent( 3 );
 111
 112	indent_puts( "case 0: /* must back up */" );
 113	indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
 114	indent_puts( "*yy_cp = yy_hold_char;" );
 115
 116	if ( fullspd || fulltbl )
 117		indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
 118	else
 119		/* Backing-up info for compressed tables is taken \after/
 120		 * yy_cp has been incremented for the next state.
 121		 */
 122		indent_puts( "yy_cp = yy_last_accepting_cpos;" );
 123
 124	indent_puts( "yy_current_state = yy_last_accepting_state;" );
 125	indent_puts( "goto yy_find_action;" );
 126	outc( '\n' );
 127
 128	set_indent( 0 );
 129	}
 130
 131
 132/* genctbl - generates full speed compressed transition table */
 133
 134void genctbl()
 135	{
 136	int i;
 137	int end_of_buffer_action = num_rules + 1;
 138
 139	/* Table of verify for transition and offset to next state. */
 140	out_dec( "static yyconst struct yy_trans_info yy_transition[%d] =\n",
 141		tblend + numecs + 1 );
 142	outn( "    {" );
 143
 144	/* We want the transition to be represented as the offset to the
 145	 * next state, not the actual state number, which is what it currently
 146	 * is.  The offset is base[nxt[i]] - (base of current state)].  That's
 147	 * just the difference between the starting points of the two involved
 148	 * states (to - from).
 149	 *
 150	 * First, though, we need to find some way to put in our end-of-buffer
 151	 * flags and states.  We do this by making a state with absolutely no
 152	 * transitions.  We put it at the end of the table.
 153	 */
 154
 155	/* We need to have room in nxt/chk for two more slots: One for the
 156	 * action and one for the end-of-buffer transition.  We now *assume*
 157	 * that we're guaranteed the only character we'll try to index this
 158	 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
 159	 * there's room for jam entries for other characters.
 160	 */
 161
 162	while ( tblend + 2 >= current_max_xpairs )
 163		expand_nxt_chk();
 164
 165	while ( lastdfa + 1 >= current_max_dfas )
 166		increase_max_dfas();
 167
 168	base[lastdfa + 1] = tblend + 2;
 169	nxt[tblend + 1] = end_of_buffer_action;
 170	chk[tblend + 1] = numecs + 1;
 171	chk[tblend + 2] = 1; /* anything but EOB */
 172
 173	/* So that "make test" won't show arb. differences. */
 174	nxt[tblend + 2] = 0;
 175
 176	/* Make sure every state has an end-of-buffer transition and an
 177	 * action #.
 178	 */
 179	for ( i = 0; i <= lastdfa; ++i )
 180		{
 181		int anum = dfaacc[i].dfaacc_state;
 182		int offset = base[i];
 183
 184		chk[offset] = EOB_POSITION;
 185		chk[offset - 1] = ACTION_POSITION;
 186		nxt[offset - 1] = anum;	/* action number */
 187		}
 188
 189	for ( i = 0; i <= tblend; ++i )
 190		{
 191		if ( chk[i] == EOB_POSITION )
 192			transition_struct_out( 0, base[lastdfa + 1] - i );
 193
 194		else if ( chk[i] == ACTION_POSITION )
 195			transition_struct_out( 0, nxt[i] );
 196
 197		else if ( chk[i] > numecs || chk[i] == 0 )
 198			transition_struct_out( 0, 0 );	/* unused slot */
 199
 200		else	/* verify, transition */
 201			transition_struct_out( chk[i],
 202						base[nxt[i]] - (i - chk[i]) );
 203		}
 204
 205
 206	/* Here's the final, end-of-buffer state. */
 207	transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
 208	transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
 209
 210	outn( "    };\n" );
 211
 212	/* Table of pointers to start states. */
 213	out_dec(
 214	"static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n",
 215		lastsc * 2 + 1 );
 216	outn( "    {" );	/* } so vi doesn't get confused */
 217
 218	for ( i = 0; i <= lastsc * 2; ++i )
 219		out_dec( "    &yy_transition[%d],\n", base[i] );
 220
 221	dataend();
 222
 223	if ( useecs )
 224		genecs();
 225	}
 226
 227
 228/* Generate equivalence-class tables. */
 229
 230void genecs()
 231	{
 232	int i, j;
 233	int numrows;
 234
 235	out_str_dec( C_int_decl, "yy_ec", csize );
 236
 237	for ( i = 1; i < csize; ++i )
 238		{
 239		if ( caseins && (i >= 'A') && (i <= 'Z') )
 240			ecgroup[i] = ecgroup[clower( i )];
 241
 242		ecgroup[i] = ABS( ecgroup[i] );
 243		mkdata( ecgroup[i] );
 244		}
 245
 246	dataend();
 247
 248	if ( trace )
 249		{
 250		fputs( _( "\n\nEquivalence Classes:\n\n" ), stderr );
 251
 252		numrows = csize / 8;
 253
 254		for ( j = 0; j < numrows; ++j )
 255			{
 256			for ( i = j; i < csize; i = i + numrows )
 257				{
 258				fprintf( stderr, "%4s = %-2d",
 259					readable_form( i ), ecgroup[i] );
 260
 261				putc( ' ', stderr );
 262				}
 263
 264			putc( '\n', stderr );
 265			}
 266		}
 267	}
 268
 269
 270/* Generate the code to find the action number. */
 271
 272void gen_find_action()
 273	{
 274	if ( fullspd )
 275		indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" );
 276
 277	else if ( fulltbl )
 278		indent_puts( "yy_act = yy_accept[yy_current_state];" );
 279
 280	else if ( reject )
 281		{
 282		indent_puts( "yy_current_state = *--yy_state_ptr;" );
 283		indent_puts( "yy_lp = yy_accept[yy_current_state];" );
 284
 285		outn(
 286		"goto find_rule; /* avoid `defined but not used' warning */");
 287		outn(
 288		"find_rule: /* we branch to this label when backing up */" );
 289
 290		indent_puts(
 291		"for ( ; ; ) /* until we find what rule we matched */" );
 292
 293		indent_up();
 294
 295		indent_puts( "{" );
 296
 297		indent_puts(
 298		"if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
 299		indent_up();
 300		indent_puts( "{" );
 301		indent_puts( "yy_act = yy_acclist[yy_lp];" );
 302
 303		if ( variable_trailing_context_rules )
 304			{
 305			indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
 306			indent_puts( "     yy_looking_for_trail_begin )" );
 307			indent_up();
 308			indent_puts( "{" );
 309
 310			indent_puts(
 311				"if ( yy_act == yy_looking_for_trail_begin )" );
 312			indent_up();
 313			indent_puts( "{" );
 314			indent_puts( "yy_looking_for_trail_begin = 0;" );
 315			indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );
 316			indent_puts( "break;" );
 317			indent_puts( "}" );
 318			indent_down();
 319
 320			indent_puts( "}" );
 321			indent_down();
 322
 323			indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );
 324			indent_up();
 325			indent_puts( "{" );
 326			indent_puts(
 327		"yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );
 328			indent_puts(
 329		"yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );
 330
 331			if ( real_reject )
 332				{
 333				/* Remember matched text in case we back up
 334				 * due to REJECT.
 335				 */
 336				indent_puts( "yy_full_match = yy_cp;" );
 337				indent_puts( "yy_full_state = yy_state_ptr;" );
 338				indent_puts( "yy_full_lp = yy_lp;" );
 339				}
 340
 341			indent_puts( "}" );
 342			indent_down();
 343
 344			indent_puts( "else" );
 345			indent_up();
 346			indent_puts( "{" );
 347			indent_puts( "yy_full_match = yy_cp;" );
 348			indent_puts( "yy_full_state = yy_state_ptr;" );
 349			indent_puts( "yy_full_lp = yy_lp;" );
 350			indent_puts( "break;" );
 351			indent_puts( "}" );
 352			indent_down();
 353
 354			indent_puts( "++yy_lp;" );
 355			indent_puts( "goto find_rule;" );
 356			}
 357
 358		else
 359			{
 360			/* Remember matched text in case we back up due to
 361			 * trailing context plus REJECT.
 362			 */
 363			indent_up();
 364			indent_puts( "{" );
 365			indent_puts( "yy_full_match = yy_cp;" );
 366			indent_puts( "break;" );
 367			indent_puts( "}" );
 368			indent_down();
 369			}
 370
 371		indent_puts( "}" );
 372		indent_down();
 373
 374		indent_puts( "--yy_cp;" );
 375
 376		/* We could consolidate the following two lines with those at
 377		 * the beginning, but at the cost of complaints that we're
 378		 * branching inside a loop.
 379		 */
 380		indent_puts( "yy_current_state = *--yy_state_ptr;" );
 381		indent_puts( "yy_lp = yy_accept[yy_current_state];" );
 382
 383		indent_puts( "}" );
 384
 385		indent_down();
 386		}
 387
 388	else
 389		{ /* compressed */
 390		indent_puts( "yy_act = yy_accept[yy_current_state];" );
 391
 392		if ( interactive && ! reject )
 393			{
 394			/* Do the guaranteed-needed backing up to figure out
 395			 * the match.
 396			 */
 397			indent_puts( "if ( yy_act == 0 )" );
 398			indent_up();
 399			indent_puts( "{ /* have to back up */" );
 400			indent_puts( "yy_cp = yy_last_accepting_cpos;" );
 401			indent_puts(
 402				"yy_current_state = yy_last_accepting_state;" );
 403			indent_puts( "yy_act = yy_accept[yy_current_state];" );
 404			indent_puts( "}" );
 405			indent_down();
 406			}
 407		}
 408	}
 409
 410
 411/* genftbl - generate full transition table */
 412
 413void genftbl()
 414	{
 415	int i;
 416	int end_of_buffer_action = num_rules + 1;
 417
 418	out_str_dec( long_align ? C_long_decl : C_short_decl,
 419		"yy_accept", lastdfa + 1 );
 420
 421	dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
 422
 423	for ( i = 1; i <= lastdfa; ++i )
 424		{
 425		int anum = dfaacc[i].dfaacc_state;
 426
 427		mkdata( anum );
 428
 429		if ( trace && anum )
 430			fprintf( stderr, _( "state # %d accepts: [%d]\n" ),
 431				i, anum );
 432		}
 433
 434	dataend();
 435
 436	if ( useecs )
 437		genecs();
 438
 439	/* Don't have to dump the actual full table entries - they were
 440	 * created on-the-fly.
 441	 */
 442	}
 443
 444
 445/* Generate the code to find the next compressed-table state. */
 446
 447void gen_next_compressed_state( char_map )
 448char *char_map;
 449	{
 450	indent_put2s( "YY_CHAR yy_c = %s;", char_map );
 451
 452	/* Save the backing-up info \before/ computing the next state
 453	 * because we always compute one more state than needed - we
 454	 * always proceed until we reach a jam state
 455	 */
 456	gen_backing_up();
 457
 458	indent_puts(
 459"while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );
 460	indent_up();
 461	indent_puts( "{" );
 462	indent_puts( "yy_current_state = (int) yy_def[yy_current_state];" );
 463
 464	if ( usemecs )
 465		{
 466		/* We've arrange it so that templates are never chained
 467		 * to one another.  This means we can afford to make a
 468		 * very simple test to see if we need to convert to
 469		 * yy_c's meta-equivalence class without worrying
 470		 * about erroneously looking up the meta-equivalence
 471		 * class twice
 472		 */
 473		do_indent();
 474
 475		/* lastdfa + 2 is the beginning of the templates */
 476		out_dec( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
 477
 478		indent_up();
 479		indent_puts( "yy_c = yy_meta[(unsigned int) yy_c];" );
 480		indent_down();
 481		}
 482
 483	indent_puts( "}" );
 484	indent_down();
 485
 486	indent_puts(
 487"yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];" );
 488	}
 489
 490
 491/* Generate the code to find the next match. */
 492
 493void gen_next_match()
 494	{
 495	/* NOTE - changes in here should be reflected in gen_next_state() and
 496	 * gen_NUL_trans().
 497	 */
 498	char *char_map = useecs ?
 499				"yy_ec[YY_SC_TO_UI(*yy_cp)]" :
 500				"YY_SC_TO_UI(*yy_cp)";
 501
 502	char *char_map_2 = useecs ?
 503				"yy_ec[YY_SC_TO_UI(*++yy_cp)]" :
 504				"YY_SC_TO_UI(*++yy_cp)";
 505
 506	if ( fulltbl )
 507		{
 508		indent_put2s(
 509	"while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
 510				char_map );
 511
 512		indent_up();
 513
 514		if ( num_backing_up > 0 )
 515			{
 516			indent_puts( "{" );	/* } for vi */
 517			gen_backing_up();
 518			outc( '\n' );
 519			}
 520
 521		indent_puts( "++yy_cp;" );
 522
 523		if ( num_backing_up > 0 )
 524			/* { for vi */
 525			indent_puts( "}" );
 526
 527		indent_down();
 528
 529		outc( '\n' );
 530		indent_puts( "yy_current_state = -yy_current_state;" );
 531		}
 532
 533	else if ( fullspd )
 534		{
 535		indent_puts( "{" );	/* } for vi */
 536		indent_puts(
 537		"yyconst struct yy_trans_info *yy_trans_info;\n" );
 538		indent_puts( "YY_CHAR yy_c;\n" );
 539		indent_put2s( "for ( yy_c = %s;", char_map );
 540		indent_puts(
 541	"      (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->" );
 542		indent_puts( "yy_verify == yy_c;" );
 543		indent_put2s( "      yy_c = %s )", char_map_2 );
 544
 545		indent_up();
 546
 547		if ( num_backing_up > 0 )
 548			indent_puts( "{" );	/* } for vi */
 549
 550		indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
 551
 552		if ( num_backing_up > 0 )
 553			{
 554			outc( '\n' );
 555			gen_backing_up();	/* { for vi */
 556			indent_puts( "}" );
 557			}
 558
 559		indent_down();	/* { for vi */
 560		indent_puts( "}" );
 561		}
 562
 563	else
 564		{ /* compressed */
 565		indent_puts( "do" );
 566
 567		indent_up();
 568		indent_puts( "{" );	/* } for vi */
 569
 570		gen_next_state( false );
 571
 572		indent_puts( "++yy_cp;" );
 573
 574		/* { for vi */
 575		indent_puts( "}" );
 576		indent_down();
 577
 578		do_indent();
 579
 580		if ( interactive )
 581			out_dec( "while ( yy_base[yy_current_state] != %d );\n",
 582				jambase );
 583		else
 584			out_dec( "while ( yy_current_state != %d );\n",
 585				jamstate );
 586
 587		if ( ! reject && ! interactive )
 588			{
 589			/* Do the guaranteed-needed backing up to figure out
 590			 * the match.
 591			 */
 592			indent_puts( "yy_cp = yy_last_accepting_cpos;" );
 593			indent_puts(
 594				"yy_current_state = yy_last_accepting_state;" );
 595			}
 596		}
 597	}
 598
 599
 600/* Generate the code to find the next state. */
 601
 602void gen_next_state( worry_about_NULs )
 603int worry_about_NULs;
 604	{ /* NOTE - changes in here should be reflected in gen_next_match() */
 605	char char_map[256];
 606
 607	if ( worry_about_NULs && ! nultrans )
 608		{
 609		if ( useecs )
 610			(void) sprintf( char_map,
 611				"(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)",
 612					NUL_ec );
 613		else
 614			(void) sprintf( char_map,
 615				"(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", NUL_ec );
 616		}
 617
 618	else
 619		strcpy( char_map, useecs ?
 620			"yy_ec[YY_SC_TO_UI(*yy_cp)]" : "YY_SC_TO_UI(*yy_cp)" );
 621
 622	if ( worry_about_NULs && nultrans )
 623		{
 624		if ( ! fulltbl && ! fullspd )
 625			/* Compressed tables back up *before* they match. */
 626			gen_backing_up();
 627
 628		indent_puts( "if ( *yy_cp )" );
 629		indent_up();
 630		indent_puts( "{" );	/* } for vi */
 631		}
 632
 633	if ( fulltbl )
 634		indent_put2s(
 635			"yy_current_state = yy_nxt[yy_current_state][%s];", 
 636				char_map );
 637
 638	else if ( fullspd )
 639		indent_put2s(
 640			"yy_current_state += yy_current_state[%s].yy_nxt;",
 641				char_map );
 642
 643	else
 644		gen_next_compressed_state( char_map );
 645
 646	if ( worry_about_NULs && nultrans )
 647		{
 648		/* { for vi */
 649		indent_puts( "}" );
 650		indent_down();
 651		indent_puts( "else" );
 652		indent_up();
 653		indent_puts(
 654			"yy_current_state = yy_NUL_trans[yy_current_state];" );
 655		indent_down();
 656		}
 657
 658	if ( fullspd || fulltbl )
 659		gen_backing_up();
 660
 661	if ( reject )
 662		indent_puts( "*yy_state_ptr++ = yy_current_state;" );
 663	}
 664
 665
 666/* Generate the code to make a NUL transition. */
 667
 668void gen_NUL_trans()
 669	{ /* NOTE - changes in here should be reflected in gen_next_match() */
 670	/* Only generate a definition for "yy_cp" if we'll generate code
 671	 * that uses it.  Otherwise lint and the like complain.
 672	 */
 673	int need_backing_up = (num_backing_up > 0 && ! reject);
 674
 675	if ( need_backing_up && (! nultrans || fullspd || fulltbl) )
 676		/* We're going to need yy_cp lying around for the call
 677		 * below to gen_backing_up().
 678		 */
 679		indent_puts( "char *yy_cp = yy_c_buf_p;" );
 680
 681	outc( '\n' );
 682
 683	if ( nultrans )
 684		{
 685		indent_puts(
 686			"yy_current_state = yy_NUL_trans[yy_current_state];" );
 687		indent_puts( "yy_is_jam = (yy_current_state == 0);" );
 688		}
 689
 690	else if ( fulltbl )
 691		{
 692		do_indent();
 693		out_dec( "yy_current_state = yy_nxt[yy_current_state][%d];\n",
 694			NUL_ec );
 695		indent_puts( "yy_is_jam = (yy_current_state <= 0);" );
 696		}
 697
 698	else if ( fullspd )
 699		{
 700		do_indent();
 701		out_dec( "int yy_c = %d;\n", NUL_ec );
 702
 703		indent_puts(
 704		"yyconst struct yy_trans_info *yy_trans_info;\n" );
 705		indent_puts(
 706		"yy_trans_info = &yy_current_state[(unsigned int) yy_c];" );
 707		indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
 708
 709		indent_puts(
 710			"yy_is_jam = (yy_trans_info->yy_verify != yy_c);" );
 711		}
 712
 713	else
 714		{
 715		char NUL_ec_str[20];
 716
 717		(void) sprintf( NUL_ec_str, "%d", NUL_ec );
 718		gen_next_compressed_state( NUL_ec_str );
 719
 720		do_indent();
 721		out_dec( "yy_is_jam = (yy_current_state == %d);\n", jamstate );
 722
 723		if ( reject )
 724			{
 725			/* Only stack this state if it's a transition we
 726			 * actually make.  If we stack it on a jam, then
 727			 * the state stack and yy_c_buf_p get out of sync.
 728			 */
 729			indent_puts( "if ( ! yy_is_jam )" );
 730			indent_up();
 731			indent_puts( "*yy_state_ptr++ = yy_current_state;" );
 732			indent_down();
 733			}
 734		}
 735
 736	/* If we've entered an accepting state, back up; note that
 737	 * compressed tables have *already* done such backing up, so
 738	 * we needn't bother with it again.
 739	 */
 740	if ( need_backing_up && (fullspd || fulltbl) )
 741		{
 742		outc( '\n' );
 743		indent_puts( "if ( ! yy_is_jam )" );
 744		indent_up();
 745		indent_puts( "{" );
 746		gen_backing_up();
 747		indent_puts( "}" );
 748		indent_down();
 749		}
 750	}
 751
 752
 753/* Generate the code to find the start state. */
 754
 755void gen_start_state()
 756	{
 757	if ( fullspd )
 758		{
 759		if ( bol_needed )
 760			{
 761			indent_puts(
 762	"yy_current_state = yy_start_state_list[yy_start + YY_AT_BOL()];" );
 763			}
 764		else
 765			indent_puts(
 766			"yy_current_state = yy_start_state_list[yy_start];" );
 767		}
 768
 769	else
 770		{
 771		indent_puts( "yy_current_state = yy_start;" );
 772
 773		if ( bol_needed )
 774			indent_puts( "yy_current_state += YY_AT_BOL();" );
 775
 776		if ( reject )
 777			{
 778			/* Set up for storing up states. */
 779			indent_puts( "yy_state_ptr = yy_state_buf;" );
 780			indent_puts( "*yy_state_ptr++ = yy_current_state;" );
 781			}
 782		}
 783	}
 784
 785
 786/* gentabs - generate data statements for the transition tables */
 787
 788void gentabs()
 789	{
 790	int i, j, k, *accset, nacc, *acc_array, total_states;
 791	int end_of_buffer_action = num_rules + 1;
 792
 793	acc_array = allocate_integer_array( current_max_dfas );
 794	nummt = 0;
 795
 796	/* The compressed table format jams by entering the "jam state",
 797	 * losing information about the previous state in the process.
 798	 * In order to recover the previous state, we effectively need
 799	 * to keep backing-up information.
 800	 */
 801	++num_backing_up;
 802
 803	if ( reject )
 804		{
 805		/* Write out accepting list and pointer list.
 806		 *
 807		 * First we generate the "yy_acclist" array.  In the process,
 808		 * we compute the indices that will go into the "yy_accept"
 809		 * array, and save the indices in the dfaacc array.
 810		 */
 811		int EOB_accepting_list[2];
 812
 813		/* Set up accepting structures for the End Of Buffer state. */
 814		EOB_accepting_list[0] = 0;
 815		EOB_accepting_list[1] = end_of_buffer_action;
 816		accsiz[end_of_buffer_state] = 1;
 817		dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
 818
 819		out_str_dec( long_align ? C_long_decl : C_short_decl,
 820			"yy_acclist", MAX( numas, 1 ) + 1 );
 821
 822		j = 1;	/* index into "yy_acclist" array */
 823
 824		for ( i = 1; i <= lastdfa; ++i )
 825			{
 826			acc_array[i] = j;
 827
 828			if ( accsiz[i] != 0 )
 829				{
 830				accset = dfaacc[i].dfaacc_set;
 831				nacc = accsiz[i];
 832
 833				if ( trace )
 834					fprintf( stderr,
 835						_( "state # %d accepts: " ),
 836						i );
 837
 838				for ( k = 1; k <= nacc; ++k )
 839					{
 840					int accnum = accset[k];
 841
 842					++j;
 843
 844					if ( variable_trailing_context_rules &&
 845					  ! (accnum & YY_TRAILING_HEAD_MASK) &&
 846					   accnum > 0 && accnum <= num_rules &&
 847					  rule_type[accnum] == RULE_VARIABLE )
 848						{
 849						/* Special hack to flag
 850						 * accepting number as part
 851						 * of trailing context rule.
 852						 */
 853						accnum |= YY_TRAILING_MASK;
 854						}
 855
 856					mkdata( accnum );
 857
 858					if ( trace )
 859						{
 860						fprintf( stderr, "[%d]",
 861							accset[k] );
 862
 863						if ( k < nacc )
 864							fputs( ", ", stderr );
 865						else
 866							putc( '\n', stderr );
 867						}
 868					}
 869				}
 870			}
 871
 872		/* add accepting number for the "jam" state */
 873		acc_array[i] = j;
 874
 875		dataend();
 876		}
 877
 878	else
 879		{
 880		dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
 881
 882		for ( i = 1; i <= lastdfa; ++i )
 883			acc_array[i] = dfaacc[i].dfaacc_state;
 884
 885		/* add accepting number for jam state */
 886		acc_array[i] = 0;
 887		}
 888
 889	/* Spit out "yy_accept" array.  If we're doing "reject", it'll be
 890	 * pointers into the "yy_acclist" array.  Otherwise it's actual
 891	 * accepting numbers.  In either case, we just dump the numbers.
 892	 */
 893
 894	/* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays
 895	 * beginning at 0 and for "jam" state.
 896	 */
 897	k = lastdfa + 2;
 898
 899	if ( reject )
 900		/* We put a "cap" on the table associating lists of accepting
 901		 * numbers with state numbers.  This is needed because we tell
 902		 * where the end of an accepting list is by looking at where
 903		 * the list for the next state starts.
 904		 */
 905		++k;
 906
 907	out_str_dec( long_align ? C_long_decl : C_short_decl, "yy_accept", k );
 908
 909	for ( i = 1; i <= lastdfa; ++i )
 910		{
 911		mkdata( acc_array[i] );
 912
 913		if ( ! reject && trace && acc_array[i] )
 914			fprintf( stderr, _( "state # %d accepts: [%d]\n" ),
 915				i, acc_array[i] );
 916		}
 917
 918	/* Add entry for "jam" state. */
 919	mkdata( acc_array[i] );
 920
 921	if ( reject )
 922		/* Add "cap" for the list. */
 923		mkdata( acc_array[i] );
 924
 925	dataend();
 926
 927	if ( useecs )
 928		genecs();
 929
 930	if ( usemecs )
 931		{
 932		/* Write out meta-equivalence classes (used to index
 933		 * templates with).
 934		 */
 935
 936		if ( trace )
 937			fputs( _( "\n\nMeta-Equivalence Classes:\n" ),
 938			      stderr );
 939
 940		out_str_dec( C_int_decl, "yy_meta", numecs + 1 );
 941
 942		for ( i = 1; i <= numecs; ++i )
 943			{
 944			if ( trace )
 945				fprintf( stderr, "%d = %d\n",
 946					i, ABS( tecbck[i] ) );
 947
 948			mkdata( ABS( tecbck[i] ) );
 949			}
 950
 951		dataend();
 952		}
 953
 954	total_states = lastdfa + numtemps;
 955
 956	out_str_dec( (tblend >= MAX_SHORT || long_align) ?
 957			C_long_decl : C_short_decl,
 958		"yy_base", total_states + 1 );
 959
 960	for ( i = 1; i <= lastdfa; ++i )
 961		{
 962		int d = def[i];
 963
 964		if ( base[i] == JAMSTATE )
 965			base[i] = jambase;
 966
 967		if ( d == JAMSTATE )
 968			def[i] = jamstate;
 969
 970		else if ( d < 0 )
 971			{
 972			/* Template reference. */
 973			++tmpuses;
 974			def[i] = lastdfa - d + 1;
 975			}
 976
 977		mkdata( base[i] );
 978		}
 979
 980	/* Generate jam state's base index. */
 981	mkdata( base[i] );
 982
 983	for ( ++i /* skip jam state */; i <= total_states; ++i )
 984		{
 985		mkdata( base[i] );
 986		def[i] = jamstate;
 987		}
 988
 989	dataend();
 990
 991	out_str_dec( (total_states >= MAX_SHORT || long_align) ?
 992			C_long_decl : C_short_decl,
 993		"yy_def", total_states + 1 );
 994
 995	for ( i = 1; i <= total_states; ++i )
 996		mkdata( def[i] );
 997
 998	dataend();
 999
1000	out_str_dec( (total_states >= MAX_SHORT || long_align) ?
1001			C_long_decl : C_short_decl,
1002		"yy_nxt", tblend + 1 );
1003
1004	for ( i = 1; i <= tblend; ++i )
1005		{
1006		/* Note, the order of the following test is important.
1007		 * If chk[i] is 0, then nxt[i] is undefined.
1008		 */
1009		if ( chk[i] == 0 || nxt[i] == 0 )
1010			nxt[i] = jamstate;	/* new state is the JAM state */
1011
1012		mkdata( nxt[i] );
1013		}
1014
1015	dataend();
1016
1017	out_str_dec( (total_states >= MAX_SHORT || long_align) ?
1018			C_long_decl : C_short_decl,
1019		"yy_chk", tblend + 1 );
1020
1021	for ( i = 1; i <= tblend; ++i )
1022		{
1023		if ( chk[i] == 0 )
1024			++nummt;
1025
1026		mkdata( chk[i] );
1027		}
1028
1029	dataend();
1030	}
1031
1032
1033/* Write out a formatted string (with a secondary string argument) at the
1034 * current indentation level, adding a final newline.
1035 */
1036
1037void indent_put2s( fmt, arg )
1038char fmt[], arg[];
1039	{
1040	do_indent();
1041	out_str( fmt, arg );
1042	outn( "" );
1043	}
1044
1045
1046/* Write out a string at the current indentation level, adding a final
1047 * newline.
1048 */
1049
1050void indent_puts( str )
1051char str[];
1052	{
1053	do_indent();
1054	outn( str );
1055	}
1056
1057
1058/* make_tables - generate transition tables and finishes generating output file
1059 */
1060
1061void make_tables()
1062	{
1063	int i;
1064	int did_eof_rule = false;
1065
1066	skelout();
1067
1068	/* First, take care of YY_DO_BEFORE_ACTION depending on yymore
1069	 * being used.
1070	 */
1071	set_indent( 1 );
1072
1073	if ( yymore_used && ! yytext_is_array )
1074		{
1075		indent_puts( "yytext_ptr -= yy_more_len; \\" );
1076		indent_puts( "yyleng = (int) (yy_cp - yytext_ptr); \\" );
1077		}
1078
1079	else
1080		indent_puts( "yyleng = (int) (yy_cp - yy_bp); \\" );
1081
1082	/* Now also deal with copying yytext_ptr to yytext if needed. */
1083	skelout();
1084	if ( yytext_is_array )
1085		{
1086		if ( yymore_used )
1087			indent_puts(
1088				"if ( yyleng + yy_more_offset >= YYLMAX ) \\" );
1089		else
1090			indent_puts( "if ( yyleng >= YYLMAX ) \\" );
1091
1092		indent_up();
1093		indent_puts(
1094		"YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\" );
1095		indent_down();
1096
1097		if ( yymore_used )
1098			{
1099			indent_puts(
1100"yy_flex_strncpy( &yytext[yy_more_offset], yytext_ptr, yyleng + 1 ); \\" );
1101			indent_puts( "yyleng += yy_more_offset; \\" );
1102			indent_puts(
1103				"yy_prev_more_offset = yy_more_offset; \\" );
1104			indent_puts( "yy_more_offset = 0; \\" );
1105			}
1106		else
1107			{
1108			indent_puts(
1109		"yy_flex_strncpy( yytext, yytext_ptr, yyleng + 1 ); \\" );
1110			}
1111		}
1112
1113	set_indent( 0 );
1114
1115	skelout();
1116
1117
1118	out_dec( "#define YY_NUM_RULES %d\n", num_rules );
1119	out_dec( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
1120
1121	if ( fullspd )
1122		{
1123		/* Need to define the transet type as a size large
1124		 * enough to hold the biggest offset.
1125		 */
1126		int total_table_size = tblend + numecs + 1;
1127		char *trans_offset_type =
1128			(total_table_size >= MAX_SHORT || long_align) ?
1129				"long" : "short";
1130
1131		set_indent( 0 );
1132		indent_puts( "struct yy_trans_info" );
1133		indent_up();
1134		indent_puts( "{" ); 	/* } for vi */
1135
1136		if ( long_align )
1137			indent_puts( "long yy_verify;" );
1138		else
1139			indent_puts( "short yy_verify;" );
1140
1141		/* In cases where its sister yy_verify *is* a "yes, there is
1142		 * a transition", yy_nxt is the offset (in records) to the
1143		 * next state.  In most cases where there is no transition,
1144		 * the value of yy_nxt is irrelevant.  If yy_nxt is the -1th
1145		 * record of a state, though, then yy_nxt is the action number
1146		 * for that state.
1147		 */
1148
1149		indent_put2s( "%s yy_nxt;", trans_offset_type );
1150		indent_puts( "};" );
1151		indent_down();
1152		}
1153
1154	if ( fullspd )
1155		genctbl();
1156	else if ( fulltbl )
1157		genftbl();
1158	else
1159		gentabs();
1160
1161	/* Definitions for backing up.  We don't need them if REJECT
1162	 * is being used because then we use an alternative backin-up
1163	 * technique instead.
1164	 */
1165	if ( num_backing_up > 0 && ! reject )
1166		{
1167		if ( ! C_plus_plus )
1168			{
1169			indent_puts(
1170			"static yy_state_type yy_last_accepting_state;" );
1171			indent_puts(
1172				"static char *yy_last_accepting_cpos;\n" );
1173			}
1174		}
1175
1176	if ( nultrans )
1177		{
1178		out_str_dec( C_state_decl, "yy_NUL_trans", lastdfa + 1 );
1179
1180		for ( i = 1; i <= lastdfa; ++i )
1181			{
1182			if ( fullspd )
1183				out_dec( "    &yy_transition[%d],\n", base[i] );
1184			else
1185				mkdata( nultrans[i] );
1186			}
1187
1188		dataend();
1189		}
1190
1191	if ( ddebug )
1192		{ /* Spit out table mapping rules to line numbers. */
1193		if ( ! C_plus_plus )
1194			{
1195			indent_puts( "extern int yy_flex_debug;" );
1196			indent_puts( "int yy_flex_debug = 1;\n" );
1197			}
1198
1199		out_str_dec( long_align ? C_long_decl : C_short_decl,
1200			"yy_rule_linenum", num_rules );
1201		for ( i = 1; i < num_rules; ++i )
1202			mkdata( rule_linenum[i] );
1203		dataend();
1204		}
1205
1206	if ( reject )
1207		{
1208		/* Declare state buffer variables. */
1209		if ( ! C_plus_plus )
1210			{
1211			outn(
1212	"static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
1213			outn( "static char *yy_full_match;" );
1214			outn( "static int yy_lp;" );
1215			}
1216
1217		if ( variable_trailing_context_rules )
1218			{
1219			if ( ! C_plus_plus )
1220				{
1221				outn(
1222				"static int yy_looking_for_trail_begin = 0;" );
1223				outn( "static int yy_full_lp;" );
1224				outn( "static int *yy_full_state;" );
1225				}
1226
1227			out_hex( "#define YY_TRAILING_MASK 0x%x\n",
1228				(unsigned int) YY_TRAILING_MASK );
1229			out_hex( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
1230				(unsigned int) YY_TRAILING_HEAD_MASK );
1231			}
1232
1233		outn( "#define REJECT \\" );
1234		outn( "{ \\" );		/* } for vi */
1235		outn(
1236	"*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
1237		outn(
1238	"yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
1239
1240		if ( variable_trailing_context_rules )
1241			{
1242			outn(
1243		"yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
1244			outn(
1245		"yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
1246			outn(
1247	"yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
1248			}
1249
1250		outn( "++yy_lp; \\" );
1251		outn( "goto find_rule; \\" );
1252		/* { for vi */
1253		outn( "}" );
1254		}
1255
1256	else
1257		{
1258		outn(
1259		"/* The intent behind this definition is that it'll catch" );
1260		outn( " * any uses of REJECT which flex missed." );
1261		outn( " */" );
1262		outn( "#define REJECT reject_used_but_not_detected" );
1263		}
1264
1265	if ( yymore_used )
1266		{
1267		if ( ! C_plus_plus )
1268			{
1269			if ( yytext_is_array )
1270				{
1271				indent_puts( "static int yy_more_offset = 0;" );
1272				indent_puts(
1273					"static int yy_prev_more_offset = 0;" );
1274				}
1275			else
1276				{
1277				indent_puts( "static int yy_more_flag = 0;" );
1278				indent_puts( "static int yy_more_len = 0;" );
1279				}
1280			}
1281
1282		if ( yytext_is_array )
1283			{
1284			indent_puts(
1285	"#define yymore() (yy_more_offset = yy_flex_strlen( yytext ))" );
1286			indent_puts( "#define YY_NEED_STRLEN" );
1287			indent_puts( "#define YY_MORE_ADJ 0" );
1288			indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET \\" );
1289			indent_up();
1290			indent_puts( "{ \\" );
1291			indent_puts( "yy_more_offset = yy_prev_more_offset; \\" );
1292			indent_puts( "yyleng -= yy_more_offset; \\" );
1293			indent_puts( "}" );
1294			indent_down();
1295			}
1296		else
1297			{
1298			indent_puts( "#define yymore() (yy_more_flag = 1)" );
1299			indent_puts( "#define YY_MORE_ADJ yy_more_len" );
1300			indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET" );
1301			}
1302		}
1303
1304	else
1305		{
1306		indent_puts( "#define yymore() yymore_used_but_not_detected" );
1307		indent_puts( "#define YY_MORE_ADJ 0" );
1308		indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET" );
1309		}
1310
1311	if ( ! C_plus_plus )
1312		{
1313		if ( yytext_is_array )
1314			{
1315			outn( "#ifndef YYLMAX" );
1316			outn( "#define YYLMAX 8192" );
1317			outn( "#endif\n" );
1318			outn( "char yytext[YYLMAX];" );
1319			outn( "char *yytext_ptr;" );
1320			}
1321
1322		else
1323			outn( "char *yytext;" );
1324		}
1325
1326	out( &action_array[defs1_offset] );
1327
1328	line_directive_out( stdout, 0 );
1329
1330	skelout();
1331
1332	if ( ! C_plus_plus )
1333		{
1334		if ( use_read )
1335			{
1336			outn(
1337"\tif ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\" );
1338			outn(
1339		"\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" );
1340			}
1341
1342		else
1343			{
1344			outn(
1345			"\tif ( yy_current_buffer->yy_is_interactive ) \\" );
1346			outn( "\t\t{ \\" );
1347			outn( "\t\tint c = '*', n; \\" );
1348			outn( "\t\tfor ( n = 0; n < max_size && \\" );
1349	outn( "\t\t\t     (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\" );
1350			outn( "\t\t\tbuf[n] = (char) c; \\" );
1351			outn( "\t\tif ( c == '\\n' ) \\" );
1352			outn( "\t\t\tbuf[n++] = (char) c; \\" );
1353			outn( "\t\tif ( c == EOF && ferror( yyin ) ) \\" );
1354			outn(
1355	"\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\" );
1356			outn( "\t\tresult = n; \\" );
1357			outn( "\t\t} \\" );
1358			outn(
1359	"\telse if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \\" );
1360			outn( "\t\t  && ferror( yyin ) ) \\" );
1361			outn(
1362		"\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" );
1363			}
1364		}
1365
1366	skelout();
1367
1368	indent_puts( "#define YY_RULE_SETUP \\" );
1369	indent_up();
1370	if ( bol_needed )
1371		{
1372		indent_puts( "if ( yyleng > 0 ) \\" );
1373		indent_up();
1374		indent_puts( "yy_current_buffer->yy_at_bol = \\" );
1375		indent_puts( "\t\t(yytext[yyleng - 1] == '\\n'); \\" );
1376		indent_down();
1377		}
1378	indent_puts( "YY_USER_ACTION" );
1379	indent_down();
1380
1381	skelout();
1382
1383	/* Copy prolog to output file. */
1384	out( &action_array[prolog_offset] );
1385
1386	line_directive_out( stdout, 0 );
1387
1388	skelout();
1389
1390	set_indent( 2 );
1391
1392	if ( yymore_used && ! yytext_is_array )
1393		{
1394		indent_puts( "yy_more_len = 0;" );
1395		indent_puts( "if ( yy_more_flag )" );
1396		indent_up();
1397		indent_puts( "{" );
1398		indent_puts( "yy_more_len = yy_c_buf_p - yytext_ptr;" );
1399		indent_puts( "yy_more_flag = 0;" );
1400		indent_puts( "}" );
1401		indent_down();
1402		}
1403
1404	skelout();
1405
1406	gen_start_state();
1407
1408	/* Note, don't use any indentation. */
1409	outn( "yy_match:" );
1410	gen_next_match();
1411
1412	skelout();
1413	set_indent( 2 );
1414	gen_find_action();
1415
1416	skelout();
1417	if ( do_yylineno )
1418		{
1419		indent_puts( "if ( yy_act != YY_END_OF_BUFFER )" );
1420		indent_up();
1421		indent_puts( "{" );
1422		indent_puts( "int yyl;" );
1423		indent_puts( "for ( yyl = 0; yyl < yyleng; ++yyl )" );
1424		indent_up();
1425		indent_puts( "if ( yytext[yyl] == '\\n' )" );
1426		indent_up();
1427		indent_puts( "++yylineno;" );
1428		indent_down();
1429		indent_down();
1430		indent_puts( "}" );
1431		indent_down();
1432		}
1433
1434	skelout();
1435	if ( ddebug )
1436		{
1437		indent_puts( "if ( yy_flex_debug )" );
1438		indent_up();
1439
1440		indent_puts( "{" );
1441		indent_puts( "if ( yy_act == 0 )" );
1442		indent_up();
1443		indent_puts( C_plus_plus ?
1444			"cerr << \"--scanner backing up\\n\";" :
1445			"fprintf( stderr, \"--scanner backing up\\n\" );" );
1446		indent_down();
1447
1448		do_indent();
1449		out_dec( "else if ( yy_act < %d )\n", num_rules );
1450		indent_up();
1451
1452		if ( C_plus_plus )
1453			{
1454			indent_puts(
1455	"cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<" );
1456			indent_puts(
1457			"         \"(\\\"\" << yytext << \"\\\")\\n\";" );
1458			}
1459		else
1460			{
1461			indent_puts(
1462	"fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," );
1463
1464			indent_puts(
1465				"         yy_rule_linenum[yy_act], yytext );" );
1466			}
1467
1468		indent_down();
1469
1470		do_indent();
1471		out_dec( "else if ( yy_act == %d )\n", num_rules );
1472		indent_up();
1473
1474		if ( C_plus_plus )
1475			{
1476			indent_puts(
1477"cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";" );
1478			}
1479		else
1480			{
1481			indent_puts(
1482	"fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," );
1483			indent_puts( "         yytext );" );
1484			}
1485
1486		indent_down();
1487
1488		do_indent();
1489		out_dec( "else if ( yy_act == %d )\n", num_rules + 1 );
1490		indent_up();
1491
1492		indent_puts( C_plus_plus ?
1493			"cerr << \"--(end of buffer or a NUL)\\n\";" :
1494		"fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" );
1495
1496		indent_down();
1497
1498		do_indent();
1499		outn( "else" );
1500		indent_up();
1501
1502		if ( C_plus_plus )
1503			{
1504			indent_puts(
1505	"cerr << \"--EOF (start condition \" << YY_START << \")\\n\";" );
1506			}
1507		else
1508			{
1509			indent_puts(
1510	"fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );" );
1511			}
1512
1513		indent_down();
1514
1515		indent_puts( "}" );
1516		indent_down();
1517		}
1518
1519	/* Copy actions to output file. */
1520	skelout();
1521	indent_up();
1522	gen_bu_action();
1523	out( &action_array[action_offset] );
1524
1525	line_directive_out( stdout, 0 );
1526
1527	/* generate cases for any missing EOF rules */
1528	for ( i = 1; i <= lastsc; ++i )
1529		if ( ! sceof[i] )
1530			{
1531			do_indent();
1532			out_str( "case YY_STATE_EOF(%s):\n", scname[i] );
1533			did_eof_rule = true;
1534			}
1535
1536	if ( did_eof_rule )
1537		{
1538		indent_up();
1539		indent_puts( "yyterminate();" );
1540		indent_down();
1541		}
1542
1543
1544	/* Generate code for handling NUL's, if needed. */
1545
1546	/* First, deal with backing up and setting up yy_cp if the scanner
1547	 * finds that it should JAM on the NUL.
1548	 */
1549	skelout();
1550	set_indent( 4 );
1551
1552	if ( fullspd || fulltbl )
1553		indent_puts( "yy_cp = yy_c_buf_p;" );
1554
1555	else
1556		{ /* compressed table */
1557		if ( ! reject && ! interactive )
1558			{
1559			/* Do the guaranteed-needed backing up to figure
1560			 * out the match.
1561			 */
1562			indent_puts( "yy_cp = yy_last_accepting_cpos;" );
1563			indent_puts(
1564				"yy_current_state = yy_last_accepting_state;" );
1565			}
1566
1567		else
1568			/* Still need to initialize yy_cp, though
1569			 * yy_current_state was set up by
1570			 * yy_get_previous_state().
1571			 */
1572			indent_puts( "yy_cp = yy_c_buf_p;" );
1573		}
1574
1575
1576	/* Generate code for yy_get_previous_state(). */
1577	set_indent( 1 );
1578	skelout();
1579
1580	gen_start_state();
1581
1582	set_indent( 2 );
1583	skelout();
1584	gen_next_state( true );
1585
1586	set_indent( 1 );
1587	skelout();
1588	gen_NUL_trans();
1589
1590	skelout();
1591	if ( do_yylineno )
1592		{ /* update yylineno inside of unput() */
1593		indent_puts( "if ( c == '\\n' )" );
1594		indent_up();
1595		indent_puts( "--yylineno;" );
1596		indent_down();
1597		}
1598
1599	skelout();
1600	/* Update BOL and yylineno inside of input(). */
1601	if ( bol_needed )
1602		{
1603		indent_puts( "yy_current_buffer->yy_at_bol = (c == '\\n');" );
1604		if ( do_yylineno )
1605			{
1606			indent_puts( "if ( yy_current_buffer->yy_at_bol )" );
1607			indent_up();
1608			indent_puts( "++yylineno;" );
1609			indent_down();
1610			}
1611		}
1612
1613	else if ( do_yylineno )
1614		{
1615		indent_puts( "if ( c == '\\n' )" );
1616		indent_up();
1617		indent_puts( "++yylineno;" );
1618		indent_down();
1619		}
1620
1621	skelout();
1622
1623	/* Copy remainder of input to output. */
1624
1625	line_directive_out( stdout, 1 );
1626
1627	if ( sectnum == 3 )
1628		(void) flexscan(); /* copy remainder of input to output */
1629	}