home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / compcomp / yacc / y3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-17  |  19.3 KB  |  694 lines

  1. /************************************************************************/
  2. /*                              y3.c                                    */ 
  3. /*  YACC source file #3 (of 4).                                         */ 
  4. /************************************************************************/    
  5.      
  6. /************************************************************************/    
  7. /*                              contents                                */    
  8. /*                                                                      */    
  9. /*    y3ActionIndex     Write out the array of action-function pointers.*/
  10. /*  * y3AGoto        Write the gotos for one nonterminal.        */
  11. /*    y3Gotos        Write the gotos for all nonterminals.        */
  12. /*    y3HideProductions Free up mem[] and y1Action[] for optimizer.    */
  13. /*    y3PackState    Pack state i from y1Temp into y1Action.     */
  14. /*    y3PutArray        Write out an array.                             */
  15. /*    y3PutStates    Write the states and tables.            */
  16. /*  * y3ShiftReduce    Decide a shift/reduce conflict by precedence.    */
  17. /*  * y3WrtAction    Write out state i.                */
  18. /*  * y3WrtState    Write state i.                    */
  19. /*                                                                      */
  20. /* * Local to this file.                                                */ 
  21. /*                                    */
  22. /************************************************************************/    
  23.     
  24.     
  25. /************************************************************************/
  26. /*                              history                                 */    
  27. /*                                                                      */    
  28. /* 85Nov19 CrT    y3ActionIndex.                        */
  29. /* 85Nov15 CrT    Global variable names decrypted.            */
  30. /* 85Nov13 CrT    Give plaintiff routine in error messages.        */
  31. /* 85Nov12 CrT    Function names decrypted. Still unique in first 6 chars.*/
  32. /* 85Nov11 CrT    y3.c reconstructed from  9 subfiles.  Cosmetics.    */
  33. /* 81Aug28 RBD  Modified to make debug code conditionally compile.      */ 
  34. /* 7?????? SCJ  Created.                                                */ 
  35. /*                                                                      */ 
  36. /*                              credits                                 */ 
  37. /*      CrT=CrT                                                         */ 
  38. /*      RBD=Bob Denny                                                   */  
  39. /*      SCJ=Steven C Johnson.                                           */  
  40. /*      SG =Scott Guthery                                               */  
  41. /************************************************************************/ 
  42.   
  43.    
  44.  
  45. #include <stdio.h>
  46. #include "system.h"
  47. #include "dtxtrn.h"
  48.                                                                   
  49. /* The number of the last reduction of a state: */
  50. static int y3LastReduction;
  51.  
  52. /* The default actions of states: */
  53. int y3DefaultAction[MAXsTATES];
  54.  
  55. /************************************************************************/
  56. /*    y3ActionIndex    Write out the array of action-function pointers.*/
  57. /************************************************************************/
  58. y3ActionIndex() {
  59.     int i;
  60.  
  61.     /* First, declare all action functions: */
  62.  
  63.     /* Declare the default (null) action: */
  64.     fprintf( y2ytabcFD, "\nint yyANop();" );
  65.  
  66.     /* Declare all action functions created from user-supplied code chunks: */
  67.     FORaLLpRODUCTIONS(0,i)  {
  68.         if (y2ProductionProperties[ i ]   &   RULEhASaCTION) { 
  69.             fprintf( y2ytabcFD, "\nint yyA%03d();", i ); 
  70.         } 
  71.     } 
  72.  
  73.     /* Now declare and initialize yyActionIndex[]: */
  74.     fprintf( y2ytabcFD, "\n\n/* Table with an action function per rule: */" );
  75.     fprintf(
  76.     y2ytabcFD,
  77.         "\nstatic (*(yyActionIndex[%d]))() = {",
  78.     y2ThisProduction
  79.     );
  80.     FORaLLpRODUCTIONS(0,i)  {
  81.         if (y2ProductionProperties[ i ]   &   RULEhASaCTION) { 
  82.         fprintf( y2ytabcFD, "\n    yyA%03d", i );
  83.     } else {
  84.         fprintf( y2ytabcFD, "\n    yyANop"       );
  85.     }
  86.     if (i < y2ThisProduction-1)   fprintf( y2ytabcFD, "," );
  87.     }
  88.     fprintf( y2ytabcFD, "\n};\n\n" );
  89. }
  90.  
  91. /************************************************************************/
  92. /*    y3AGoto        Write the gotos for one nonterminal.        */
  93. /************************************************************************/
  94. static y3AGoto( c )           /* Called only from y3Gotos */
  95. int c;
  96. {
  97.     int     i, work, cc;
  98.     struct item *p, *q;
  99.   
  100.   
  101.     /* First, find nonterminals with gotos on c: */
  102.   
  103.     y1ArrayFill( y1Temp, y2LastNonterminal+1, 0 );
  104.  
  105.     y1Temp[ c ] = 1;
  106.   
  107.     for (work = 1;   work;   )     {
  108.     work = 0;
  109.  
  110.     FORaLLpRODUCTIONS(0,i) {
  111.  
  112.         if ((cc = y2Production[ i ][ 1 ] - FIRSTnONTERMINAL)   >=    0) {
  113.  
  114.                 /* cc is a nonterminal: */
  115.  
  116.         if (y1Temp[ cc ]) {
  117.  
  118.             /* cc has a goto on c: */
  119.  
  120.             /* Thus, the left side of production i does too: */
  121.             cc = *y2Production[ i ] - FIRSTnONTERMINAL;
  122.  
  123.             if (y1Temp[cc] == 0) {
  124.             work      = 1;
  125.             y1Temp[cc] = 1;
  126.             }
  127.         }
  128.             } 
  129.     }
  130.     }
  131.   
  132.     /* "Now, we have y1Temp[c] = 1 if a goto on c in closure of cc" :-) */
  133.   
  134. #ifdef debug 
  135.     if (y2OutputFD != NULL) {
  136.  
  137.     fprintf( y2OutputFD, "%s: gotos on ", y2NonterminalState[c].name );
  138.  
  139.     FORaLLnONTERMINALS(i) {
  140.         if (y1Temp[i]) {
  141.         fprintf( y2OutputFD, "%s ", y2NonterminalState[i].name);
  142.         }
  143.         }
  144.     fprintf( y2OutputFD, "\n");
  145.     }
  146. #endif 
  147.  
  148.     /* Now, go through and put gotos into y1StateType: */
  149.   
  150.     y1ArrayFill( y1StateType, y1NextState, 0 );
  151.  
  152.     FORaLLsTATES(i) {
  153.  
  154.     FORaLLiTEMS(i,p,q) {
  155.  
  156.         if ((cc = *p->pitem)   >=    FIRSTnONTERMINAL) {
  157.  
  158.         if (y1Temp[cc -= FIRSTnONTERMINAL]) {
  159.  
  160.             /* goto on c is possible: */
  161.             y1StateType[ i ]    = y1Action[ y1GotoIndex[ i ] +c ];
  162.             break;
  163.         }
  164.             } 
  165.     }
  166.     }
  167. }
  168.  
  169. /************************************************************************/
  170. /*    y3Gotos           Write the gotos for all nonterminals.           */
  171. /************************************************************************/
  172. y3Gotos() {        /* Called only from main. */
  173.     int   i, j, k, best, count, cbest, times;
  174.   
  175.     /* Mark begining of gotos: */
  176.     fprintf( y2TempFileFD, "$\n" );
  177.  
  178.     for (i = 1;   i <= y2LastNonterminal;   ++i) {
  179.  
  180.     y3AGoto( i );
  181.   
  182.     /* Find the best one to make default: */
  183.   
  184.     best    = -1;
  185.     times    = 0;
  186.   
  187.     for (j = 0;   j <= y1NextState;   ++j) {
  188.  
  189.         /* Is j the most frequent? */
  190.         if (y1StateType[ j ]   ==     0)   continue;
  191.         if (y1StateType[ j ]   == best)   continue;
  192.   
  193.         /* Is y1StateType[j] the most frequent? */
  194.   
  195.         count   = 0;
  196.         cbest   = y1StateType[ j ];
  197.   
  198.         for (k = j;   k <= y1NextState;   ++k) {
  199.  
  200.         if (y1StateType[ k ]   ==   cbest)   ++count;
  201.   
  202.         }
  203.         if (count > times) {
  204.         best    = cbest;
  205.         times    = count;
  206.         }
  207.     }
  208.  
  209.     /* Best is now the default entry: */
  210.  
  211.     y1GotosSavedByDefault += (times-1);
  212.  
  213.     for (j = 0;   j <= y1NextState;   ++j) {
  214.  
  215.         if (y1StateType[ j ] != 0    &&   y1StateType[ j ] != best) {
  216.  
  217.         fprintf( y2TempFileFD, "%d,%d,", j, y1StateType[j] );
  218.         y1GotoEntries += 1;
  219.         }
  220.     }
  221.  
  222.     /* Now, the default: */
  223.  
  224.     y1GotoEntries += 1;
  225.     fprintf( y2TempFileFD, "%d\n", best );
  226.     }
  227. }
  228.  
  229. /************************************************************************/
  230. /*    y3HideProductions Free up mem[] and y1Action[] for optimizer.        */
  231. /************************************************************************/
  232. y3HideProductions() {        /* Called only from main. */
  233.  
  234.     /********************************************************************/
  235.     /* In order to free up the mem and y1Action arrays for the optimizer,   */
  236.     /* and still be able to output yyr1, etc., after the sizes of    */
  237.     /* the action array is known, we hide the nonterminals        */
  238.     /* derived by productions in y2ProductionProperties:                */
  239.     /********************************************************************/
  240.  
  241.     register i, j;
  242.           
  243.     j        = 0;
  244.     y2ProductionProperties[0]    = 0;
  245.  
  246.     FORaLLpRODUCTIONS(1,i) {
  247.     if ( !(y2ProductionProperties[i] & RULEhASbEENrEDUCED) ) {
  248.         ++j;
  249.  
  250.         if (y2OutputFD != NULL) {
  251.         fprintf(
  252.             y2OutputFD,
  253.             "Rule not reduced:   %s\n",
  254.             y1WriteItem( y2Production[i] )
  255.         );
  256.             } 
  257.     }
  258.     y2ProductionProperties[i] = *y2Production[i] - FIRSTnONTERMINAL;
  259.     }
  260.     if (j)  fprintf( stdout, "%d rules never reduced\n", j );
  261. }
  262.  
  263. /************************************************************************/
  264. /*    y3PackState    Pack state i from y1Temp into y1Action.          */
  265. /************************************************************************/ 
  266. y3PackState( p, n )     /* Called only from y1MakeStates        */ 
  267. int *p; 
  268.     int off; 
  269.     register *pp, *qq, *rr; 
  270.     int *q, *r; 
  271.            
  272.     /****************************************************/ 
  273.     /* We don't need to worry about checking because we */ 
  274.     /* will only look for entries known to be there.    */
  275.     /****************************************************/ 
  276.   
  277.     /* Eliminate leading and trailing 0's: */ 
  278.            
  279.     q   = p+n; 
  280.   
  281.     for (pp=p, off=0;   *pp==0 && pp<=q;   ++pp, --off); 
  282.   
  283.     if (pp > q)   return(0);  /* no actions */ 
  284.   
  285.     p   = pp; 
  286.            
  287.     /* Now, find a place for the elements from p to q, inclusive: */ 
  288.            
  289.     r    = &y1Action[ MAXaCTIONS -1 ];
  290.   
  291.     for (rr = y1Action;   rr <= r;   ++rr, ++off) {
  292.   
  293.         /* Try rr: */ 
  294.         for (qq=rr, pp=p;   pp <= q;   ++pp, ++qq) { 
  295.   
  296.             if (*pp != 0 ) { 
  297.                 if (*pp != *qq   &&   *qq != 0)   goto nextk; 
  298.             }  
  299.         } 
  300.            
  301.         /* We have found an acceptable k: */ 
  302.            
  303. #ifdef debug  
  304.     if (y2OutputFD != NULL) {
  305.          fprintf(y2OutputFD,"off = %d, k = %d\n",off,rr-y1Action);
  306.     }
  307. #endif     
  308.   
  309.         for (qq=rr, pp=p;   pp <= q;   ++pp, ++qq) { 
  310.   
  311.             if (*pp) { 
  312.         if (qq > r   )     {
  313.             y1Error( "y3PackState: Action table overflow" );
  314.         }
  315.                 if (qq > y1NextAction)   y1NextAction = qq;
  316.                 *qq = *pp; 
  317.             }  
  318.         } 
  319.   
  320. #ifdef debug  
  321.     if (y2OutputFD != NULL) {
  322.         for (pp = y1Action;   pp <= y1NextAction;    pp += 10) {
  323.         fprintf( y2OutputFD, "\t");
  324.                 for (qq = pp;   qq <= pp+9;   ++qq) { 
  325.             fprintf( y2OutputFD, "%d ", *qq );
  326.                 } 
  327.         fprintf( y2OutputFD, "\n" );
  328.             }  
  329.         } 
  330. #endif     
  331.   
  332.         return   off; 
  333.            
  334. nextk:  ; 
  335.     } 
  336.   
  337.     y1Error( "y3PackState: No space in action table" );
  338.   
  339.     /* NOTREACHED */ 
  340.   
  341. /************************************************************************/
  342. /*    y3PutArray        Write out an array.                             */ 
  343. /************************************************************************/ 
  344. y3PutArray( s, v, n )           /* Called only from y1Others */ 
  345. char *s; 
  346. int  *v, n; 
  347.     register i; 
  348.            
  349.     fprintf( y2ytabcFD, "\nshort %s[] = {\n", s );
  350.   
  351.     for (i = 0;   i < n;   ) { 
  352.   
  353.     if (i % 10   ==   0)   fprintf( y2ytabcFD, "\n" );
  354.   
  355.     fprintf( y2ytabcFD, "%4d", v[i] );
  356.   
  357.     if (++i == n)    fprintf( y2ytabcFD, "\n};\n" );
  358.     else        fprintf( y2ytabcFD, ","      );
  359.     } 
  360.   
  361. /************************************************************************/
  362. /*    y3PutStates       Write the states and tables.                    */
  363. /************************************************************************/
  364. y3PutStates() {     /* Called only from main. */
  365.  
  366.     int          i, k, c;
  367.     register struct wset *u, *v;
  368.           
  369.     fprintf( y2ytabcFD, "\nshort yyexca[] = {\n" );
  370.           
  371.     FORaLLsTATES(i) {
  372.           
  373.     /* Write the stuff for state i: */
  374.     y1NoLookahead = !(y1StateType[i]==MUSTlOOKaHEADsTATE);
  375.     y1Closure(i);
  376.           
  377.     /* Write actions: */
  378.     y1NoLookahead = 1;
  379.     y1ArrayFill( y1Temp, y2NextTerminal+y2LastNonterminal+1, 0 );
  380.  
  381.     FORaLLwORKINGsETS(y1WorkingSet,u)  {
  382.           
  383.         c = *( u->pitem );
  384.  
  385.         if (c > 1    &&   c < FIRSTnONTERMINAL   &&     y1Temp[ c ] == 0) {
  386.  
  387.         FORaLLwORKINGsETS(u,v) {
  388.  
  389.             if (c == *(v->pitem)) {
  390.             y1PutItem( v->pitem+1, (struct looksets *)0 );
  391.             }
  392.         }
  393.         y1Temp[ c ]  = y1State( c );
  394.  
  395.         } else if( c > FIRSTnONTERMINAL && !y1Temp[ (c -= FIRSTnONTERMINAL) + y2NextTerminal ]) {
  396.  
  397.         y1Temp[ c+y2NextTerminal ] = y1Action[y1GotoIndex[i]+c];
  398.             } 
  399.     }
  400.           
  401.     if (i == 1)   y1Temp[ 1 ] = ACCEPTaCTION;
  402.           
  403.     /* We have the shifts;    Look at the reductions: */
  404.           
  405.     y3LastReduction = 0;
  406.  
  407.     FORaLLwORKINGsETS(y1WorkingSet,u) {
  408.  
  409.         c = *( u->pitem );
  410.  
  411.         if (c <= 0) {
  412.  
  413.         /* Reduction: */
  414.         y3LastReduction = -c;
  415.  
  416.         FORaLLtERMINALS(k) {
  417.  
  418.             if (GETBIT(u->ws.lset,k)) {
  419.  
  420.             if (y1Temp[ k ] == 0)  {
  421.  
  422.                 y1Temp[ k ] = c;
  423.  
  424.             } else if( y1Temp[k]<0 ) {
  425.  
  426.                 /* Reduce/reduce conflict: */
  427.                 if (y2OutputFD != NULL) {
  428.                 fprintf(
  429.                     y2OutputFD,
  430.                     "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
  431.                     i,
  432.                     -y1Temp[k],
  433.                     y3LastReduction,
  434.                     y1SymbolName(k)
  435.                 );
  436.                 }
  437.  
  438.                 if (-y1Temp[k] > y3LastReduction)    y1Temp[k] = -y3LastReduction;
  439.                 ++y1ReduceReduceConflicts;
  440.  
  441.             } else {
  442.  
  443.                 /* Potential shift/reduce conflict: */
  444.                 y3ShiftReduce( y3LastReduction, k, i );
  445.             }
  446.             }
  447.         }
  448.         }
  449.     }
  450.     y3WrtAction(i);
  451.     }
  452.     fprintf( y2ytabcFD, "\n};\n" );
  453.           
  454.     fprintf( y2ytabcFD, "# define %s %d\n", "YYNPROD", y2ThisProduction );
  455. }
  456.  
  457. /************************************************************************/
  458. /*      y3ShiftReduce   Decide a shift/reduce conflict by precedence.   */ 
  459. /************************************************************************/ 
  460. y3ShiftReduce(r,t,s)            /* Called only from y3PutStates */ 
  461. int r, t, s; 
  462.     /*****************************************************/ 
  463.     /* Decide a shift/reduce conflict by precedence.     */ 
  464.     /* r is a rule number, t a token number.             */ 
  465.     /* The conflict is in state s.                       */ 
  466.     /* y1Temp[t] is changed to reflect the action.      */
  467.     /*****************************************************/ 
  468.            
  469.     int lp,lt, action; 
  470.            
  471.     lp    = y2ProductionProperties[ r ];
  472.     lt    = y2TerminalProperties[ t ];
  473.   
  474.     if ( 
  475.     ! PRECEDENCElEVEL(lt)
  476.         || 
  477.     ! PRECEDENCElEVEL(lp)
  478.     ) { 
  479.   
  480.         /* Conflict: */ 
  481.     if (y2OutputFD != NULL) {
  482.             fprintf( 
  483.         y2OutputFD,
  484.                 "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s", 
  485.                 s, 
  486.         y1Temp[t],
  487.                 r, 
  488.                 y1SymbolName(t) 
  489.             ); 
  490.         } 
  491.     ++y1ShiftReduceConflicts;
  492.         return; 
  493.     } 
  494.   
  495.     if (PRECEDENCElEVEL(lt) == PRECEDENCElEVEL(lp)) {
  496.   
  497.     action = ASSOCIATIVITY(lt);
  498.   
  499.     } else if( PRECEDENCElEVEL(lt) > PRECEDENCElEVEL(lp) ) {
  500.   
  501.         /* Shift: */ 
  502.     action = RIGHTaSSOCIATIVE;
  503.   
  504.     } else { 
  505.   
  506.         /* Reduce: */ 
  507.     action = LEFTaSSOCIATIVE;
  508.     } 
  509.            
  510.     switch (action) { 
  511.   
  512.     case BINARYaSSOCIATIVE:
  513.         /* Error action: */ 
  514.     y1Temp[t] = ERRORaCTION;
  515.         return; 
  516.            
  517.     case LEFTaSSOCIATIVE:
  518.         /* Reduce: */ 
  519.     y1Temp[t] = -r;
  520.         return; 
  521.     } 
  522.   
  523.   
  524. /************************************************************************/
  525. /*    y3WrtAction    Write out state i.                */
  526. /************************************************************************/
  527. static y3WrtAction( i )     /* Called only from y3PutStates */
  528. int i;
  529. {
  530.     /* Write out state i.  y1Temp has the actions, y3LastReduction the default: */
  531.     int p, p0, p1;
  532.     int ntimes, tred, count, j;
  533.     int flag;
  534.           
  535.     /* Find the best choice for y3LastReduction: */
  536.           
  537.     y3LastReduction = 0;
  538.     ntimes  = 0;
  539.  
  540.     FORaLLtERMINALS(j) {
  541.  
  542.     if (y1Temp[ j ]         >=     0)   continue;
  543.     if (y1Temp[ j ] + y3LastReduction   ==     0)   continue;
  544.  
  545.     /* Count the number of appearances of y1Temp[j]: */
  546.  
  547.     count        = 0;
  548.     tred        = -y1Temp[ j ];
  549.     y2ProductionProperties[tred]   |= RULEhASbEENrEDUCED;
  550.  
  551.     FORaLLtERMINALS(p) {
  552.         if (y1Temp[ p ] + tred   ==   0)   ++count;
  553.     }
  554.  
  555.     if (count > ntimes) {
  556.         y3LastReduction = tred;
  557.         ntimes = count;
  558.     }
  559.     }
  560.           
  561.     /**********************************************************************/
  562.     /* For error recovery, arrange that, if there is a shift on the error */
  563.     /* recovery token, `error', that the default be the error action:      */
  564.     /**********************************************************************/
  565.  
  566.     if (y1Temp[ 1 ]   >   0)   y3LastReduction = 0;
  567.           
  568.     /* Clear out entries in y1Temp which equal y3LastReduction: */
  569.  
  570.     FORaLLtERMINALS(p)     if (y1Temp[ p ] + y3LastReduction   ==   0)   y1Temp[ p ] = 0;
  571.           
  572.     y3WrtState( i );
  573.  
  574.     y3DefaultAction[ i ] = y3LastReduction;
  575.     flag    =    0;
  576.  
  577.     FORaLLtERMINALS(p0) {
  578.  
  579.     if (p1 = y1Temp[ p0 ]) {
  580.  
  581.             if (p1 < 0) {
  582.  
  583.                 p1 = -p1;
  584.         goto exc;
  585.  
  586.         } else if( p1 == ACCEPTaCTION ) {
  587.  
  588.         p1 = -1;
  589.         goto exc;
  590.  
  591.         } else if( p1 ==    ERRORaCTION ) {
  592.  
  593.         p1 = 0;
  594.         goto exc;
  595. exc:      
  596.         if (flag++ == 0)   fprintf( y2ytabcFD, "-1, %d,\n", i );
  597.         fprintf( y2ytabcFD, "\t%d, %d,\n", y2Terminal[p0].value, p1 );
  598.         ++y1Exceptions;
  599.  
  600.             } else {
  601.         fprintf( y2TempFileFD, "%d,%d,", y2Terminal[p0].value, p1 );
  602.         ++y1ShiftEntries;
  603.             } 
  604.     }
  605.     }
  606.  
  607.     if (flag) {
  608.     y3DefaultAction[ i ] = -2;
  609.     fprintf( y2ytabcFD, "\t-2, %d,\n", y3LastReduction );
  610.     }
  611.     fprintf( y2TempFileFD, "\n" );
  612.     return;
  613. }
  614.  
  615. /************************************************************************/
  616. /*    y3WrtState    Write state i.                    */
  617. /************************************************************************/
  618. static y3WrtState( i )           /* Called only from y3WrtAction */
  619. int i;
  620. {
  621.     register          j0,j1;
  622.     register struct   item *pp, *qq;
  623.     register struct   wset *u;
  624.           
  625.     if (y2OutputFD == NULL)   return;
  626.     fprintf( y2OutputFD, "\nstate %d\n", i );
  627.  
  628.     FORaLLiTEMS( i, pp, qq ) {
  629.     fprintf( y2OutputFD, "\t%s\n", y1WriteItem(pp->pitem) );
  630.     }
  631.  
  632.     if (y1StateType[i] == MUSTlOOKaHEADsTATE) {
  633.  
  634.     /* Print out empty productions in closure: */
  635.     FORaLLwORKINGsETS( y1WorkingSet+(y1StateItem[i+1]-y1StateItem[i]), u ){
  636.  
  637.         if( *(u->pitem) < 0 )  {
  638.         fprintf( y2OutputFD, "\t%s\n", y1WriteItem(u->pitem) );
  639.         }
  640.     }
  641.     }
  642.           
  643.     /* Check for state equal to another: */
  644.           
  645.     FORaLLtERMINALS(j0) {
  646.  
  647.     if (j1 = y1Temp[ j0 ]) {
  648.  
  649.         fprintf( y2OutputFD, "\n\t%s  ", y1SymbolName(j0) );
  650.  
  651.         if (j1 <= 0) {
  652.         fprintf( y2OutputFD, "reduce %d",-j1 );
  653.         } else {
  654.  
  655.         /* Shift, error, or accept: */
  656.         if    (j1 == ACCEPTaCTION ) fprintf( y2OutputFD, "accept"  );
  657.         else if (j1 ==    ERRORaCTION ) fprintf( y2OutputFD, "error"   );
  658.         else             fprintf( y2OutputFD, "shift %d", j1 );
  659.         }
  660.     }
  661.     }
  662.           
  663.     /* Write the final production: */
  664.           
  665.     if (y3LastReduction)  {
  666.     fprintf( y2OutputFD, "\n\t.  reduce %d\n\n", y3LastReduction );
  667.     } else {
  668.     fprintf( y2OutputFD, "\n\t.  error\n\n"              );
  669.     }
  670.           
  671.     /* Now, output nonterminal actions: */
  672.           
  673.     j1    = y2NextTerminal;
  674.  
  675.     for (j0 = 1;   j0 <= y2LastNonterminal;   ++j0) {
  676.     if (y1Temp[ ++j1 ])  {
  677.         fprintf(
  678.         y2OutputFD,
  679.         "\t%s  goto %d\n",
  680.         y1SymbolName( j0+FIRSTnONTERMINAL),
  681.         y1Temp[j1]
  682.         );
  683.     }
  684.     }
  685. }
  686.           
  687.  
  688.