|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Vern Paxson.
7: *
8: * The United States Government has rights in this work pursuant
9: * to contract no. DE-AC03-76SF00098 between the United States
10: * Department of Energy and the University of California.
11: *
12: * Redistribution and use in source and binary forms are permitted provided
13: * that: (1) source distributions retain this entire copyright notice and
14: * comment, and (2) distributions including binaries display the following
15: * acknowledgement: ``This product includes software developed by the
16: * University of California, Berkeley and its contributors'' in the
17: * documentation or other materials provided with the distribution and in
18: * all advertising materials mentioning features or use of this software.
19: * Neither the name of the University nor the names of its contributors may
20: * be used to endorse or promote products derived from this software without
21: * specific prior written permission.
22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
23: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
24: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25: */
26:
27: #ifndef lint
28: static char sccsid[] = "@(#)gen.c 5.2 (Berkeley) 6/18/90";
29: #endif /* not lint */
30:
31: /* gen - actual generation (writing) of flex scanners */
32:
33: #include "flexdef.h"
34:
35: /* declare functions that have forward references */
36:
37: void gen_next_state PROTO((int));
38: void genecs PROTO(());
39: void indent_put2s PROTO((char [], char []));
40: void indent_puts PROTO((char []));
41:
42:
43: static int indent_level = 0; /* each level is 4 spaces */
44:
45: #define indent_up() (++indent_level)
46: #define indent_down() (--indent_level)
47: #define set_indent(indent_val) indent_level = indent_val
48:
49: /* *everything* is done in terms of arrays starting at 1, so provide
50: * a null entry for the zero element of all C arrays
51: */
52: static char C_short_decl[] = "static const short int %s[%d] =\n { 0,\n";
53: static char C_long_decl[] = "static const long int %s[%d] =\n { 0,\n";
54: static char C_state_decl[] =
55: "static const yy_state_type %s[%d] =\n { 0,\n";
56:
57:
58: /* indent to the current level */
59:
60: void do_indent()
61:
62: {
63: register int i = indent_level * 4;
64:
65: while ( i >= 8 )
66: {
67: putchar( '\t' );
68: i -= 8;
69: }
70:
71: while ( i > 0 )
72: {
73: putchar( ' ' );
74: --i;
75: }
76: }
77:
78:
79: /* generate the code to keep backtracking information */
80:
81: void gen_backtracking()
82:
83: {
84: if ( reject || num_backtracking == 0 )
85: return;
86:
87: if ( fullspd )
88: indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
89: else
90: indent_puts( "if ( yy_accept[yy_current_state] )" );
91:
92: indent_up();
93: indent_puts( "{" );
94: indent_puts( "yy_last_accepting_state = yy_current_state;" );
95: indent_puts( "yy_last_accepting_cpos = yy_cp;" );
96: indent_puts( "}" );
97: indent_down();
98: }
99:
100:
101: /* generate the code to perform the backtrack */
102:
103: void gen_bt_action()
104:
105: {
106: if ( reject || num_backtracking == 0 )
107: return;
108:
109: set_indent( 3 );
110:
111: indent_puts( "case 0: /* must backtrack */" );
112: indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
113: indent_puts( "*yy_cp = yy_hold_char;" );
114:
115: if ( fullspd || fulltbl )
116: indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
117: else
118: /* backtracking info for compressed tables is taken \after/
119: * yy_cp has been incremented for the next state
120: */
121: indent_puts( "yy_cp = yy_last_accepting_cpos;" );
122:
123: indent_puts( "yy_current_state = yy_last_accepting_state;" );
124: indent_puts( "goto yy_find_action;" );
125: putchar( '\n' );
126:
127: set_indent( 0 );
128: }
129:
130:
131: /* genctbl - generates full speed compressed transition table
132: *
133: * synopsis
134: * genctbl();
135: */
136:
137: void genctbl()
138:
139: {
140: register int i;
141: int end_of_buffer_action = num_rules + 1;
142:
143: /* table of verify for transition and offset to next state */
144: printf( "static const struct yy_trans_info yy_transition[%d] =\n",
145: tblend + numecs + 1 );
146: printf( " {\n" );
147:
148: /* We want the transition to be represented as the offset to the
149: * next state, not the actual state number, which is what it currently is.
150: * The offset is base[nxt[i]] - base[chk[i]]. That's just the
151: * difference between the starting points of the two involved states
152: * (to - from).
153: *
154: * first, though, we need to find some way to put in our end-of-buffer
155: * flags and states. We do this by making a state with absolutely no
156: * transitions. We put it at the end of the table.
157: */
158: /* at this point, we're guaranteed that there's enough room in nxt[]
159: * and chk[] to hold tblend + numecs entries. We need just two slots.
160: * One for the action and one for the end-of-buffer transition. We
161: * now *assume* that we're guaranteed the only character we'll try to
162: * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to
163: * make sure there's room for jam entries for other characters.
164: */
165:
166: base[lastdfa + 1] = tblend + 2;
167: nxt[tblend + 1] = end_of_buffer_action;
168: chk[tblend + 1] = numecs + 1;
169: chk[tblend + 2] = 1; /* anything but EOB */
170: nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */
171:
172: /* make sure every state has a end-of-buffer transition and an action # */
173: for ( i = 0; i <= lastdfa; ++i )
174: {
175: register int anum = dfaacc[i].dfaacc_state;
176:
177: chk[base[i]] = EOB_POSITION;
178: chk[base[i] - 1] = ACTION_POSITION;
179: nxt[base[i] - 1] = anum; /* action number */
180: }
181:
182: for ( i = 0; i <= tblend; ++i )
183: {
184: if ( chk[i] == EOB_POSITION )
185: transition_struct_out( 0, base[lastdfa + 1] - i );
186:
187: else if ( chk[i] == ACTION_POSITION )
188: transition_struct_out( 0, nxt[i] );
189:
190: else if ( chk[i] > numecs || chk[i] == 0 )
191: transition_struct_out( 0, 0 ); /* unused slot */
192:
193: else /* verify, transition */
194: transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) );
195: }
196:
197:
198: /* here's the final, end-of-buffer state */
199: transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
200: transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
201:
202: printf( " };\n" );
203: printf( "\n" );
204:
205: /* table of pointers to start states */
206: printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
207: lastsc * 2 + 1 );
208: printf( " {\n" );
209:
210: for ( i = 0; i <= lastsc * 2; ++i )
211: printf( " &yy_transition[%d],\n", base[i] );
212:
213: dataend();
214:
215: if ( useecs )
216: genecs();
217: }
218:
219:
220: /* generate equivalence-class tables */
221:
222: void genecs()
223:
224: {
225: register int i, j;
226: static char C_char_decl[] = "static const %s %s[%d] =\n { 0,\n";
227: int numrows;
228: Char clower();
229:
230: if ( numecs < csize )
231: printf( C_char_decl, "YY_CHAR", "yy_ec", csize );
232: else
233: printf( C_char_decl, "short", "yy_ec", csize );
234:
235: for ( i = 1; i < csize; ++i )
236: {
237: if ( caseins && (i >= 'A') && (i <= 'Z') )
238: ecgroup[i] = ecgroup[clower( i )];
239:
240: ecgroup[i] = abs( ecgroup[i] );
241: mkdata( ecgroup[i] );
242: }
243:
244: dataend();
245:
246: if ( trace )
247: {
248: char *readable_form();
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", readable_form( i ), ecgroup[i] );
259:
260: putc( ' ', stderr );
261: }
262:
263: putc( '\n', stderr );
264: }
265: }
266: }
267:
268:
269: /* generate the code to find the action number */
270:
271: void gen_find_action()
272:
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: puts( "find_rule: /* we branch to this label when backtracking */" );
286:
287: indent_puts( "for ( ; ; ) /* until we find what rule we matched */" );
288:
289: indent_up();
290:
291: indent_puts( "{" );
292:
293: indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
294: indent_up();
295: indent_puts( "{" );
296: indent_puts( "yy_act = yy_acclist[yy_lp];" );
297:
298: if ( variable_trailing_context_rules )
299: {
300: indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
301: indent_puts( " yy_looking_for_trail_begin )" );
302: indent_up();
303: indent_puts( "{" );
304:
305: indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" );
306: indent_up();
307: indent_puts( "{" );
308: indent_puts( "yy_looking_for_trail_begin = 0;" );
309: indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );
310: indent_puts( "break;" );
311: indent_puts( "}" );
312: indent_down();
313:
314: indent_puts( "}" );
315: indent_down();
316:
317: indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );
318: indent_up();
319: indent_puts( "{" );
320: indent_puts(
321: "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );
322: indent_puts(
323: "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );
324:
325: if ( real_reject )
326: {
327: /* remember matched text in case we back up due to REJECT */
328: indent_puts( "yy_full_match = yy_cp;" );
329: indent_puts( "yy_full_state = yy_state_ptr;" );
330: indent_puts( "yy_full_lp = yy_lp;" );
331: }
332:
333: indent_puts( "}" );
334: indent_down();
335:
336: indent_puts( "else" );
337: indent_up();
338: indent_puts( "{" );
339: indent_puts( "yy_full_match = yy_cp;" );
340: indent_puts( "yy_full_state = yy_state_ptr;" );
341: indent_puts( "yy_full_lp = yy_lp;" );
342: indent_puts( "break;" );
343: indent_puts( "}" );
344: indent_down();
345:
346: indent_puts( "++yy_lp;" );
347: indent_puts( "goto find_rule;" );
348: }
349:
350: else
351: {
352: /* remember matched text in case we back up due to trailing context
353: * plus REJECT
354: */
355: indent_up();
356: indent_puts( "{" );
357: indent_puts( "yy_full_match = yy_cp;" );
358: indent_puts( "break;" );
359: indent_puts( "}" );
360: indent_down();
361: }
362:
363: indent_puts( "}" );
364: indent_down();
365:
366: indent_puts( "--yy_cp;" );
367:
368: /* we could consolidate the following two lines with those at
369: * the beginning, but at the cost of complaints that we're
370: * branching inside a loop
371: */
372: indent_puts( "yy_current_state = *--yy_state_ptr;" );
373: indent_puts( "yy_lp = yy_accept[yy_current_state];" );
374:
375: indent_puts( "}" );
376:
377: indent_down();
378: }
379:
380: else
381: /* compressed */
382: indent_puts( "yy_act = yy_accept[yy_current_state];" );
383: }
384:
385:
386: /* genftbl - generates full transition table
387: *
388: * synopsis
389: * genftbl();
390: */
391:
392: void genftbl()
393:
394: {
395: register int i;
396: int end_of_buffer_action = num_rules + 1;
397:
398: printf( C_short_decl, "yy_accept", lastdfa + 1 );
399:
400:
401: dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
402:
403: for ( i = 1; i <= lastdfa; ++i )
404: {
405: register int anum = dfaacc[i].dfaacc_state;
406:
407: mkdata( anum );
408:
409: if ( trace && anum )
410: fprintf( stderr, "state # %d accepts: [%d]\n", i, anum );
411: }
412:
413: dataend();
414:
415: if ( useecs )
416: genecs();
417:
418: /* don't have to dump the actual full table entries - they were created
419: * on-the-fly
420: */
421: }
422:
423:
424: /* generate the code to find the next compressed-table state */
425:
426: void gen_next_compressed_state( char_map )
427: char *char_map;
428:
429: {
430: indent_put2s( "register YY_CHAR yy_c = %s;", char_map );
431:
432: /* save the backtracking info \before/ computing the next state
433: * because we always compute one more state than needed - we
434: * always proceed until we reach a jam state
435: */
436: gen_backtracking();
437:
438: indent_puts(
439: "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );
440: indent_up();
441: indent_puts( "{" );
442: indent_puts( "yy_current_state = yy_def[yy_current_state];" );
443:
444: if ( usemecs )
445: {
446: /* we've arrange it so that templates are never chained
447: * to one another. This means we can afford make a
448: * very simple test to see if we need to convert to
449: * yy_c's meta-equivalence class without worrying
450: * about erroneously looking up the meta-equivalence
451: * class twice
452: */
453: do_indent();
454: /* lastdfa + 2 is the beginning of the templates */
455: printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
456:
457: indent_up();
458: indent_puts( "yy_c = yy_meta[yy_c];" );
459: indent_down();
460: }
461:
462: indent_puts( "}" );
463: indent_down();
464:
465: indent_puts(
466: "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" );
467: }
468:
469:
470: /* generate the code to find the next match */
471:
472: void gen_next_match()
473:
474: {
475: /* NOTE - changes in here should be reflected in gen_next_state() and
476: * gen_NUL_trans()
477: */
478: char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
479: char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp";
480:
481: if ( fulltbl )
482: {
483: indent_put2s(
484: "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
485: char_map );
486:
487: indent_up();
488:
489: if ( num_backtracking > 0 )
490: {
491: indent_puts( "{" );
492: gen_backtracking();
493: putchar( '\n' );
494: }
495:
496: indent_puts( "++yy_cp;" );
497:
498: if ( num_backtracking > 0 )
499: indent_puts( "}" );
500:
501: indent_down();
502:
503: putchar( '\n' );
504: indent_puts( "yy_current_state = -yy_current_state;" );
505: }
506:
507: else if ( fullspd )
508: {
509: indent_puts( "{" );
510: indent_puts( "register const struct yy_trans_info *yy_trans_info;\n" );
511: indent_puts( "register YY_CHAR yy_c;\n" );
512: indent_put2s( "for ( yy_c = %s;", char_map );
513: indent_puts(
514: " (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" );
515: indent_put2s( " yy_c = %s )", char_map_2 );
516:
517: indent_up();
518:
519: if ( num_backtracking > 0 )
520: indent_puts( "{" );
521:
522: indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
523:
524: if ( num_backtracking > 0 )
525: {
526: putchar( '\n' );
527: gen_backtracking();
528: indent_puts( "}" );
529: }
530:
531: indent_down();
532: indent_puts( "}" );
533: }
534:
535: else
536: { /* compressed */
537: indent_puts( "do" );
538:
539: indent_up();
540: indent_puts( "{" );
541:
542: gen_next_state( false );
543:
544: indent_puts( "++yy_cp;" );
545:
546: indent_puts( "}" );
547: indent_down();
548:
549: do_indent();
550:
551: if ( interactive )
552: printf( "while ( yy_base[yy_current_state] != %d );\n", jambase );
553: else
554: printf( "while ( yy_current_state != %d );\n", jamstate );
555:
556: if ( ! reject && ! interactive )
557: {
558: /* do the guaranteed-needed backtrack to figure out the match */
559: indent_puts( "yy_cp = yy_last_accepting_cpos;" );
560: indent_puts( "yy_current_state = yy_last_accepting_state;" );
561: }
562: }
563: }
564:
565:
566: /* generate the code to find the next state */
567:
568: void gen_next_state( worry_about_NULs )
569: int worry_about_NULs;
570:
571: { /* NOTE - changes in here should be reflected in get_next_match() */
572: char char_map[256];
573:
574: if ( worry_about_NULs && ! nultrans )
575: {
576: if ( useecs )
577: (void) sprintf( char_map, "(*yy_cp ? yy_ec[*yy_cp] : %d)", NUL_ec );
578: else
579: (void) sprintf( char_map, "(*yy_cp ? *yy_cp : %d)", NUL_ec );
580: }
581:
582: else
583: (void) strcpy( char_map, useecs ? "yy_ec[*yy_cp]" : "*yy_cp" );
584:
585: if ( worry_about_NULs && nultrans )
586: {
587: if ( ! fulltbl && ! fullspd )
588: /* compressed tables backtrack *before* they match */
589: gen_backtracking();
590:
591: indent_puts( "if ( *yy_cp )" );
592: indent_up();
593: indent_puts( "{" );
594: }
595:
596: if ( fulltbl )
597: indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];",
598: char_map );
599:
600: else if ( fullspd )
601: indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;",
602: char_map );
603:
604: else
605: gen_next_compressed_state( char_map );
606:
607: if ( worry_about_NULs && nultrans )
608: {
609: indent_puts( "}" );
610: indent_down();
611: indent_puts( "else" );
612: indent_up();
613: indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" );
614: indent_down();
615: }
616:
617: if ( fullspd || fulltbl )
618: gen_backtracking();
619:
620: if ( reject )
621: indent_puts( "*yy_state_ptr++ = yy_current_state;" );
622: }
623:
624:
625: /* generate the code to make a NUL transition */
626:
627: void gen_NUL_trans()
628:
629: { /* NOTE - changes in here should be reflected in get_next_match() */
630: int need_backtracking = (num_backtracking > 0 && ! reject);
631:
632: if ( need_backtracking )
633: /* we'll need yy_cp lying around for the gen_backtracking() */
634: indent_puts( "register YY_CHAR *yy_cp = yy_c_buf_p;" );
635:
636: putchar( '\n' );
637:
638: if ( nultrans )
639: {
640: indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" );
641: indent_puts( "yy_is_jam = (yy_current_state == 0);" );
642: }
643:
644: else if ( fulltbl )
645: {
646: do_indent();
647: printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n",
648: NUL_ec );
649: indent_puts( "yy_is_jam = (yy_current_state <= 0);" );
650: }
651:
652: else if ( fullspd )
653: {
654: do_indent();
655: printf( "register int yy_c = %d;\n", NUL_ec );
656:
657: indent_puts(
658: "register const struct yy_trans_info *yy_trans_info;\n" );
659: indent_puts( "yy_trans_info = &yy_current_state[yy_c];" );
660: indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
661:
662: indent_puts( "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" );
663: }
664:
665: else
666: {
667: char NUL_ec_str[20];
668:
669: (void) sprintf( NUL_ec_str, "%d", NUL_ec );
670: gen_next_compressed_state( NUL_ec_str );
671:
672: if ( reject )
673: indent_puts( "*yy_state_ptr++ = yy_current_state;" );
674:
675: do_indent();
676:
677: if ( interactive )
678: printf( "yy_is_jam = (yy_base[yy_current_state] == %d);\n",
679: jambase );
680: else
681: printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate );
682: }
683:
684: /* if we've entered an accepting state, backtrack; note that
685: * compressed tables have *already* done such backtracking, so
686: * we needn't bother with it again
687: */
688: if ( need_backtracking && (fullspd || fulltbl) )
689: {
690: putchar( '\n' );
691: indent_puts( "if ( ! yy_is_jam )" );
692: indent_up();
693: indent_puts( "{" );
694: gen_backtracking();
695: indent_puts( "}" );
696: indent_down();
697: }
698: }
699:
700:
701: /* generate the code to find the start state */
702:
703: void gen_start_state()
704:
705: {
706: if ( fullspd )
707: indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];",
708: bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" );
709:
710: else
711: {
712: indent_puts( "yy_current_state = yy_start;" );
713:
714: if ( bol_needed )
715: {
716: indent_puts( "if ( yy_bp[-1] == '\\n' )" );
717: indent_up();
718: indent_puts( "++yy_current_state;" );
719: indent_down();
720: }
721:
722: if ( reject )
723: {
724: /* set up for storing up states */
725: indent_puts( "yy_state_ptr = yy_state_buf;" );
726: indent_puts( "*yy_state_ptr++ = yy_current_state;" );
727: }
728: }
729: }
730:
731:
732: /* gentabs - generate data statements for the transition tables
733: *
734: * synopsis
735: * gentabs();
736: */
737:
738: void gentabs()
739:
740: {
741: int i, j, k, *accset, nacc, *acc_array, total_states;
742: int end_of_buffer_action = num_rules + 1;
743:
744: /* *everything* is done in terms of arrays starting at 1, so provide
745: * a null entry for the zero element of all C arrays
746: */
747: static char C_char_decl[] =
748: "static const YY_CHAR %s[%d] =\n { 0,\n";
749:
750: acc_array = allocate_integer_array( current_max_dfas );
751: nummt = 0;
752:
753: /* the compressed table format jams by entering the "jam state",
754: * losing information about the previous state in the process.
755: * In order to recover the previous state, we effectively need
756: * to keep backtracking information.
757: */
758: ++num_backtracking;
759:
760: if ( reject )
761: {
762: /* write out accepting list and pointer list
763: *
764: * first we generate the "yy_acclist" array. In the process, we compute
765: * the indices that will go into the "yy_accept" array, and save the
766: * indices in the dfaacc array
767: */
768: int EOB_accepting_list[2];
769:
770: /* set up accepting structures for the End Of Buffer state */
771: EOB_accepting_list[0] = 0;
772: EOB_accepting_list[1] = end_of_buffer_action;
773: accsiz[end_of_buffer_state] = 1;
774: dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
775:
776: printf( C_short_decl, "yy_acclist", max( numas, 1 ) + 1 );
777:
778: j = 1; /* index into "yy_acclist" array */
779:
780: for ( i = 1; i <= lastdfa; ++i )
781: {
782: acc_array[i] = j;
783:
784: if ( accsiz[i] != 0 )
785: {
786: accset = dfaacc[i].dfaacc_set;
787: nacc = accsiz[i];
788:
789: if ( trace )
790: fprintf( stderr, "state # %d accepts: ", i );
791:
792: for ( k = 1; k <= nacc; ++k )
793: {
794: int accnum = accset[k];
795:
796: ++j;
797:
798: if ( variable_trailing_context_rules &&
799: ! (accnum & YY_TRAILING_HEAD_MASK) &&
800: accnum > 0 &&
801: rule_type[accnum] == RULE_VARIABLE )
802: {
803: /* special hack to flag accepting number as part
804: * of trailing context rule
805: */
806: accnum |= YY_TRAILING_MASK;
807: }
808:
809: mkdata( accnum );
810:
811: if ( trace )
812: {
813: fprintf( stderr, "[%d]", accset[k] );
814:
815: if ( k < nacc )
816: fputs( ", ", stderr );
817: else
818: putc( '\n', stderr );
819: }
820: }
821: }
822: }
823:
824: /* add accepting number for the "jam" state */
825: acc_array[i] = j;
826:
827: dataend();
828: }
829:
830: else
831: {
832: dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
833:
834: for ( i = 1; i <= lastdfa; ++i )
835: acc_array[i] = dfaacc[i].dfaacc_state;
836:
837: /* add accepting number for jam state */
838: acc_array[i] = 0;
839: }
840:
841: /* spit out "yy_accept" array. If we're doing "reject", it'll be pointers
842: * into the "yy_acclist" array. Otherwise it's actual accepting numbers.
843: * In either case, we just dump the numbers.
844: */
845:
846: /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays
847: * beginning at 0 and for "jam" state
848: */
849: k = lastdfa + 2;
850:
851: if ( reject )
852: /* we put a "cap" on the table associating lists of accepting
853: * numbers with state numbers. This is needed because we tell
854: * where the end of an accepting list is by looking at where
855: * the list for the next state starts.
856: */
857: ++k;
858:
859: printf( C_short_decl, "yy_accept", k );
860:
861: for ( i = 1; i <= lastdfa; ++i )
862: {
863: mkdata( acc_array[i] );
864:
865: if ( ! reject && trace && acc_array[i] )
866: fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] );
867: }
868:
869: /* add entry for "jam" state */
870: mkdata( acc_array[i] );
871:
872: if ( reject )
873: /* add "cap" for the list */
874: mkdata( acc_array[i] );
875:
876: dataend();
877:
878: if ( useecs )
879: genecs();
880:
881: if ( usemecs )
882: {
883: /* write out meta-equivalence classes (used to index templates with) */
884:
885: if ( trace )
886: fputs( "\n\nMeta-Equivalence Classes:\n", stderr );
887:
888: printf( C_char_decl, "yy_meta", numecs + 1 );
889:
890: for ( i = 1; i <= numecs; ++i )
891: {
892: if ( trace )
893: fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) );
894:
895: mkdata( abs( tecbck[i] ) );
896: }
897:
898: dataend();
899: }
900:
901: total_states = lastdfa + numtemps;
902:
903: printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
904: "yy_base", total_states + 1 );
905:
906: for ( i = 1; i <= lastdfa; ++i )
907: {
908: register int d = def[i];
909:
910: if ( base[i] == JAMSTATE )
911: base[i] = jambase;
912:
913: if ( d == JAMSTATE )
914: def[i] = jamstate;
915:
916: else if ( d < 0 )
917: {
918: /* template reference */
919: ++tmpuses;
920: def[i] = lastdfa - d + 1;
921: }
922:
923: mkdata( base[i] );
924: }
925:
926: /* generate jam state's base index */
927: mkdata( base[i] );
928:
929: for ( ++i /* skip jam state */; i <= total_states; ++i )
930: {
931: mkdata( base[i] );
932: def[i] = jamstate;
933: }
934:
935: dataend();
936:
937: printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
938: "yy_def", total_states + 1 );
939:
940: for ( i = 1; i <= total_states; ++i )
941: mkdata( def[i] );
942:
943: dataend();
944:
945: printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
946: "yy_nxt", tblend + 1 );
947:
948: for ( i = 1; i <= tblend; ++i )
949: {
950: if ( nxt[i] == 0 || chk[i] == 0 )
951: nxt[i] = jamstate; /* new state is the JAM state */
952:
953: mkdata( nxt[i] );
954: }
955:
956: dataend();
957:
958: printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
959: "yy_chk", tblend + 1 );
960:
961: for ( i = 1; i <= tblend; ++i )
962: {
963: if ( chk[i] == 0 )
964: ++nummt;
965:
966: mkdata( chk[i] );
967: }
968:
969: dataend();
970: }
971:
972:
973: /* write out a formatted string (with a secondary string argument) at the
974: * current indentation level, adding a final newline
975: */
976:
977: void indent_put2s( fmt, arg )
978: char fmt[], arg[];
979:
980: {
981: do_indent();
982: printf( fmt, arg );
983: putchar( '\n' );
984: }
985:
986:
987: /* write out a string at the current indentation level, adding a final
988: * newline
989: */
990:
991: void indent_puts( str )
992: char str[];
993:
994: {
995: do_indent();
996: puts( str );
997: }
998:
999:
1000: /* make_tables - generate transition tables
1001: *
1002: * synopsis
1003: * make_tables();
1004: *
1005: * Generates transition tables and finishes generating output file
1006: */
1007:
1008: void make_tables()
1009:
1010: {
1011: register int i;
1012: int did_eof_rule = false;
1013:
1014: skelout();
1015:
1016: /* first, take care of YY_DO_BEFORE_ACTION depending on yymore being used */
1017: set_indent( 2 );
1018:
1019: if ( yymore_used )
1020: {
1021: indent_puts( "yytext -= yy_more_len; \\" );
1022: indent_puts( "yyleng = yy_cp - yytext; \\" );
1023: }
1024:
1025: else
1026: indent_puts( "yyleng = yy_cp - yy_bp; \\" );
1027:
1028: set_indent( 0 );
1029:
1030: skelout();
1031:
1032:
1033: printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
1034:
1035: if ( fullspd )
1036: { /* need to define the transet type as a size large
1037: * enough to hold the biggest offset
1038: */
1039: int total_table_size = tblend + numecs + 1;
1040: char *trans_offset_type =
1041: total_table_size > MAX_SHORT ? "long" : "short";
1042:
1043: set_indent( 0 );
1044: indent_puts( "struct yy_trans_info" );
1045: indent_up();
1046: indent_puts( "{" );
1047: indent_puts( "short yy_verify;" );
1048:
1049: /* in cases where its sister yy_verify *is* a "yes, there is a
1050: * transition", yy_nxt is the offset (in records) to the next state.
1051: * In most cases where there is no transition, the value of yy_nxt
1052: * is irrelevant. If yy_nxt is the -1th record of a state, though,
1053: * then yy_nxt is the action number for that state
1054: */
1055:
1056: indent_put2s( "%s yy_nxt;", trans_offset_type );
1057: indent_puts( "};" );
1058: indent_down();
1059:
1060: indent_puts( "typedef const struct yy_trans_info *yy_state_type;" );
1061: }
1062:
1063: else
1064: indent_puts( "typedef int yy_state_type;" );
1065:
1066: if ( fullspd )
1067: genctbl();
1068:
1069: else if ( fulltbl )
1070: genftbl();
1071:
1072: else
1073: gentabs();
1074:
1075: if ( num_backtracking > 0 )
1076: {
1077: indent_puts( "static yy_state_type yy_last_accepting_state;" );
1078: indent_puts( "static YY_CHAR *yy_last_accepting_cpos;\n" );
1079: }
1080:
1081: if ( nultrans )
1082: {
1083: printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 );
1084:
1085: for ( i = 1; i <= lastdfa; ++i )
1086: {
1087: if ( fullspd )
1088: {
1089: if ( nultrans )
1090: printf( " &yy_transition[%d],\n", base[i] );
1091: else
1092: printf( " 0,\n" );
1093: }
1094:
1095: else
1096: mkdata( nultrans[i] );
1097: }
1098:
1099: dataend();
1100: }
1101:
1102: if ( ddebug )
1103: { /* spit out table mapping rules to line numbers */
1104: indent_puts( "extern int yy_flex_debug;" );
1105: indent_puts( "int yy_flex_debug = 1;\n" );
1106:
1107: printf( C_short_decl, "yy_rule_linenum", num_rules );
1108: for ( i = 1; i < num_rules; ++i )
1109: mkdata( rule_linenum[i] );
1110: dataend();
1111: }
1112:
1113: if ( reject )
1114: {
1115: /* declare state buffer variables */
1116: puts(
1117: "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
1118: puts( "static YY_CHAR *yy_full_match;" );
1119: puts( "static int yy_lp;" );
1120:
1121: if ( variable_trailing_context_rules )
1122: {
1123: puts( "static int yy_looking_for_trail_begin = 0;" );
1124: puts( "static int yy_full_lp;" );
1125: puts( "static int *yy_full_state;" );
1126: printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK );
1127: printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
1128: YY_TRAILING_HEAD_MASK );
1129: }
1130:
1131: puts( "#define REJECT \\" );
1132: puts( "{ \\" );
1133: puts(
1134: "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
1135: puts(
1136: "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
1137:
1138: if ( variable_trailing_context_rules )
1139: {
1140: puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
1141: puts(
1142: "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
1143: puts(
1144: "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
1145: }
1146:
1147: puts( "++yy_lp; \\" );
1148: puts( "goto find_rule; \\" );
1149: puts( "}" );
1150: }
1151:
1152: else
1153: {
1154: puts( "/* the intent behind this definition is that it'll catch" );
1155: puts( " * any uses of REJECT which flex missed" );
1156: puts( " */" );
1157: puts( "#define REJECT reject_used_but_not_detected" );
1158: }
1159:
1160: if ( yymore_used )
1161: {
1162: indent_puts( "static int yy_more_flag = 0;" );
1163: indent_puts( "static int yy_doing_yy_more = 0;" );
1164: indent_puts( "static int yy_more_len = 0;" );
1165: indent_puts(
1166: "#define yymore() { yy_more_flag = 1; }" );
1167: indent_puts(
1168: "#define YY_MORE_ADJ (yy_doing_yy_more ? yy_more_len : 0)" );
1169: }
1170:
1171: else
1172: {
1173: indent_puts( "#define yymore() yymore_used_but_not_detected" );
1174: indent_puts( "#define YY_MORE_ADJ 0" );
1175: }
1176:
1177: skelout();
1178:
1179: if ( ferror( temp_action_file ) )
1180: flexfatal( "error occurred when writing temporary action file" );
1181:
1182: else if ( fclose( temp_action_file ) )
1183: flexfatal( "error occurred when closing temporary action file" );
1184:
1185: temp_action_file = fopen( action_file_name, "r" );
1186:
1187: if ( temp_action_file == NULL )
1188: flexfatal( "could not re-open temporary action file" );
1189:
1190: /* copy prolog from action_file to output file */
1191: action_out();
1192:
1193: skelout();
1194:
1195: set_indent( 2 );
1196:
1197: if ( yymore_used )
1198: {
1199: indent_puts( "yy_doing_yy_more = yy_more_flag;" );
1200: indent_puts( "if ( yy_doing_yy_more )" );
1201: indent_up();
1202: indent_puts( "{" );
1203: indent_puts( "yy_more_len = yyleng;" );
1204: indent_puts( "yy_more_flag = 0;" );
1205: indent_puts( "}" );
1206: indent_down();
1207: }
1208:
1209: skelout();
1210:
1211: gen_start_state();
1212:
1213: /* note, don't use any indentation */
1214: puts( "yy_match:" );
1215: gen_next_match();
1216:
1217: skelout();
1218: set_indent( 2 );
1219: gen_find_action();
1220:
1221: skelout();
1222: if ( ddebug )
1223: {
1224: indent_puts( "if ( yy_flex_debug )" );
1225: indent_up();
1226:
1227: indent_puts( "{" );
1228: indent_puts( "if ( yy_act == 0 )" );
1229: indent_up();
1230: indent_puts( "fprintf( stderr, \"--scanner backtracking\\n\" );" );
1231: indent_down();
1232:
1233: do_indent();
1234: printf( "else if ( yy_act < %d )\n", num_rules );
1235: indent_up();
1236: indent_puts(
1237: "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," );
1238: indent_puts( " yy_rule_linenum[yy_act], yytext );" );
1239: indent_down();
1240:
1241: do_indent();
1242: printf( "else if ( yy_act == %d )\n", num_rules );
1243: indent_up();
1244: indent_puts(
1245: "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," );
1246: indent_puts( " yytext );" );
1247: indent_down();
1248:
1249: do_indent();
1250: printf( "else if ( yy_act == %d )\n", num_rules + 1 );
1251: indent_up();
1252: indent_puts( "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" );
1253: indent_down();
1254:
1255: do_indent();
1256: printf( "else\n" );
1257: indent_up();
1258: indent_puts( "fprintf( stderr, \"--EOF\\n\" );" );
1259: indent_down();
1260:
1261: indent_puts( "}" );
1262: indent_down();
1263: }
1264:
1265: /* copy actions from action_file to output file */
1266: skelout();
1267: indent_up();
1268: gen_bt_action();
1269: action_out();
1270:
1271: /* generate cases for any missing EOF rules */
1272: for ( i = 1; i <= lastsc; ++i )
1273: if ( ! sceof[i] )
1274: {
1275: do_indent();
1276: printf( "case YY_STATE_EOF(%s):\n", scname[i] );
1277: did_eof_rule = true;
1278: }
1279:
1280: if ( did_eof_rule )
1281: {
1282: indent_up();
1283: indent_puts( "yyterminate();" );
1284: indent_down();
1285: }
1286:
1287:
1288: /* generate code for handling NUL's, if needed */
1289:
1290: /* first, deal with backtracking and setting up yy_cp if the scanner
1291: * finds that it should JAM on the NUL
1292: */
1293: skelout();
1294: set_indent( 7 );
1295:
1296: if ( fullspd || fulltbl )
1297: indent_puts( "yy_cp = yy_c_buf_p;" );
1298:
1299: else
1300: { /* compressed table */
1301: if ( ! reject && ! interactive )
1302: {
1303: /* do the guaranteed-needed backtrack to figure out the match */
1304: indent_puts( "yy_cp = yy_last_accepting_cpos;" );
1305: indent_puts( "yy_current_state = yy_last_accepting_state;" );
1306: }
1307: }
1308:
1309:
1310: /* generate code for yy_get_previous_state() */
1311: set_indent( 1 );
1312: skelout();
1313:
1314: if ( bol_needed )
1315: indent_puts( "register YY_CHAR *yy_bp = yytext;\n" );
1316:
1317: gen_start_state();
1318:
1319: set_indent( 2 );
1320: skelout();
1321: gen_next_state( true );
1322:
1323: set_indent( 1 );
1324: skelout();
1325: gen_NUL_trans();
1326:
1327: skelout();
1328:
1329: /* copy remainder of input to output */
1330:
1331: line_directive_out( stdout );
1332: (void) flexscan(); /* copy remainder of input to output */
1333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.