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