]> pd.if.org Git - pccts/blob - dlg/output.c
auto commit for import
[pccts] / dlg / output.c
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-1995
65  */
66
67 #include <stdio.h>
68 #include "dlg.h"
69 #ifdef MEMCHK
70 #include "trax.h"
71 #else
72 #ifdef __STDC__
73 #include <stdlib.h>
74 #else
75 #include <malloc.h>
76 #endif /* __STDC__ */
77 #endif
78
79 static char *mode_name[MAX_MODES];
80 static int mode_number[MAX_MODES];
81 static int cur_mode=0;
82
83 int operation_no = 0; /* used to mark nodes so that infinite loops avoided */
84 int dfa_basep[MAX_MODES];       /* start of each group of states */
85 int dfa_class_nop[MAX_MODES];   /* number of elements in each group of states*/
86
87 int gen_ansi = FALSE;           /* allows ansi code to be generated */
88
89 FILE *input_stream;     /* where to read description from */
90 FILE *output_stream;    /* where to put the output        */
91 FILE *mode_stream;      /* where to put the mode.h stuff */
92 FILE *class_stream;     /* where to put the scan.h stuff (if gen_cpp) */
93
94 /* NOTE: This section is MACHINE DEPENDENT */
95 #define DIF_SIZE 4
96 #if defined(PC) && !defined(PC32)
97 long typesize[DIF_SIZE]  = { 0x7f, 0x7fff, 0x7fff, 0x7fffffff };
98 char t0[] = "unsigned char";
99 char t1[] = "unsigned short";
100 char t2[] = "unsigned int";
101 char t3[] = "unsigned long";
102 char *typevar[DIF_SIZE] = { t0, t1, t2, t3};
103 #else
104 long typesize[DIF_SIZE]  = { 0x7f, 0x7fff, 0x7fffffff, 0x7fffffff };
105 char t0[] = "unsigned char";
106 char t1[] = "unsigned short";
107 char t2[] = "unsigned int";
108 char t3[] = "unsigned long";
109 char *typevar[DIF_SIZE] = { t0, t1, t2, t3};
110 #endif
111
112 #ifdef __STDC__
113 char *minsize(int);
114 #else
115 char *minsize();
116 #endif
117
118 /* Added by TJP August 1994 */
119 /* Take in MyLexer and return MyLexer_h */
120 static char *
121 #ifdef __USE_PROTOS
122 gate_symbol(char *name)
123 #else
124 gate_symbol(name)
125 char *name;
126 #endif
127 {
128         static char buf[100];
129         sprintf(buf, "%s_h", name);
130         return buf;
131 }
132
133 /* Added by TJP August 1994 */
134 static char *
135 #ifdef __USE_PROTOS
136 mystrdup(char *s)
137 #else
138 mystrdup(s)
139 char *s;
140 #endif
141 {
142         char *p = (char *)malloc(strlen(s)+1);
143         strcpy(p, s);
144         return p;
145 }
146
147 p_class_hdr()
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-1994 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 }
164
165 p_class_def()
166 {
167         int i, m;
168
169         if ( class_stream == NULL ) return;
170         fprintf(class_stream, "\n");
171         fprintf(class_stream, "#include \"%s\"\n\n", DLEXERBASE_H);
172         fprintf(class_stream, "class %s : public DLGLexerBase {\n", ClassName(""));
173         fprintf(class_stream, "public:\n");
174         fprintf(class_stream, "\tstatic const int MAX_MODE;\n");
175         fprintf(class_stream, "\tstatic const int DfaStates;\n");
176         for (i=0; i<cur_mode; i++) {
177                 fprintf(class_stream, "\tstatic const int %s;\n", mode_name[i]);
178         }
179
180         fprintf(class_stream, "\ttypedef %s DfaState;\n\n", minsize(dfa_allocated));
181         fprintf(class_stream, "\t%s(DLGInputStream *in,\n",ClassName(""));
182         fprintf(class_stream, "\t\tunsigned bufsize=2000)\n");
183         fprintf(class_stream, "\t\t: DLGLexerBase(in, bufsize, %d)\n", interactive);
184         fprintf(class_stream, "\t{\n");
185         fprintf(class_stream, "\t;\n");
186         fprintf(class_stream, "\t}\n");
187         fprintf(class_stream, "\tvoid   mode(int);\n");
188         fprintf(class_stream, "\tANTLRTokenType nextTokenType(void);\n");
189         fprintf(class_stream, "\tvoid   advance(void);\n");
190
191         fprintf(class_stream, "protected:\n");
192         for (i=1; i<=action_no; ++i) {
193                 fprintf(class_stream, "\tANTLRTokenType act%d();\n", i);
194         }
195
196         for(m=0; m<(mode_counter-1); ++m){
197                 for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)
198                         fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);
199         }
200         for(i=dfa_basep[m]; i<=dfa_allocated; ++i)
201                 fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);
202
203         fprintf(class_stream, "\tstatic DfaState *dfa[%d];\n", dfa_allocated);
204         fprintf(class_stream, "\tstatic DfaState dfa_base[];\n");
205 /*      fprintf(class_stream, "\tstatic int dfa_base_no[];\n"); */
206         fprintf(class_stream, "\tstatic unsigned char *b_class_no[];\n");
207         fprintf(class_stream, "\tstatic DfaState accepts[%d];\n",dfa_allocated+1);
208         fprintf(class_stream, "\tstatic DLGChar alternatives[%d];\n",dfa_allocated+1);
209         /* WARNING: should be ANTLRTokenType for action table, but g++ 2.5.6 is hosed */
210         fprintf(class_stream, "\tstatic ANTLRTokenType (%s::*actions[%d])();\n", ClassName(""), action_no+1);
211         for(m=0; m<mode_counter; ++m) {
212                 fprintf(class_stream, "\tstatic unsigned char shift%d[%d];\n",
213                         m, CHAR_RANGE);
214         }
215         if (comp_level)
216                 fprintf(class_stream, "\tint ZZSHIFT(int c) { return b_class_no[automaton][1+c]; }\n");
217         else
218                 fprintf(class_stream, "\tint ZZSHIFT(int c) { return 1+c; }\n");
219
220         fprintf(class_stream, "};\n");
221
222         fprintf(class_stream, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n",
223                         ClassName(""), ClassName(""));
224
225         fprintf(class_stream, "#endif\n");
226 }
227
228 /* generate required header on output */
229
230 p_head()
231 {
232         fprintf(OUT, "/*\n");
233         fprintf(OUT, " * D L G tables\n");
234         fprintf(OUT, " *\n");
235         fprintf(OUT, " * Generated from:");
236         fprintf(OUT, " %s", file_str[0]);
237         fprintf(OUT, "\n");
238         fprintf(OUT, " *\n");
239         fprintf(OUT, " * 1989-1994 by  Will Cohen, Terence Parr, and Hank Dietz\n");
240         fprintf(OUT, " * Purdue University Electrical Engineering\n");
241         fprintf(OUT, " * DLG Version %s\n", version);
242         fprintf(OUT, " */\n\n");
243         if ( gen_cpp ) fprintf(OUT, "#include <stdio.h>\n");
244         if ( !gen_cpp ) fprintf(OUT, "#include \"%s\"\n\n", mode_file);
245         fprintf(OUT,"\n");
246 }
247
248 p_includes()
249 {
250         int i;
251
252         fprintf(OUT, "#include \"%s\"\n", APARSER_H);
253         fprintf(OUT, "#include \"%s\"\n", DLEXERBASE_H);
254         fprintf(OUT, "#include \"%s\"\n", ClassName(".h"));
255 }
256
257 /* generate code to tie up any loose ends */
258
259 p_tail()
260 {
261         if ( gen_cpp ) {
262                 if ( strcmp(ClassName(""), DEFAULT_CLASSNAME)!=0 )
263                         fprintf(OUT, "#define DLGLexer %s\n", ClassName(""));
264                 fprintf(OUT, "#include \"%s\"\n", DLEXER_C);
265                 return;
266         }
267         fprintf(OUT, "\n");
268         fprintf(OUT, "\n");
269         if (comp_level)
270                 fprintf(OUT, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n");
271         else
272                 fprintf(OUT, "#define ZZSHIFT(c) (1+c)\n");
273         if ( !gen_cpp ) fprintf(OUT, "#define MAX_MODE %d\n",mode_counter);
274         fprintf(OUT, "#include \"dlgauto.h\"\n");
275 }
276
277
278 /* output the table of DFA for general use */
279
280 p_tables()
281 {
282         char *minsize();
283
284         if ( !gen_cpp ) {
285                 fprintf(OUT, "#define DfaStates\t%d\n", dfa_allocated);
286                 fprintf(OUT, "typedef %s DfaState;\n\n", minsize(dfa_allocated));
287         }
288
289         if ( gen_cpp ) {
290                 int i;
291                 fprintf(OUT, "\n");
292                 fprintf(OUT, "const int %s::MAX_MODE=%d;\n",
293                                 ClassName(""),
294                                 mode_counter);
295                 fprintf(OUT, "const int %s::DfaStates=%d;\n",
296                                 ClassName(""),
297                                 dfa_allocated);
298                 for (i=0; i<cur_mode; i++) {
299                         fprintf(OUT, "const int %s::%s=%d;\n",
300                                         ClassName(""), mode_name[i], mode_number[i]);
301                 }
302                 fprintf(OUT, "\n");
303         }
304
305         p_node_table();
306         p_dfa_table();
307         p_accept_table();
308         p_action_table();
309         p_base_table();
310         p_class_table();
311         if (comp_level)
312                 p_bshift_table();
313         if (interactive || gen_cpp )
314                 p_alternative_table();
315 }
316
317
318 /* figures out the smallest variable type that will hold the transitions
319  */
320 char *minsize(elements)
321 int elements;
322 {
323         int i = 0;
324
325         while (elements > typesize[i])
326                 ++i;
327         return typevar[i];
328 }
329
330
331 p_node_table()
332 {
333         register int    i;
334         register int    m = 0;
335
336         for(m=0; m<(mode_counter-1); ++m){
337                 for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)
338                         p_single_node(i,dfa_class_nop[m]);
339         }
340         for(i=dfa_basep[m]; i<=dfa_allocated; ++i)
341                 p_single_node(i,dfa_class_nop[m]);
342 }
343
344
345 p_single_node(i,classes)
346 int i,classes;
347 {
348         register int    j;
349         register int    trans, items_on_line;
350
351 #if 1
352         /* extra state (classes+1) for invalid characters */
353         fprintf(OUT, "%sDfaState %sst%d[%d] = {\n  ",
354                 gen_cpp?ClassName("::"):"static ",
355                 gen_cpp?ClassName("::"):"",(i-1), (classes+1));
356 #else
357         fprintf(OUT, "static DfaState st%d[%d] = {\n  ", (i-1), classes);
358 #endif
359         items_on_line = MAX_ON_LINE;
360         for(j=0; j<classes; ++j){
361                 DAWDLE;
362                 trans = DFA(i)->trans[j];
363                 if (trans == NIL_INDEX)
364                         trans = dfa_allocated+1;
365                 /* all of DFA moved down one in array */
366                 fprintf(OUT, "%d", trans-1);
367                 fprintf(OUT, ", ");
368                 if (!(--items_on_line)){
369                         fprintf(OUT, "\n  ");
370                         items_on_line = MAX_ON_LINE;
371                 }
372         }
373 #if 1
374         /* put in jump to error state */
375         fprintf(OUT, "%d\n};\n\n", dfa_allocated);
376 #else
377         fprintf(OUT, "\n};\n\n");
378 #endif
379 }
380
381
382 p_dfa_table()
383 {
384         register int    i;
385
386         fprintf(OUT, "\n%sDfaState *%sdfa[%d] = {\n",
387                 gen_cpp?ClassName("::"):"",gen_cpp?ClassName("::"):"", dfa_allocated);
388         for (i=0; i<(dfa_allocated-1); ++i){
389                 fprintf(OUT, "\tst%d,\n", i);
390         }
391         fprintf(OUT, "\tst%d\n", i);
392         fprintf(OUT, "};\n\n");
393 }
394
395
396 p_accept_table()
397 {
398         register int    i = 1;
399         register int    items_on_line = 0;
400         int             true_interactive = TRUE;
401
402         /* make sure element for one past (zzerraction) -WEC 12/16/92 */
403         fprintf(OUT,"\n%sDfaState %saccepts[%d] = {\n  ",
404                         gen_cpp?ClassName("::"):"",
405                         gen_cpp?ClassName("::"):"",
406                         dfa_allocated+1);
407         /* don't do anything if no dfa nodes */
408         if (i>dfa_allocated) goto skip_accepts;
409         while (TRUE){
410                 int accept;
411                 set accept_set;
412                 set nfa_states;
413                 unsigned int *t, *nfa_i;
414                 unsigned int *q, *regular_expr;
415
416                 accept_set = empty;
417                 nfa_states = DFA(i)->nfa_states;
418                 t = nfa_i = set_pdq(nfa_states);
419                 /* NOTE: picks lowest accept because accepts monotonic  */
420                 /*      with respect to nfa node numbers and set_pdq    */
421                 /*      returns in that order                           */
422                 while((*nfa_i != nil) && (!(accept = NFA(*nfa_i)->accept))){
423                         nfa_i++;
424                 }
425
426                 /* figure out if more than one accept state there */
427                 if (warn_ambig ){
428                         set_orel(accept, &accept_set);
429                         while(*nfa_i != nil){
430                                 set_orel(NFA(*nfa_i)->accept, &accept_set);
431                                 nfa_i++;
432                         }
433                         /* remove error action from consideration */
434                         set_rm(0, accept_set);
435
436                         if( set_deg(accept_set)>1){
437                                 fprintf(stderr, "dlg warning: ambiguous regular expression ");
438                                 q = regular_expr = set_pdq(accept_set);
439                                 while(*regular_expr != nil){
440                                         fprintf(stderr," %d ", *regular_expr);
441                                         ++regular_expr;
442                                 }
443                                 fprintf(stderr, "\n");
444                                 free(q);
445                         }
446                 }
447
448                 if ((DFA(i)->alternatives) && (accept != 0)){
449                         true_interactive = FALSE;
450                 }
451                 fprintf(OUT, "%d, ", accept);
452
453                 /* free up memory before we "break" below -ATG 4/6/95 */
454                 free(t);
455                 set_free(accept_set);
456
457                 if ((++i)>dfa_allocated)
458                         break;
459                 if ((++items_on_line)>=MAX_ON_LINE){
460                         fprintf(OUT,"\n  ");
461                         items_on_line = 0;
462                 }
463 /*
464                 free(t);
465                 set_free(accept_set);
466 */
467         }
468         /* make sure element for one past (zzerraction) -WEC 12/16/92 */
469 skip_accepts:
470         fprintf(OUT, "0\n};\n\n");
471 }
472
473
474 p_action_table()
475 {
476         register int    i;
477         char* className = ClassName("");
478
479         if ( gen_cpp )
480                 fprintf(OUT, "Ptr%sMemberFunc %s::actions[%d] = {\n", className,
481                                         className, action_no+1);
482         else
483                 fprintf(OUT, "void (*actions[%d])() = {\n", action_no+1);
484         if ( gen_cpp )
485 /*              fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", className, className);*/
486                 fprintf(OUT, "\t&%s::erraction,\n", className);
487         else
488                 fprintf(OUT, "\tzzerraction,\n");
489         for (i=1; i<action_no; ++i) {
490                 if ( gen_cpp )
491 /*                      fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d,\n", className, className, i);*/
492                         fprintf(OUT,"\t&%s::act%d,\n", className, i);
493                 else
494                         fprintf(OUT,"\tact%d,\n", i);
495                 DAWDLE;
496         }
497         if ( gen_cpp )
498 /*              fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d\n", className, className, i);*/
499                 fprintf(OUT,"\t&%s::act%d\n", className, i);
500         else
501                 fprintf(OUT,"\tact%d\n", i);
502         fprintf(OUT, "};\n\n");
503 }
504
505
506 p_shift_table(m)
507 int m;
508 {
509         register int    i = 0, j;
510         register int    items_on_line = 0;
511
512         fprintf(OUT, "%s unsigned char %sshift%d[%d] = {\n  ",
513                 gen_cpp?"":"static",
514                 gen_cpp?ClassName("::"):"", m, CHAR_RANGE);
515         while (TRUE){
516                 /* find which partition character i is in */
517                 for (j=0; j<dfa_class_nop[mode_counter]; ++j){
518                         if (set_el(i,class_sets[j]))
519                                 break;
520                         }
521                 fprintf(OUT,"%d",j);
522                 if ((++i)>=CHAR_RANGE)
523                         break;
524                 fprintf(OUT,", ");
525                 if ((++items_on_line)>=MAX_ON_LINE){
526                         fprintf(OUT,"\n  ");
527                         items_on_line = 0;
528                         }
529                 }
530         fprintf(OUT, "\n};\n\n");
531 }
532
533
534 p_base_table()
535 {
536         register int m;
537
538         fprintf(OUT, "%sDfaState %sdfa_base[] = {\n",
539                         gen_cpp?ClassName("::"):"static ",
540                         gen_cpp?ClassName("::"):"");
541         for(m=0; m<(mode_counter-1); ++m)
542                 fprintf(OUT, "\t%d,\n", dfa_basep[m]-1);
543         fprintf(OUT, "\t%d\n};\n\n", dfa_basep[m]-1);
544 }
545
546
547 p_class_table()
548 {
549 #if 0
550         register int m;
551
552         fprintf(OUT,"%s int %sdfa_class_no[] = {\n",
553                         gen_cpp?"":"static",
554                         gen_cpp?ClassName("::"):"");
555         for(m=0; m<(mode_counter-1); ++m)
556                 fprintf(OUT,"\t%d,\n", dfa_class_nop[m]);
557         fprintf(OUT,"\t%d\n};\n\n", dfa_class_nop[m]);
558 #endif
559 }
560
561
562 p_bshift_table()
563 {
564         register int m;
565
566         fprintf(OUT,"%s unsigned char *%sb_class_no[] = {\n",
567                 gen_cpp?"":"static",
568                 gen_cpp?ClassName("::"):"");
569         for(m=0; m<(mode_counter-1); ++m)
570                 fprintf(OUT, "\tshift%d,\n", m);
571         fprintf(OUT, "\tshift%d\n};\n\n", m);
572 }
573
574
575 p_alternative_table()
576 {
577         register int i;
578
579         if ( !gen_cpp ) fprintf(OUT, "#define ZZINTERACTIVE\n\n");
580         if ( gen_cpp )
581                 fprintf(OUT, "DLGChar %salternatives[%sDfaStates+1] = {\n",
582                                 ClassName("::"),
583                                 ClassName("::"));
584         else
585                 fprintf(OUT, "static %s zzalternatives[DfaStates+1] = {\n",
586                                 minsize(dfa_allocated));
587
588         for(i=1; i<=dfa_allocated; ++i)
589                 fprintf(OUT, "\t%d,\n", DFA(i)->alternatives);
590         fprintf(OUT, "/* must have 0 for zzalternatives[DfaStates] */\n");
591         fprintf(OUT, "\t0\n};\n\n");
592 }
593
594
595 p_mode_def(s,m)
596 char *s;
597 int m;
598 {
599         if ( gen_cpp )
600         {
601                 mode_name[cur_mode] = mystrdup(s);
602                 mode_number[cur_mode] = m;
603                 cur_mode++;
604         }
605         else
606                 fprintf(mode_stream, "#define %s %d\n", s, m);
607 }
608
609 char *
610 ClassName(suffix)
611 char *suffix;
612 {
613         static char buf[200];
614         extern char *class_name;
615
616         sprintf(buf, "%s%s", class_name, suffix);
617         return buf;
618 }
619
620 #ifdef DEBUG
621 /* print out a particular nfa node that is pointed to by p */
622 p_nfa_node(p)
623 nfa_node *p;
624 {
625          register nfa_node *t;
626
627         if (p != NIL_INDEX){
628                 printf("NFA state : %d\naccept state : %d\n",
629                         NFA_NO(p),p->accept);
630                 if (p->trans[0] != NIL_INDEX){
631                         printf("trans[0] => %d on ", NFA_NO(p->trans[0]));
632                         p_set(p->label);
633                         printf("\n");
634                         }
635                 else
636                         printf("trans[0] => nil\n");
637                 if (p->trans[1] != NIL_INDEX)
638                         printf("trans[1] => %d on epsilon\n",
639                                 NFA_NO(p->trans[1]));
640                 else
641                         printf("trans[1] => nil\n");
642                 printf("\n");
643                 }
644 }
645 #endif
646
647 #ifdef  DEBUG
648 /* code to print out special structures when using a debugger */
649
650 p_nfa(p)
651 nfa_node *p;    /* state number also index into array */
652 {
653 /* each node has a marker on it so it only gets printed once */
654
655         operation_no++; /* get new number */
656         s_p_nfa(p);
657 }
658
659 s_p_nfa(p)
660 nfa_node *p;    /* state number also index into array */
661 {
662         if ((p != NIL_INDEX) && (p->nfa_set != operation_no)){
663                 /* so it is only printed once */
664                 p->nfa_set = operation_no;
665                 p_nfa_node(p);
666                 s_p_nfa(p->trans[0]);
667                 s_p_nfa(p->trans[1]);
668                 }
669 }
670
671 p_dfa_node(p)
672 dfa_node *p;
673 {
674         int i;
675
676         if (p != NIL_INDEX){
677                 printf("DFA state :%d\n",NFA_NO(p));
678                 if (p->done)
679                         printf("done\n");
680                 else
681                         printf("undone\n");
682                 printf("from nfa states : ");
683                 p_set(p->nfa_states);
684                 printf("\n");
685                 /* NOTE: trans arcs stored as ints rather than pointer*/
686                 for (i=0; i<class_no; i++){
687                         printf("%d ",p->trans[i]);
688                         }
689                 printf("\n\n");
690                 }
691 }
692
693 p_dfa()
694 {
695 /* prints out all the dfa nodes actually allocated */
696
697         int i;
698
699         for (i = 1; i<=dfa_allocated; i++)
700                 p_dfa_node(NFA(i));
701 }
702
703
704 /* print out numbers in the set label */
705 p_set(label)
706 set label;
707 {
708         unsigned *t, *e;
709
710         if (set_nil(label)){
711                 printf("epsilon\n");
712         }else{
713                 t = e = set_pdq(label);
714                 while(*e != nil){
715                         printf("%d ", (*e+MIN_CHAR));
716                         e++;
717                 }
718                 printf("\n");
719                 free(t);
720         }
721         
722 }
723 #endif
724