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