Home | History | Annotate | Download | only in dlg
      1 /* output.c, output generator for dlg
      2  *
      3  * Output Notes:
      4  *
      5  * DfaStates == number of dfa nodes in automaton (just a #define)
      6  * DfaState == type large enough to index every node in automaton
      7  *         <256 unsigned char, <65536 unsigned short, etc.
      8  *
      9  * Thus, the elements in each of the automaton states (st%d) are type DfaState
     10  * and are size appropriately, since they must be able to index the next
     11  * automaton state.
     12  *
     13  * dfa[] == a linear array that points to all the automaton states (st%d)
     14  *         (dfa_base[] should be the same, but isn't right now)
     15  *
     16  * accepts[] == Taking a closer look at this one, it probably shouldn't be type
     17  *         DfaState because there is no real requirement that the number of
     18  *         accepts states is less than the number of dfa state.  However, if
     19  *         the number of accept states was more than the number of DFA states
     20  *         then the lexical specification would be really ambiguous.
     21  *
     22  *         Another note. Is that is should be possible to fold accepts[] and
     23  *         actions[] together.  If this is done, I would suggest get rid of
     24  *         accept[] and make actions[] have an entry for each state (st%d) in
     25  *         the automaton.
     26  *
     27  * dfa_base[] == starting location for each lexical mode.  This should be
     28  *         Dfastate type (but isn't right now), since it points to the states
     29  *         in the automaton.
     30  *
     31  * dfa_class_no[] == indicates the number of columns each lexical mode has.
     32  *
     33  * b_class_no[] == pointer to the start of the translation array used to
     34  *         convert from input character to character class.  This could cause
     35  *         problems if there are more than 256 classes
     36  *
     37  * shift%d[] == the actual translation arrays that convert the input character
     38  *         into the character class.  These will have to change if there are
     39  *         more than 256 character classes.
     40  *
     41  * SOFTWARE RIGHTS
     42  *
     43  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
     44  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
     45  * company may do whatever they wish with source code distributed with
     46  * PCCTS or the code generated by PCCTS, including the incorporation of
     47  * PCCTS, or its output, into commerical software.
     48  *
     49  * We encourage users to develop software with PCCTS.  However, we do ask
     50  * that credit is given to us for developing PCCTS.  By "credit",
     51  * we mean that if you incorporate our source code into one of your
     52  * programs (commercial product, research project, or otherwise) that you
     53  * acknowledge this fact somewhere in the documentation, research report,
     54  * etc...  If you like PCCTS and have developed a nice tool with the
     55  * output, please mention that you developed it using PCCTS.  In
     56  * addition, we ask that this header remain intact in our source code.
     57  * As long as these guidelines are kept, we expect to continue enhancing
     58  * this system and expect to make other tools available as they are
     59  * completed.
     60  *
     61  * DLG 1.33
     62  * Will Cohen
     63  * With mods by Terence Parr; AHPCRC, University of Minnesota
     64  * 1989-2001
     65  */
     66 
     67 #include <stdio.h>
     68 #include <string.h>
     69 #include "dlg.h"
     70 #ifdef MEMCHK
     71 #include "trax.h"
     72 #else
     73 #ifdef __STDC__
     74 #include <stdlib.h>
     75 #else
     76 #include <malloc.h>
     77 #endif /* __STDC__ */
     78 #endif
     79 
     80 static char *mode_name[MAX_MODES];
     81 static int mode_number[MAX_MODES];
     82 static int cur_mode=0;
     83 
     84 int operation_no = 0; /* used to mark nodes so that infinite loops avoided */
     85 int dfa_basep[MAX_MODES]; 	/* start of each group of states */
     86 int dfa_class_nop[MAX_MODES];	/* number of elements in each group of states*/
     87 
     88 int gen_ansi = FALSE;		/* allows ansi code to be generated */
     89 
     90 FILE *input_stream;	/* where to read description from */
     91 FILE *output_stream;	/* where to put the output	  */
     92 FILE *mode_stream;	/* where to put the mode.h stuff */
     93 FILE *class_stream;	/* where to put the scan.h stuff (if gen_cpp) */
     94 
     95 /* NOTE: This section is MACHINE DEPENDENT */
     96 #define DIF_SIZE 4
     97 #if defined(PC) && !defined(PC32)
     98 unsigned long typesize[DIF_SIZE]  = { 0x7f, 0x7fff, 0x7ffful, 0x7ffffffful }; /* MR20 */
     99 char t0[] = "unsigned char";
    100 char t1[] = "unsigned short";
    101 char t2[] = "unsigned int";
    102 char t3[] = "unsigned long";
    103 char *typevar[DIF_SIZE] = { t0, t1, t2, t3};
    104 #else
    105 unsigned long typesize[DIF_SIZE]  = { 0x7f, 0x7fff, 0x7ffffffful, 0x7ffffffful }; /* MR20 */
    106 char t0[] = "unsigned char";
    107 char t1[] = "unsigned short";
    108 char t2[] = "unsigned int";
    109 char t3[] = "unsigned long";
    110 char *typevar[DIF_SIZE] = { t0, t1, t2, t3};
    111 #endif
    112 
    113 /* Added by TJP August 1994 */
    114 /* Take in MyLexer and return MyLexer_h */
    115 
    116 static char *
    117 #ifdef __USE_PROTOS
    118 gate_symbol(char *name)
    119 #else
    120 gate_symbol(name)
    121 char *name;
    122 #endif
    123 {
    124 	static char buf[100];
    125 	sprintf(buf, "%s_h", name);
    126 	return buf;
    127 }
    128 
    129 /* Added by TJP August 1994 */
    130 static char *
    131 #ifdef __USE_PROTOS
    132 mystrdup(char *s)
    133 #else
    134 mystrdup(s)
    135 char *s;
    136 #endif
    137 {
    138 	char *p = (char *)malloc(strlen(s)+1);
    139 	strcpy(p, s);
    140 	return p;
    141 }
    142 
    143 #ifdef __USE_PROTOS
    144 void p_class_hdr(void)
    145 #else
    146 void p_class_hdr()
    147 #endif
    148 {
    149 	if ( class_stream == NULL ) return;
    150 	fprintf(class_stream, "#ifndef %s\n", gate_symbol(ClassName("")));
    151 	fprintf(class_stream, "#define %s\n", gate_symbol(ClassName("")));
    152 	fprintf(class_stream, "/*\n");
    153 	fprintf(class_stream, " * D L G L e x e r  C l a s s  D e f i n i t i o n\n");
    154 	fprintf(class_stream, " *\n");
    155 	fprintf(class_stream, " * Generated from:");
    156 	fprintf(class_stream, " %s", file_str[0]);
    157 	fprintf(class_stream, "\n");
    158 	fprintf(class_stream, " *\n");
    159 	fprintf(class_stream, " * 1989-2001 by  Will Cohen, Terence Parr, and Hank Dietz\n");
    160 	fprintf(class_stream, " * Purdue University Electrical Engineering\n");
    161 	fprintf(class_stream, " * DLG Version %s\n", version);
    162 	fprintf(class_stream, " */\n\n");
    163 	fprintf(class_stream, "\n");
    164 	fprintf(class_stream, "#include \"%s\"\n", DLEXERBASE_H);
    165 }
    166 
    167 /* MR1									*/
    168 /* MR1 16-Apr-97  Split printing of class header up into several parts  */
    169 /* MR1		    so that #lexprefix <<...>>and #lexmember <<...>>	*/
    170 /* MR1		    can be inserted in the appropriate spots		*/
    171 /* MR1									*/
    172 
    173 #ifdef __USE_PROTOS
    174 void p_class_def1(void)
    175 #else
    176 void p_class_def1()
    177 #endif
    178 {
    179 	if ( class_stream == NULL ) return;
    180 	fprintf(class_stream, "\nclass %s : public DLGLexerBase {\n", ClassName(""));
    181 	fprintf(class_stream, "public:\n");
    182 }
    183 
    184 #ifdef __USE_PROTOS
    185 void p_class_def2(void)
    186 #else
    187 void p_class_def2()
    188 #endif
    189 {
    190 	int i, m;
    191 	if ( class_stream == NULL ) return;
    192 	fprintf(class_stream, "public:\n");
    193 	fprintf(class_stream, "\tstatic const int MAX_MODE;\n");
    194 	fprintf(class_stream, "\tstatic const int DfaStates;\n");
    195 	for (i=0; i<cur_mode; i++) {
    196 		fprintf(class_stream, "\tstatic const int %s;\n", mode_name[i]);
    197 	}
    198 
    199 	fprintf(class_stream, "\ttypedef %s DfaState;\n\n", minsize(dfa_allocated));
    200 	fprintf(class_stream, "\t%s(DLGInputStream *in,\n",ClassName(""));
    201 	fprintf(class_stream, "\t\tunsigned bufsize=2000)\n");
    202 	fprintf(class_stream, "\t\t: DLGLexerBase(in, bufsize, %d)\n", interactive);
    203 	fprintf(class_stream, "\t{\n");
    204 	fprintf(class_stream, "\t;\n");
    205 	fprintf(class_stream, "\t}\n");
    206 	fprintf(class_stream, "\tvoid	  mode(int);\n");
    207 	fprintf(class_stream, "\tANTLRTokenType nextTokenType(void);\n");
    208 	fprintf(class_stream, "\tvoid     advance(void);\n");
    209 	fprintf(class_stream, "protected:\n");
    210 	for (i=1; i<=action_no; ++i) {
    211 		fprintf(class_stream, "\tANTLRTokenType act%d();\n", i);
    212 	}
    213 
    214 	for(m=0; m<(mode_counter-1); ++m){
    215 		for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)
    216 			fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);
    217 	}
    218 	for(i=dfa_basep[m]; i<=dfa_allocated; ++i)
    219 		fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);
    220 
    221 	fprintf(class_stream, "\tstatic DfaState *dfa[%d];\n", dfa_allocated);
    222 	fprintf(class_stream, "\tstatic DfaState dfa_base[];\n");
    223 /*	fprintf(class_stream, "\tstatic int dfa_base_no[];\n"); */
    224 	fprintf(class_stream, "\tstatic unsigned char *b_class_no[];\n");
    225 	fprintf(class_stream, "\tstatic DfaState accepts[%d];\n",dfa_allocated+1);
    226 	fprintf(class_stream, "\tstatic DLGChar alternatives[%d];\n",dfa_allocated+1);
    227 	/* WARNING: should be ANTLRTokenType for action table, but g++ 2.5.6 is hosed */
    228 	fprintf(class_stream, "\tstatic ANTLRTokenType (%s::*actions[%d])();\n", ClassName(""), action_no+1);
    229 	for(m=0; m<mode_counter; ++m) {
    230 		fprintf(class_stream, "\tstatic unsigned char shift%d[%d];\n",
    231 			m, CHAR_RANGE);
    232 	}
    233 	if (comp_level)
    234 		fprintf(class_stream, "\tint ZZSHIFT(int c) { return b_class_no[automaton][1+c]; }\n");
    235 	else
    236 		fprintf(class_stream, "\tint ZZSHIFT(int c) { return 1+c; }\n");
    237 
    238 /* MR1									  */
    239 /* MR1 11-APr-97   Kludge to allow inclusion of user-defined code in	  */
    240 /* MR1			 DLGLexer class header				  */
    241 /* MR1		   Deprecated in favor of 133MR1 addition #lexmember <<>> */
    242 /* MR1									  */
    243 /* MR1 */	fprintf(class_stream,"//\n");
    244 /* MR1 */	fprintf(class_stream,
    245 /* MR1 */	   "// 133MR1 Deprecated feature to allow inclusion of ");
    246 /* MR1 */	fprintf(class_stream,
    247 /* MR1 */	   "user-defined code in DLG class header\n");
    248 /* MR1 */	fprintf(class_stream,"//\n");
    249 /* MR1 */
    250 /* MR1 */	fprintf(class_stream,"#ifdef DLGLexerIncludeFile\n");
    251 /* MR1 */	fprintf(class_stream,"#include DLGLexerIncludeFile\n");
    252 /* MR1 */	fprintf(class_stream,"#endif\n");
    253 
    254 	fprintf(class_stream, "};\n");
    255 
    256 	fprintf(class_stream, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n",
    257 			ClassName(""), ClassName(""));
    258 
    259 	fprintf(class_stream, "#endif\n");
    260 }
    261 
    262 /* generate required header on output */
    263 
    264 #ifdef __USE_PROTOS
    265 void p_head(void)
    266 #else
    267 void p_head()
    268 #endif
    269 {
    270 	fprintf(OUT, "/*\n");
    271 	fprintf(OUT, " * D L G tables\n");
    272 	fprintf(OUT, " *\n");
    273 	fprintf(OUT, " * Generated from:");
    274 	fprintf(OUT, " %s", file_str[0]);
    275 	fprintf(OUT, "\n");
    276 	fprintf(OUT, " *\n");
    277 	fprintf(OUT, " * 1989-2001 by  Will Cohen, Terence Parr, and Hank Dietz\n");
    278 	fprintf(OUT, " * Purdue University Electrical Engineering\n");
    279 	fprintf(OUT, " * DLG Version %s\n", version);
    280 	fprintf(OUT, " */\n\n");
    281 	if ( gen_cpp)  fprintf(OUT, "#include \"pcctscfg.h\"\n");
    282 	if ( gen_cpp ) fprintf(OUT, "#include \"pccts_stdio.h\"\n");
    283 	if ( !gen_cpp ) fprintf(OUT, "#include \"%s\"\n\n", mode_file);
    284 	fprintf(OUT,"\n");
    285 }
    286 
    287 #ifdef __USE_PROTOS
    288 void p_includes(void)
    289 #else
    290 void p_includes()
    291 #endif
    292 {
    293 	fprintf(OUT, "#include \"%s\"\n", APARSER_H);
    294 	fprintf(OUT, "#include \"%s\"\n", DLEXERBASE_H);
    295 	fprintf(OUT, "#include \"%s\"\n", ClassName(".h"));
    296 }
    297 
    298 /* generate code to tie up any loose ends */
    299 
    300 #ifdef __USE_PROTOS
    301 void p_tail(void)   				/* MR1 */
    302 #else
    303 void p_tail()						/* MR1 */
    304 #endif
    305 {
    306 	if ( gen_cpp ) {
    307 		if ( strcmp(ClassName(""), DEFAULT_CLASSNAME)!=0 )
    308 			fprintf(OUT, "#define DLGLexer %s\n", ClassName(""));
    309 		fprintf(OUT, "#include \"%s\"\n", DLEXER_H);  /* MR23 Rename DLexer.cpp to DLexer.h */
    310 		return;
    311 	}
    312 	fprintf(OUT, "\n");
    313 	fprintf(OUT, "\n");
    314 	if (comp_level)
    315 		fprintf(OUT, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n");
    316 	else
    317 		fprintf(OUT, "#define ZZSHIFT(c) (1+c)\n");
    318 	if ( !gen_cpp ) fprintf(OUT, "#define MAX_MODE %d\n",mode_counter);
    319 	fprintf(OUT, "#include \"dlgauto.h\"\n");
    320 }
    321 
    322 
    323 /* output the table of DFA for general use */
    324 
    325 #ifdef __USE_PROTOS
    326 void p_tables()
    327 #else
    328 void p_tables()
    329 #endif
    330 {
    331 	if ( !gen_cpp ) {
    332 		fprintf(OUT, "#define DfaStates\t%d\n", dfa_allocated);
    333 		fprintf(OUT, "typedef %s DfaState;\n\n", minsize(dfa_allocated));
    334 	}
    335 
    336 	if ( gen_cpp ) {
    337 		int i;
    338 		fprintf(OUT, "\n");
    339 		fprintf(OUT, "const int %s::MAX_MODE=%d;\n",
    340 				ClassName(""),
    341 				mode_counter);
    342 		fprintf(OUT, "const int %s::DfaStates=%d;\n",
    343 				ClassName(""),
    344 				dfa_allocated);
    345 		for (i=0; i<cur_mode; i++) {
    346 			fprintf(OUT, "const int %s::%s=%d;\n",
    347 					ClassName(""), mode_name[i], mode_number[i]);
    348 		}
    349 		fprintf(OUT, "\n");
    350 	}
    351 
    352 	p_node_table();
    353 	p_dfa_table();
    354 	p_accept_table();
    355 	p_action_table();
    356 	p_base_table();
    357 	p_class_table();
    358 	if (comp_level)
    359 		p_bshift_table();
    360 	if (interactive || gen_cpp )
    361 		p_alternative_table();
    362 }
    363 
    364 
    365 /* figures out the smallest variable type that will hold the transitions
    366  */
    367 
    368 #ifdef __USE_PROTOS
    369 char *minsize(int elements)
    370 #else
    371 char *minsize(elements)
    372 int elements;
    373 #endif
    374 {
    375 	int i = 0;
    376 
    377 	while ((unsigned long) elements > typesize[i]) /* MR20 */
    378 		++i;
    379 	return typevar[i];
    380 }
    381 
    382 
    383 #ifdef __USE_PROTOS
    384 void p_node_table(void)
    385 #else
    386 void p_node_table()
    387 #endif
    388 {
    389 	register int	i;
    390 	register int	m = 0;
    391 
    392 	for(m=0; m<(mode_counter-1); ++m){
    393 		for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)
    394 			p_single_node(i,dfa_class_nop[m]);
    395 	}
    396 	for(i=dfa_basep[m]; i<=dfa_allocated; ++i)
    397 		p_single_node(i,dfa_class_nop[m]);
    398 }
    399 
    400 
    401 #ifdef __USE_PROTOS
    402 void p_single_node(int i,int classes)
    403 #else
    404 void p_single_node(i,classes)
    405 int i,classes;
    406 #endif
    407 {
    408 	register int	j;
    409 	register int	trans, items_on_line;
    410 
    411 #if 1
    412 	/* extra state (classes+1) for invalid characters */
    413 	fprintf(OUT, "%sDfaState %sst%d[%d] = {\n  ",
    414 		gen_cpp?ClassName("::"):"static ",
    415 		gen_cpp?ClassName("::"):"",(i-1), (classes+1));
    416 #else
    417 	fprintf(OUT, "static DfaState st%d[%d] = {\n  ", (i-1), classes);
    418 #endif
    419 	items_on_line = MAX_ON_LINE;
    420 	for(j=0; j<classes; ++j){
    421 		DAWDLE;
    422 		trans = DFA(i)->trans[j];
    423 		if (trans == NIL_INDEX)
    424 			trans = dfa_allocated+1;
    425 		/* all of DFA moved down one in array */
    426 		fprintf(OUT, "%d", trans-1);
    427 		fprintf(OUT, ", ");
    428 		if (!(--items_on_line)){
    429 			fprintf(OUT, "\n  ");
    430 			items_on_line = MAX_ON_LINE;
    431 		}
    432 	}
    433 #if 1
    434 	/* put in jump to error state */
    435 	fprintf(OUT, "%d\n};\n\n", dfa_allocated);
    436 #else
    437 	fprintf(OUT, "\n};\n\n");
    438 #endif
    439 }
    440 
    441 
    442 #ifdef __USE_PROTOS
    443 void p_dfa_table(void)
    444 #else
    445 void p_dfa_table()
    446 #endif
    447 {
    448 	register int	i;
    449 
    450 	fprintf(OUT, "\n%sDfaState *%sdfa[%d] = {\n",
    451 		gen_cpp?ClassName("::"):"",gen_cpp?ClassName("::"):"", dfa_allocated);
    452 	for (i=0; i<(dfa_allocated-1); ++i){
    453 		fprintf(OUT, "\tst%d,\n", i);
    454 	}
    455 	fprintf(OUT, "\tst%d\n", i);
    456 	fprintf(OUT, "};\n\n");
    457 }
    458 
    459 
    460 #ifdef __USE_PROTOS
    461 void p_accept_table(void)
    462 #else
    463 void p_accept_table()
    464 #endif
    465 {
    466 	register int	i = 1;
    467 	register int	items_on_line = 0;
    468 	int		true_interactive = TRUE;
    469 
    470 	/* make sure element for one past (zzerraction) -WEC 12/16/92 */
    471 	fprintf(OUT,"\n%sDfaState %saccepts[%d] = {\n  ",
    472 			gen_cpp?ClassName("::"):"",
    473 			gen_cpp?ClassName("::"):"",
    474 			dfa_allocated+1);
    475 	/* don't do anything if no dfa nodes */
    476 	if (i>dfa_allocated) goto skip_accepts;
    477 	for (;;) {
    478 		int accept=0;   /* MR14a - Manuel Kessler (mlkessle (at) cip.physik.uni-wuerzburg.de) */
    479 		set accept_set;
    480 		set nfa_states;
    481 		unsigned int *t, *nfa_i;
    482 		unsigned int *q, *regular_expr;
    483 
    484 		accept_set = empty;
    485 		nfa_states = DFA(i)->nfa_states;
    486 		t = nfa_i = set_pdq(nfa_states);
    487 		/* NOTE: picks lowest accept because accepts monotonic	*/
    488 		/*	with respect to nfa node numbers and set_pdq	*/
    489 		/*	returns in that order				*/
    490 		while((*nfa_i != nil) && (!(accept = NFA(*nfa_i)->accept))){
    491 			nfa_i++;
    492 		}
    493 
    494 		/* figure out if more than one accept state there */
    495 		if (warn_ambig ){
    496 			set_orel(accept, &accept_set);
    497 			while(*nfa_i != nil){
    498 				set_orel(NFA(*nfa_i)->accept, &accept_set);
    499 				nfa_i++;
    500 			}
    501 			/* remove error action from consideration */
    502 			set_rm(0, accept_set);
    503 
    504 			if( set_deg(accept_set)>1){
    505 				fprintf(stderr, "dlg warning: ambiguous regular expression ");
    506 				q = regular_expr = set_pdq(accept_set);
    507 				while(*regular_expr != nil){
    508 					fprintf(stderr," %d ", *regular_expr);
    509 					++regular_expr;
    510 				}
    511 				fprintf(stderr, "\n");
    512 				free(q);
    513 			}
    514 		}
    515 
    516 		if ((DFA(i)->alternatives) && (accept != 0)){
    517 			true_interactive = FALSE;
    518 		}
    519 		fprintf(OUT, "%d, ", accept);
    520 
    521 		/* free up memory before we "break" below -ATG 4/6/95 */
    522 		free(t);
    523 		set_free(accept_set);
    524 
    525 		if ((++i)>dfa_allocated)
    526 			break;
    527 		if ((++items_on_line)>=MAX_ON_LINE){
    528 			fprintf(OUT,"\n  ");
    529 			items_on_line = 0;
    530 		}
    531 /*
    532 		free(t);
    533 		set_free(accept_set);
    534 */
    535 	}
    536 	/* make sure element for one past (zzerraction) -WEC 12/16/92 */
    537 skip_accepts:
    538 	fprintf(OUT, "0\n};\n\n");
    539 }
    540 
    541 
    542 #ifdef __USE_PROTOS
    543 void p_action_table(void)
    544 #else
    545 void p_action_table()
    546 #endif
    547 {
    548 	register int	i;
    549 	char* theClassName = ClassName("");
    550 
    551 	if ( gen_cpp )
    552 		fprintf(OUT, "Ptr%sMemberFunc %s::actions[%d] = {\n", theClassName,
    553 					theClassName, action_no+1);
    554 	else
    555 		fprintf(OUT, "void (*actions[%d])() = {\n", action_no+1);
    556 	if ( gen_cpp )
    557 /*		fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", theClassName, theClassName);*/
    558 		fprintf(OUT, "\t&%s::erraction,\n", theClassName);
    559 	else
    560 		fprintf(OUT, "\tzzerraction,\n");
    561 	for (i=1; i<action_no; ++i) {
    562 		if ( gen_cpp )
    563 /*			fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d,\n", theClassName, theClassName, i);*/
    564 			fprintf(OUT,"\t&%s::act%d,\n", theClassName, i);
    565 		else
    566 			fprintf(OUT,"\tact%d,\n", i);
    567 		DAWDLE;
    568 	}
    569 	if ( gen_cpp )
    570 /*		fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d\n", theClassName, theClassName, i);*/
    571 		fprintf(OUT,"\t&%s::act%d\n", theClassName, i);
    572 	else
    573 		fprintf(OUT,"\tact%d\n", i);
    574 	fprintf(OUT, "};\n\n");
    575 }
    576 
    577 
    578 #ifdef __USE_PROTOS
    579 void p_shift_table(int m)  				    /* MR1 */
    580 #else
    581 void p_shift_table(m)						/* MR1 */
    582 int m;
    583 #endif
    584 {
    585 	register int	i = 0, j;
    586 	register int	items_on_line = 0;
    587 
    588 	fprintf(OUT, "%s unsigned char %sshift%d[%d] = {\n  ",
    589 		gen_cpp?"":"static",
    590 		gen_cpp?ClassName("::"):"", m, CHAR_RANGE);
    591 	for (;;) {
    592 		/* find which partition character i is in */
    593 		for (j=0; j<dfa_class_nop[mode_counter]; ++j){
    594 			if (set_el(i,class_sets[j]))
    595 				break;
    596 			}
    597 		fprintf(OUT,"%d",j);
    598 		if ((++i)>=CHAR_RANGE)
    599 			break;
    600 		fprintf(OUT,", ");
    601 		if ((++items_on_line)>=MAX_ON_LINE){
    602 			fprintf(OUT,"\n  ");
    603 			items_on_line = 0;
    604 			}
    605 		}
    606 	fprintf(OUT, "\n};\n\n");
    607 }
    608 
    609 
    610 #ifdef __USE_PROTOS
    611 void p_base_table(void)
    612 #else
    613 void p_base_table()
    614 #endif
    615 {
    616 	register int m;
    617 
    618 	fprintf(OUT, "%sDfaState %sdfa_base[] = {\n",
    619 			gen_cpp?ClassName("::"):"static ",
    620 			gen_cpp?ClassName("::"):"");
    621 	for(m=0; m<(mode_counter-1); ++m)
    622 		fprintf(OUT, "\t%d,\n", dfa_basep[m]-1);
    623 	fprintf(OUT, "\t%d\n};\n\n", dfa_basep[m]-1);
    624 }
    625 
    626 
    627 #ifdef __USE_PROTOS
    628 void p_class_table(void)    				/* MR1 */
    629 #else
    630 void p_class_table()						/* MR1 */
    631 #endif
    632 {
    633 #if 0
    634 	register int m;
    635 
    636 	fprintf(OUT,"%s int %sdfa_class_no[] = {\n",
    637 			gen_cpp?"":"static",
    638 			gen_cpp?ClassName("::"):"");
    639 	for(m=0; m<(mode_counter-1); ++m)
    640 		fprintf(OUT,"\t%d,\n", dfa_class_nop[m]);
    641 	fprintf(OUT,"\t%d\n};\n\n", dfa_class_nop[m]);
    642 #endif
    643 }
    644 
    645 
    646 #ifdef __USE_PROTOS
    647 void p_bshift_table(void)					/* MR1 */
    648 #else
    649 void p_bshift_table()						/* MR1 */
    650 #endif
    651 {
    652 	register int m;
    653 
    654 	fprintf(OUT,"%s unsigned char *%sb_class_no[] = {\n",
    655 		gen_cpp?"":"static",
    656 		gen_cpp?ClassName("::"):"");
    657 	for(m=0; m<(mode_counter-1); ++m)
    658 		fprintf(OUT, "\tshift%d,\n", m);
    659 	fprintf(OUT, "\tshift%d\n};\n\n", m);
    660 }
    661 
    662 
    663 #ifdef __USE_PROTOS
    664 void p_alternative_table(void)				/* MR1 */
    665 #else
    666 void p_alternative_table()					/* MR1 */
    667 #endif
    668 {
    669 	register int i;
    670 
    671 	if ( !gen_cpp ) fprintf(OUT, "#define ZZINTERACTIVE\n\n");
    672 	if ( gen_cpp )
    673 		fprintf(OUT, "DLGChar %salternatives[%d] = {\n",  /* mr23 vhs %sDfaStates+1 */
    674 				ClassName("::"),
    675 				dfa_allocated+1); /* vhs ClassName("::")); */
    676 	else
    677 		fprintf(OUT, "static %s zzalternatives[DfaStates+1] = {\n",
    678 				minsize(dfa_allocated));
    679 
    680 	for(i=1; i<=dfa_allocated; ++i)
    681 		fprintf(OUT, "\t%d,\n", DFA(i)->alternatives);
    682 	fprintf(OUT, "/* must have 0 for zzalternatives[DfaStates] */\n");
    683 	fprintf(OUT, "\t0\n};\n\n");
    684 }
    685 
    686 
    687 #ifdef __USE_PROTOS
    688 void p_mode_def(char *s,int m)			/* MR1 */
    689 #else
    690 void p_mode_def(s,m)					/* MR1 */
    691 char *s;
    692 int m;
    693 #endif
    694 {
    695 	if ( gen_cpp )
    696 	{
    697 		mode_name[cur_mode] = mystrdup(s);
    698 		mode_number[cur_mode] = m;
    699 		cur_mode++;
    700 	}
    701 	else
    702 		fprintf(mode_stream, "#define %s %d\n", s, m);
    703 }
    704 
    705 #ifdef __USE_PROTOS
    706 char * ClassName(char *suffix)
    707 #else
    708 char * ClassName(suffix)
    709 char *suffix;
    710 #endif
    711 {
    712 	static char buf[200];
    713 	extern char *class_name;
    714 
    715 	sprintf(buf, "%s%s", class_name, suffix);
    716 	return buf;
    717 }
    718 
    719 #ifdef DEBUG
    720 
    721 /* print out a particular nfa node that is pointed to by p */
    722 
    723 #ifdef __USE_PROTOS
    724 void p_nfa_node(nfa_node *p)
    725 #else
    726 void p_nfa_node(p)
    727 nfa_node *p;
    728 #endif
    729 {
    730 	 register nfa_node *t;
    731 
    732 	if (p != NIL_INDEX){
    733 		printf("NFA state : %d\naccept state : %d\n",
    734 			NFA_NO(p),p->accept);
    735 		if (p->trans[0] != NIL_INDEX){
    736 			printf("trans[0] => %d on ", NFA_NO(p->trans[0]));
    737 			p_set(p->label);
    738 			printf("\n");
    739 			}
    740 		else
    741 			printf("trans[0] => nil\n");
    742 		if (p->trans[1] != NIL_INDEX)
    743 			printf("trans[1] => %d on epsilon\n",
    744 				NFA_NO(p->trans[1]));
    745 		else
    746 			printf("trans[1] => nil\n");
    747 		printf("\n");
    748 		}
    749 }
    750 #endif
    751 
    752 #ifdef  DEBUG
    753 
    754 /* code to print out special structures when using a debugger */
    755 
    756 #ifdef __USE_PROTOS
    757 void p_nfa(p)
    758 #else
    759 void p_nfa(nfa_node *p)
    760 nfa_node *p;	/* state number also index into array */
    761 #endif
    762 {
    763 /* each node has a marker on it so it only gets printed once */
    764 
    765 	operation_no++; /* get new number */
    766 	s_p_nfa(p);
    767 }
    768 
    769 #ifdef __USE_PROTOS
    770 void s_p_nfa(nfa_node *p)
    771 #else
    772 void s_p_nfa(p)
    773 nfa_node *p;	/* state number also index into array */
    774 #endif
    775 {
    776 	if ((p != NIL_INDEX) && (p->nfa_set != operation_no)){
    777 		/* so it is only printed once */
    778 		p->nfa_set = operation_no;
    779 		p_nfa_node(p);
    780 		s_p_nfa(p->trans[0]);
    781 		s_p_nfa(p->trans[1]);
    782 		}
    783 }
    784 
    785 #ifdef __USE_PROTOS
    786 void p_dfa_node(dfa_node *p)
    787 #else
    788 void p_dfa_node(p)
    789 dfa_node *p;
    790 #endif
    791 {
    792 	int i;
    793 
    794 	if (p != NIL_INDEX){
    795 		printf("DFA state :%d\n",NFA_NO(p));
    796 		if (p->done)
    797 			printf("done\n");
    798 		else
    799 			printf("undone\n");
    800 		printf("from nfa states : ");
    801 		p_set(p->nfa_states);
    802 		printf("\n");
    803 		/* NOTE: trans arcs stored as ints rather than pointer*/
    804 		for (i=0; i<class_no; i++){
    805 			printf("%d ",p->trans[i]);
    806 			}
    807 		printf("\n\n");
    808 		}
    809 }
    810 
    811 #ifdef __USE_PROTOS
    812 void p_dfa(void)
    813 #else
    814 void p_dfa()
    815 #endif
    816 {
    817 /* prints out all the dfa nodes actually allocated */
    818 
    819 	int i;
    820 
    821 	for (i = 1; i<=dfa_allocated; i++)
    822 		p_dfa_node(NFA(i));
    823 }
    824 
    825 
    826 /* print out numbers in the set label */
    827 
    828 #ifdef __USE_PROTOS
    829 void p_set(set label)
    830 #else
    831 void p_set(label)
    832 set label;
    833 #endif
    834 {
    835 	unsigned *t, *e;
    836 
    837 	if (set_nil(label)){
    838 		printf("epsilon\n");
    839 	}else{
    840 		t = e = set_pdq(label);
    841 		while(*e != nil){
    842 			printf("%d ", (*e+MIN_CHAR));
    843 			e++;
    844 		}
    845 		printf("\n");
    846 		free(t);
    847 	}
    848 
    849 }
    850 #endif
    851