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