home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pccts.zip / pccts / dlg / output.c < prev    next >
C/C++ Source or Header  |  1994-03-31  |  17KB  |  645 lines

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