Annotation of src/usr.bin/lex/gen.c, Revision 1.7
1.7 ! deraadt 1: /* $OpenBSD: gen.c,v 1.6 2001/11/19 19:02:14 mpech 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.7 ! deraadt 31: /* $Header: /cvs/src/usr.bin/lex/gen.c,v 1.6 2001/11/19 19:02:14 mpech 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 )
1.7 ! deraadt 608: (void) snprintf( char_map, sizeof char_map,
1.1 deraadt 609: "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)",
610: NUL_ec );
611: else
1.7 ! deraadt 612: (void) snprintf( char_map, sizeof char_map,
1.1 deraadt 613: "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", NUL_ec );
614: }
615:
616: else
1.7 ! deraadt 617: strlcpy( char_map, useecs ?
! 618: "yy_ec[YY_SC_TO_UI(*yy_cp)]" : "YY_SC_TO_UI(*yy_cp)",
! 619: sizeof char_map );
1.1 deraadt 620:
621: if ( worry_about_NULs && nultrans )
622: {
623: if ( ! fulltbl && ! fullspd )
624: /* Compressed tables back up *before* they match. */
625: gen_backing_up();
626:
627: indent_puts( "if ( *yy_cp )" );
628: indent_up();
629: indent_puts( "{" ); /* } for vi */
630: }
631:
632: if ( fulltbl )
633: indent_put2s(
634: "yy_current_state = yy_nxt[yy_current_state][%s];",
635: char_map );
636:
637: else if ( fullspd )
638: indent_put2s(
639: "yy_current_state += yy_current_state[%s].yy_nxt;",
640: char_map );
641:
642: else
643: gen_next_compressed_state( char_map );
644:
645: if ( worry_about_NULs && nultrans )
646: {
647: /* { for vi */
648: indent_puts( "}" );
649: indent_down();
650: indent_puts( "else" );
651: indent_up();
652: indent_puts(
653: "yy_current_state = yy_NUL_trans[yy_current_state];" );
654: indent_down();
655: }
656:
657: if ( fullspd || fulltbl )
658: gen_backing_up();
659:
660: if ( reject )
661: indent_puts( "*yy_state_ptr++ = yy_current_state;" );
662: }
663:
664:
665: /* Generate the code to make a NUL transition. */
666:
667: void gen_NUL_trans()
668: { /* NOTE - changes in here should be reflected in gen_next_match() */
669: /* Only generate a definition for "yy_cp" if we'll generate code
670: * that uses it. Otherwise lint and the like complain.
671: */
672: int need_backing_up = (num_backing_up > 0 && ! reject);
673:
674: if ( need_backing_up && (! nultrans || fullspd || fulltbl) )
675: /* We're going to need yy_cp lying around for the call
676: * below to gen_backing_up().
677: */
678: indent_puts( "register char *yy_cp = yy_c_buf_p;" );
679:
680: outc( '\n' );
681:
682: if ( nultrans )
683: {
684: indent_puts(
685: "yy_current_state = yy_NUL_trans[yy_current_state];" );
686: indent_puts( "yy_is_jam = (yy_current_state == 0);" );
687: }
688:
689: else if ( fulltbl )
690: {
691: do_indent();
692: out_dec( "yy_current_state = yy_nxt[yy_current_state][%d];\n",
693: NUL_ec );
694: indent_puts( "yy_is_jam = (yy_current_state <= 0);" );
695: }
696:
697: else if ( fullspd )
698: {
699: do_indent();
700: out_dec( "register int yy_c = %d;\n", NUL_ec );
701:
702: indent_puts(
703: "register yyconst struct yy_trans_info *yy_trans_info;\n" );
704: indent_puts(
705: "yy_trans_info = &yy_current_state[(unsigned int) yy_c];" );
706: indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
707:
708: indent_puts(
709: "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" );
710: }
711:
712: else
713: {
714: char NUL_ec_str[20];
715:
1.7 ! deraadt 716: (void) snprintf( NUL_ec_str, sizeof NUL_ec_str, "%d", NUL_ec );
1.1 deraadt 717: gen_next_compressed_state( NUL_ec_str );
718:
1.3 millert 719: do_indent();
720: out_dec( "yy_is_jam = (yy_current_state == %d);\n", jamstate );
721:
1.1 deraadt 722: if ( reject )
1.3 millert 723: {
724: /* Only stack this state if it's a transition we
725: * actually make. If we stack it on a jam, then
726: * the state stack and yy_c_buf_p get out of sync.
727: */
728: indent_puts( "if ( ! yy_is_jam )" );
729: indent_up();
1.1 deraadt 730: indent_puts( "*yy_state_ptr++ = yy_current_state;" );
1.3 millert 731: indent_down();
732: }
1.1 deraadt 733: }
734:
735: /* If we've entered an accepting state, back up; note that
736: * compressed tables have *already* done such backing up, so
737: * we needn't bother with it again.
738: */
739: if ( need_backing_up && (fullspd || fulltbl) )
740: {
741: outc( '\n' );
742: indent_puts( "if ( ! yy_is_jam )" );
743: indent_up();
744: indent_puts( "{" );
745: gen_backing_up();
746: indent_puts( "}" );
747: indent_down();
748: }
749: }
750:
751:
752: /* Generate the code to find the start state. */
753:
754: void gen_start_state()
755: {
756: if ( fullspd )
757: {
758: if ( bol_needed )
759: {
760: indent_puts(
761: "yy_current_state = yy_start_state_list[yy_start + YY_AT_BOL()];" );
762: }
763: else
764: indent_puts(
765: "yy_current_state = yy_start_state_list[yy_start];" );
766: }
767:
768: else
769: {
770: indent_puts( "yy_current_state = yy_start;" );
771:
772: if ( bol_needed )
773: indent_puts( "yy_current_state += YY_AT_BOL();" );
774:
775: if ( reject )
776: {
777: /* Set up for storing up states. */
778: indent_puts( "yy_state_ptr = yy_state_buf;" );
779: indent_puts( "*yy_state_ptr++ = yy_current_state;" );
780: }
781: }
782: }
783:
784:
785: /* gentabs - generate data statements for the transition tables */
786:
787: void gentabs()
788: {
789: int i, j, k, *accset, nacc, *acc_array, total_states;
790: int end_of_buffer_action = num_rules + 1;
791:
792: acc_array = allocate_integer_array( current_max_dfas );
793: nummt = 0;
794:
795: /* The compressed table format jams by entering the "jam state",
796: * losing information about the previous state in the process.
797: * In order to recover the previous state, we effectively need
798: * to keep backing-up information.
799: */
800: ++num_backing_up;
801:
802: if ( reject )
803: {
804: /* Write out accepting list and pointer list.
805: *
806: * First we generate the "yy_acclist" array. In the process,
807: * we compute the indices that will go into the "yy_accept"
808: * array, and save the indices in the dfaacc array.
809: */
810: int EOB_accepting_list[2];
811:
812: /* Set up accepting structures for the End Of Buffer state. */
813: EOB_accepting_list[0] = 0;
814: EOB_accepting_list[1] = end_of_buffer_action;
815: accsiz[end_of_buffer_state] = 1;
816: dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
817:
818: out_str_dec( long_align ? C_long_decl : C_short_decl,
819: "yy_acclist", MAX( numas, 1 ) + 1 );
820:
821: j = 1; /* index into "yy_acclist" array */
822:
823: for ( i = 1; i <= lastdfa; ++i )
824: {
825: acc_array[i] = j;
826:
827: if ( accsiz[i] != 0 )
828: {
829: accset = dfaacc[i].dfaacc_set;
830: nacc = accsiz[i];
831:
832: if ( trace )
833: fprintf( stderr,
834: _( "state # %d accepts: " ),
835: i );
836:
837: for ( k = 1; k <= nacc; ++k )
838: {
839: int accnum = accset[k];
840:
841: ++j;
842:
843: if ( variable_trailing_context_rules &&
844: ! (accnum & YY_TRAILING_HEAD_MASK) &&
845: accnum > 0 && accnum <= num_rules &&
846: rule_type[accnum] == RULE_VARIABLE )
847: {
848: /* Special hack to flag
849: * accepting number as part
850: * of trailing context rule.
851: */
852: accnum |= YY_TRAILING_MASK;
853: }
854:
855: mkdata( accnum );
856:
857: if ( trace )
858: {
859: fprintf( stderr, "[%d]",
860: accset[k] );
861:
862: if ( k < nacc )
863: fputs( ", ", stderr );
864: else
865: putc( '\n', stderr );
866: }
867: }
868: }
869: }
870:
871: /* add accepting number for the "jam" state */
872: acc_array[i] = j;
873:
874: dataend();
875: }
876:
877: else
878: {
879: dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
880:
881: for ( i = 1; i <= lastdfa; ++i )
882: acc_array[i] = dfaacc[i].dfaacc_state;
883:
884: /* add accepting number for jam state */
885: acc_array[i] = 0;
886: }
887:
888: /* Spit out "yy_accept" array. If we're doing "reject", it'll be
889: * pointers into the "yy_acclist" array. Otherwise it's actual
890: * accepting numbers. In either case, we just dump the numbers.
891: */
892:
893: /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays
894: * beginning at 0 and for "jam" state.
895: */
896: k = lastdfa + 2;
897:
898: if ( reject )
899: /* We put a "cap" on the table associating lists of accepting
900: * numbers with state numbers. This is needed because we tell
901: * where the end of an accepting list is by looking at where
902: * the list for the next state starts.
903: */
904: ++k;
905:
906: out_str_dec( long_align ? C_long_decl : C_short_decl, "yy_accept", k );
907:
908: for ( i = 1; i <= lastdfa; ++i )
909: {
910: mkdata( acc_array[i] );
911:
912: if ( ! reject && trace && acc_array[i] )
913: fprintf( stderr, _( "state # %d accepts: [%d]\n" ),
914: i, acc_array[i] );
915: }
916:
917: /* Add entry for "jam" state. */
918: mkdata( acc_array[i] );
919:
920: if ( reject )
921: /* Add "cap" for the list. */
922: mkdata( acc_array[i] );
923:
924: dataend();
925:
926: if ( useecs )
927: genecs();
928:
929: if ( usemecs )
930: {
931: /* Write out meta-equivalence classes (used to index
932: * templates with).
933: */
934:
935: if ( trace )
936: fputs( _( "\n\nMeta-Equivalence Classes:\n" ),
937: stderr );
938:
939: out_str_dec( C_int_decl, "yy_meta", numecs + 1 );
940:
941: for ( i = 1; i <= numecs; ++i )
942: {
943: if ( trace )
944: fprintf( stderr, "%d = %d\n",
945: i, ABS( tecbck[i] ) );
946:
947: mkdata( ABS( tecbck[i] ) );
948: }
949:
950: dataend();
951: }
952:
953: total_states = lastdfa + numtemps;
954:
955: out_str_dec( (tblend >= MAX_SHORT || long_align) ?
956: C_long_decl : C_short_decl,
957: "yy_base", total_states + 1 );
958:
959: for ( i = 1; i <= lastdfa; ++i )
960: {
1.6 mpech 961: int d = def[i];
1.1 deraadt 962:
963: if ( base[i] == JAMSTATE )
964: base[i] = jambase;
965:
966: if ( d == JAMSTATE )
967: def[i] = jamstate;
968:
969: else if ( d < 0 )
970: {
971: /* Template reference. */
972: ++tmpuses;
973: def[i] = lastdfa - d + 1;
974: }
975:
976: mkdata( base[i] );
977: }
978:
979: /* Generate jam state's base index. */
980: mkdata( base[i] );
981:
982: for ( ++i /* skip jam state */; i <= total_states; ++i )
983: {
984: mkdata( base[i] );
985: def[i] = jamstate;
986: }
987:
988: dataend();
989:
990: out_str_dec( (total_states >= MAX_SHORT || long_align) ?
991: C_long_decl : C_short_decl,
992: "yy_def", total_states + 1 );
993:
994: for ( i = 1; i <= total_states; ++i )
995: mkdata( def[i] );
996:
997: dataend();
998:
999: out_str_dec( (total_states >= MAX_SHORT || long_align) ?
1000: C_long_decl : C_short_decl,
1001: "yy_nxt", tblend + 1 );
1002:
1003: for ( i = 1; i <= tblend; ++i )
1004: {
1005: /* Note, the order of the following test is important.
1006: * If chk[i] is 0, then nxt[i] is undefined.
1007: */
1008: if ( chk[i] == 0 || nxt[i] == 0 )
1009: nxt[i] = jamstate; /* new state is the JAM state */
1010:
1011: mkdata( nxt[i] );
1012: }
1013:
1014: dataend();
1015:
1016: out_str_dec( (total_states >= MAX_SHORT || long_align) ?
1017: C_long_decl : C_short_decl,
1018: "yy_chk", tblend + 1 );
1019:
1020: for ( i = 1; i <= tblend; ++i )
1021: {
1022: if ( chk[i] == 0 )
1023: ++nummt;
1024:
1025: mkdata( chk[i] );
1026: }
1027:
1028: dataend();
1.4 deraadt 1029: free(acc_array);
1.1 deraadt 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:
1037: void indent_put2s( fmt, arg )
1038: char 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:
1050: void indent_puts( str )
1051: char str[];
1052: {
1053: do_indent();
1054: outn( str );
1055: }
1056:
1057:
1058: /* make_tables - generate transition tables and finishes generating output file
1059: */
1060:
1061: void make_tables()
1062: {
1.6 mpech 1063: int i;
1.1 deraadt 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:
1.3 millert 1073: if ( yymore_used && ! yytext_is_array )
1.1 deraadt 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: {
1.3 millert 1086: if ( yymore_used )
1087: indent_puts(
1088: "if ( yyleng + yy_more_offset >= YYLMAX ) \\" );
1089: else
1090: indent_puts( "if ( yyleng >= YYLMAX ) \\" );
1091:
1.1 deraadt 1092: indent_up();
1093: indent_puts(
1094: "YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\" );
1095: indent_down();
1.3 millert 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(
1.1 deraadt 1109: "yy_flex_strncpy( yytext, yytext_ptr, yyleng + 1 ); \\" );
1.3 millert 1110: }
1.1 deraadt 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: {
1.3 millert 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: }
1.1 deraadt 1280: }
1281:
1.3 millert 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: }
1.1 deraadt 1302: }
1303:
1304: else
1305: {
1306: indent_puts( "#define yymore() yymore_used_but_not_detected" );
1307: indent_puts( "#define YY_MORE_ADJ 0" );
1.3 millert 1308: indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET" );
1.1 deraadt 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:
1.3 millert 1392: if ( yymore_used && ! yytext_is_array )
1.1 deraadt 1393: {
1394: indent_puts( "yy_more_len = 0;" );
1395: indent_puts( "if ( yy_more_flag )" );
1396: indent_up();
1397: indent_puts( "{" );
1.3 millert 1398: indent_puts( "yy_more_len = yy_c_buf_p - yytext_ptr;" );
1.1 deraadt 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: }