home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* y3.c */
- /* YACC source file #3 (of 4). */
- /************************************************************************/
-
- /************************************************************************/
- /* contents */
- /* */
- /* y3ActionIndex Write out the array of action-function pointers.*/
- /* * y3AGoto Write the gotos for one nonterminal. */
- /* y3Gotos Write the gotos for all nonterminals. */
- /* y3HideProductions Free up mem[] and y1Action[] for optimizer. */
- /* y3PackState Pack state i from y1Temp into y1Action. */
- /* y3PutArray Write out an array. */
- /* y3PutStates Write the states and tables. */
- /* * y3ShiftReduce Decide a shift/reduce conflict by precedence. */
- /* * y3WrtAction Write out state i. */
- /* * y3WrtState Write state i. */
- /* */
- /* * Local to this file. */
- /* */
- /************************************************************************/
-
-
- /************************************************************************/
- /* history */
- /* */
- /* 85Nov19 CrT y3ActionIndex. */
- /* 85Nov15 CrT Global variable names decrypted. */
- /* 85Nov13 CrT Give plaintiff routine in error messages. */
- /* 85Nov12 CrT Function names decrypted. Still unique in first 6 chars.*/
- /* 85Nov11 CrT y3.c reconstructed from 9 subfiles. Cosmetics. */
- /* 81Aug28 RBD Modified to make debug code conditionally compile. */
- /* 7?????? SCJ Created. */
- /* */
- /* credits */
- /* CrT=CrT */
- /* RBD=Bob Denny */
- /* SCJ=Steven C Johnson. */
- /* SG =Scott Guthery */
- /************************************************************************/
-
-
-
- #include <stdio.h>
- #include "system.h"
- #include "dtxtrn.h"
-
- /* The number of the last reduction of a state: */
- static int y3LastReduction;
-
- /* The default actions of states: */
- int y3DefaultAction[MAXsTATES];
-
- /************************************************************************/
- /* y3ActionIndex Write out the array of action-function pointers.*/
- /************************************************************************/
- y3ActionIndex() {
- int i;
-
- /* First, declare all action functions: */
-
- /* Declare the default (null) action: */
- fprintf( y2ytabcFD, "\nint yyANop();" );
-
- /* Declare all action functions created from user-supplied code chunks: */
- FORaLLpRODUCTIONS(0,i) {
- if (y2ProductionProperties[ i ] & RULEhASaCTION) {
- fprintf( y2ytabcFD, "\nint yyA%03d();", i );
- }
- }
-
- /* Now declare and initialize yyActionIndex[]: */
- fprintf( y2ytabcFD, "\n\n/* Table with an action function per rule: */" );
- fprintf(
- y2ytabcFD,
- "\nstatic (*(yyActionIndex[%d]))() = {",
- y2ThisProduction
- );
- FORaLLpRODUCTIONS(0,i) {
- if (y2ProductionProperties[ i ] & RULEhASaCTION) {
- fprintf( y2ytabcFD, "\n yyA%03d", i );
- } else {
- fprintf( y2ytabcFD, "\n yyANop" );
- }
- if (i < y2ThisProduction-1) fprintf( y2ytabcFD, "," );
- }
- fprintf( y2ytabcFD, "\n};\n\n" );
- }
-
- /************************************************************************/
- /* y3AGoto Write the gotos for one nonterminal. */
- /************************************************************************/
- static y3AGoto( c ) /* Called only from y3Gotos */
- int c;
- {
- int i, work, cc;
- struct item *p, *q;
-
-
- /* First, find nonterminals with gotos on c: */
-
- y1ArrayFill( y1Temp, y2LastNonterminal+1, 0 );
-
- y1Temp[ c ] = 1;
-
- for (work = 1; work; ) {
- work = 0;
-
- FORaLLpRODUCTIONS(0,i) {
-
- if ((cc = y2Production[ i ][ 1 ] - FIRSTnONTERMINAL) >= 0) {
-
- /* cc is a nonterminal: */
-
- if (y1Temp[ cc ]) {
-
- /* cc has a goto on c: */
-
- /* Thus, the left side of production i does too: */
- cc = *y2Production[ i ] - FIRSTnONTERMINAL;
-
- if (y1Temp[cc] == 0) {
- work = 1;
- y1Temp[cc] = 1;
- }
- }
- }
- }
- }
-
- /* "Now, we have y1Temp[c] = 1 if a goto on c in closure of cc" :-) */
-
- #ifdef debug
- if (y2OutputFD != NULL) {
-
- fprintf( y2OutputFD, "%s: gotos on ", y2NonterminalState[c].name );
-
- FORaLLnONTERMINALS(i) {
- if (y1Temp[i]) {
- fprintf( y2OutputFD, "%s ", y2NonterminalState[i].name);
- }
- }
- fprintf( y2OutputFD, "\n");
- }
- #endif
-
- /* Now, go through and put gotos into y1StateType: */
-
- y1ArrayFill( y1StateType, y1NextState, 0 );
-
- FORaLLsTATES(i) {
-
- FORaLLiTEMS(i,p,q) {
-
- if ((cc = *p->pitem) >= FIRSTnONTERMINAL) {
-
- if (y1Temp[cc -= FIRSTnONTERMINAL]) {
-
- /* goto on c is possible: */
- y1StateType[ i ] = y1Action[ y1GotoIndex[ i ] +c ];
- break;
- }
- }
- }
- }
- }
-
- /************************************************************************/
- /* y3Gotos Write the gotos for all nonterminals. */
- /************************************************************************/
- y3Gotos() { /* Called only from main. */
- int i, j, k, best, count, cbest, times;
-
- /* Mark begining of gotos: */
- fprintf( y2TempFileFD, "$\n" );
-
- for (i = 1; i <= y2LastNonterminal; ++i) {
-
- y3AGoto( i );
-
- /* Find the best one to make default: */
-
- best = -1;
- times = 0;
-
- for (j = 0; j <= y1NextState; ++j) {
-
- /* Is j the most frequent? */
- if (y1StateType[ j ] == 0) continue;
- if (y1StateType[ j ] == best) continue;
-
- /* Is y1StateType[j] the most frequent? */
-
- count = 0;
- cbest = y1StateType[ j ];
-
- for (k = j; k <= y1NextState; ++k) {
-
- if (y1StateType[ k ] == cbest) ++count;
-
- }
- if (count > times) {
- best = cbest;
- times = count;
- }
- }
-
- /* Best is now the default entry: */
-
- y1GotosSavedByDefault += (times-1);
-
- for (j = 0; j <= y1NextState; ++j) {
-
- if (y1StateType[ j ] != 0 && y1StateType[ j ] != best) {
-
- fprintf( y2TempFileFD, "%d,%d,", j, y1StateType[j] );
- y1GotoEntries += 1;
- }
- }
-
- /* Now, the default: */
-
- y1GotoEntries += 1;
- fprintf( y2TempFileFD, "%d\n", best );
- }
- }
-
- /************************************************************************/
- /* y3HideProductions Free up mem[] and y1Action[] for optimizer. */
- /************************************************************************/
- y3HideProductions() { /* Called only from main. */
-
- /********************************************************************/
- /* In order to free up the mem and y1Action arrays for the optimizer, */
- /* and still be able to output yyr1, etc., after the sizes of */
- /* the action array is known, we hide the nonterminals */
- /* derived by productions in y2ProductionProperties: */
- /********************************************************************/
-
- register i, j;
-
- j = 0;
- y2ProductionProperties[0] = 0;
-
- FORaLLpRODUCTIONS(1,i) {
- if ( !(y2ProductionProperties[i] & RULEhASbEENrEDUCED) ) {
- ++j;
-
- if (y2OutputFD != NULL) {
- fprintf(
- y2OutputFD,
- "Rule not reduced: %s\n",
- y1WriteItem( y2Production[i] )
- );
- }
- }
- y2ProductionProperties[i] = *y2Production[i] - FIRSTnONTERMINAL;
- }
- if (j) fprintf( stdout, "%d rules never reduced\n", j );
- }
-
- /************************************************************************/
- /* y3PackState Pack state i from y1Temp into y1Action. */
- /************************************************************************/
- y3PackState( p, n ) /* Called only from y1MakeStates */
- int *p;
- {
- int off;
- register *pp, *qq, *rr;
- int *q, *r;
-
- /****************************************************/
- /* We don't need to worry about checking because we */
- /* will only look for entries known to be there. */
- /****************************************************/
-
- /* Eliminate leading and trailing 0's: */
-
- q = p+n;
-
- for (pp=p, off=0; *pp==0 && pp<=q; ++pp, --off);
-
- if (pp > q) return(0); /* no actions */
-
- p = pp;
-
- /* Now, find a place for the elements from p to q, inclusive: */
-
- r = &y1Action[ MAXaCTIONS -1 ];
-
- for (rr = y1Action; rr <= r; ++rr, ++off) {
-
- /* Try rr: */
- for (qq=rr, pp=p; pp <= q; ++pp, ++qq) {
-
- if (*pp != 0 ) {
- if (*pp != *qq && *qq != 0) goto nextk;
- }
- }
-
- /* We have found an acceptable k: */
-
- #ifdef debug
- if (y2OutputFD != NULL) {
- fprintf(y2OutputFD,"off = %d, k = %d\n",off,rr-y1Action);
- }
- #endif
-
- for (qq=rr, pp=p; pp <= q; ++pp, ++qq) {
-
- if (*pp) {
- if (qq > r ) {
- y1Error( "y3PackState: Action table overflow" );
- }
- if (qq > y1NextAction) y1NextAction = qq;
- *qq = *pp;
- }
- }
-
- #ifdef debug
- if (y2OutputFD != NULL) {
- for (pp = y1Action; pp <= y1NextAction; pp += 10) {
- fprintf( y2OutputFD, "\t");
- for (qq = pp; qq <= pp+9; ++qq) {
- fprintf( y2OutputFD, "%d ", *qq );
- }
- fprintf( y2OutputFD, "\n" );
- }
- }
- #endif
-
- return off;
-
- nextk: ;
- }
-
- y1Error( "y3PackState: No space in action table" );
-
- /* NOTREACHED */
- }
-
- /************************************************************************/
- /* y3PutArray Write out an array. */
- /************************************************************************/
- y3PutArray( s, v, n ) /* Called only from y1Others */
- char *s;
- int *v, n;
- {
- register i;
-
- fprintf( y2ytabcFD, "\nshort %s[] = {\n", s );
-
- for (i = 0; i < n; ) {
-
- if (i % 10 == 0) fprintf( y2ytabcFD, "\n" );
-
- fprintf( y2ytabcFD, "%4d", v[i] );
-
- if (++i == n) fprintf( y2ytabcFD, "\n};\n" );
- else fprintf( y2ytabcFD, "," );
- }
- }
-
- /************************************************************************/
- /* y3PutStates Write the states and tables. */
- /************************************************************************/
- y3PutStates() { /* Called only from main. */
-
- int i, k, c;
- register struct wset *u, *v;
-
- fprintf( y2ytabcFD, "\nshort yyexca[] = {\n" );
-
- FORaLLsTATES(i) {
-
- /* Write the stuff for state i: */
- y1NoLookahead = !(y1StateType[i]==MUSTlOOKaHEADsTATE);
- y1Closure(i);
-
- /* Write actions: */
- y1NoLookahead = 1;
- y1ArrayFill( y1Temp, y2NextTerminal+y2LastNonterminal+1, 0 );
-
- FORaLLwORKINGsETS(y1WorkingSet,u) {
-
- c = *( u->pitem );
-
- if (c > 1 && c < FIRSTnONTERMINAL && y1Temp[ c ] == 0) {
-
- FORaLLwORKINGsETS(u,v) {
-
- if (c == *(v->pitem)) {
- y1PutItem( v->pitem+1, (struct looksets *)0 );
- }
- }
- y1Temp[ c ] = y1State( c );
-
- } else if( c > FIRSTnONTERMINAL && !y1Temp[ (c -= FIRSTnONTERMINAL) + y2NextTerminal ]) {
-
- y1Temp[ c+y2NextTerminal ] = y1Action[y1GotoIndex[i]+c];
- }
- }
-
- if (i == 1) y1Temp[ 1 ] = ACCEPTaCTION;
-
- /* We have the shifts; Look at the reductions: */
-
- y3LastReduction = 0;
-
- FORaLLwORKINGsETS(y1WorkingSet,u) {
-
- c = *( u->pitem );
-
- if (c <= 0) {
-
- /* Reduction: */
- y3LastReduction = -c;
-
- FORaLLtERMINALS(k) {
-
- if (GETBIT(u->ws.lset,k)) {
-
- if (y1Temp[ k ] == 0) {
-
- y1Temp[ k ] = c;
-
- } else if( y1Temp[k]<0 ) {
-
- /* Reduce/reduce conflict: */
- if (y2OutputFD != NULL) {
- fprintf(
- y2OutputFD,
- "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
- i,
- -y1Temp[k],
- y3LastReduction,
- y1SymbolName(k)
- );
- }
-
- if (-y1Temp[k] > y3LastReduction) y1Temp[k] = -y3LastReduction;
- ++y1ReduceReduceConflicts;
-
- } else {
-
- /* Potential shift/reduce conflict: */
- y3ShiftReduce( y3LastReduction, k, i );
- }
- }
- }
- }
- }
- y3WrtAction(i);
- }
- fprintf( y2ytabcFD, "\n};\n" );
-
- fprintf( y2ytabcFD, "# define %s %d\n", "YYNPROD", y2ThisProduction );
- }
-
- /************************************************************************/
- /* y3ShiftReduce Decide a shift/reduce conflict by precedence. */
- /************************************************************************/
- y3ShiftReduce(r,t,s) /* Called only from y3PutStates */
- int r, t, s;
- {
- /*****************************************************/
- /* Decide a shift/reduce conflict by precedence. */
- /* r is a rule number, t a token number. */
- /* The conflict is in state s. */
- /* y1Temp[t] is changed to reflect the action. */
- /*****************************************************/
-
- int lp,lt, action;
-
- lp = y2ProductionProperties[ r ];
- lt = y2TerminalProperties[ t ];
-
- if (
- ! PRECEDENCElEVEL(lt)
- ||
- ! PRECEDENCElEVEL(lp)
- ) {
-
- /* Conflict: */
- if (y2OutputFD != NULL) {
- fprintf(
- y2OutputFD,
- "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s",
- s,
- y1Temp[t],
- r,
- y1SymbolName(t)
- );
- }
- ++y1ShiftReduceConflicts;
- return;
- }
-
- if (PRECEDENCElEVEL(lt) == PRECEDENCElEVEL(lp)) {
-
- action = ASSOCIATIVITY(lt);
-
- } else if( PRECEDENCElEVEL(lt) > PRECEDENCElEVEL(lp) ) {
-
- /* Shift: */
- action = RIGHTaSSOCIATIVE;
-
- } else {
-
- /* Reduce: */
- action = LEFTaSSOCIATIVE;
- }
-
- switch (action) {
-
- case BINARYaSSOCIATIVE:
- /* Error action: */
- y1Temp[t] = ERRORaCTION;
- return;
-
- case LEFTaSSOCIATIVE:
- /* Reduce: */
- y1Temp[t] = -r;
- return;
- }
- }
-
-
- /************************************************************************/
- /* y3WrtAction Write out state i. */
- /************************************************************************/
- static y3WrtAction( i ) /* Called only from y3PutStates */
- int i;
- {
- /* Write out state i. y1Temp has the actions, y3LastReduction the default: */
- int p, p0, p1;
- int ntimes, tred, count, j;
- int flag;
-
- /* Find the best choice for y3LastReduction: */
-
- y3LastReduction = 0;
- ntimes = 0;
-
- FORaLLtERMINALS(j) {
-
- if (y1Temp[ j ] >= 0) continue;
- if (y1Temp[ j ] + y3LastReduction == 0) continue;
-
- /* Count the number of appearances of y1Temp[j]: */
-
- count = 0;
- tred = -y1Temp[ j ];
- y2ProductionProperties[tred] |= RULEhASbEENrEDUCED;
-
- FORaLLtERMINALS(p) {
- if (y1Temp[ p ] + tred == 0) ++count;
- }
-
- if (count > ntimes) {
- y3LastReduction = tred;
- ntimes = count;
- }
- }
-
- /**********************************************************************/
- /* For error recovery, arrange that, if there is a shift on the error */
- /* recovery token, `error', that the default be the error action: */
- /**********************************************************************/
-
- if (y1Temp[ 1 ] > 0) y3LastReduction = 0;
-
- /* Clear out entries in y1Temp which equal y3LastReduction: */
-
- FORaLLtERMINALS(p) if (y1Temp[ p ] + y3LastReduction == 0) y1Temp[ p ] = 0;
-
- y3WrtState( i );
-
- y3DefaultAction[ i ] = y3LastReduction;
- flag = 0;
-
- FORaLLtERMINALS(p0) {
-
- if (p1 = y1Temp[ p0 ]) {
-
- if (p1 < 0) {
-
- p1 = -p1;
- goto exc;
-
- } else if( p1 == ACCEPTaCTION ) {
-
- p1 = -1;
- goto exc;
-
- } else if( p1 == ERRORaCTION ) {
-
- p1 = 0;
- goto exc;
- exc:
- if (flag++ == 0) fprintf( y2ytabcFD, "-1, %d,\n", i );
- fprintf( y2ytabcFD, "\t%d, %d,\n", y2Terminal[p0].value, p1 );
- ++y1Exceptions;
-
- } else {
- fprintf( y2TempFileFD, "%d,%d,", y2Terminal[p0].value, p1 );
- ++y1ShiftEntries;
- }
- }
- }
-
- if (flag) {
- y3DefaultAction[ i ] = -2;
- fprintf( y2ytabcFD, "\t-2, %d,\n", y3LastReduction );
- }
- fprintf( y2TempFileFD, "\n" );
- return;
- }
-
- /************************************************************************/
- /* y3WrtState Write state i. */
- /************************************************************************/
- static y3WrtState( i ) /* Called only from y3WrtAction */
- int i;
- {
- register j0,j1;
- register struct item *pp, *qq;
- register struct wset *u;
-
- if (y2OutputFD == NULL) return;
- fprintf( y2OutputFD, "\nstate %d\n", i );
-
- FORaLLiTEMS( i, pp, qq ) {
- fprintf( y2OutputFD, "\t%s\n", y1WriteItem(pp->pitem) );
- }
-
- if (y1StateType[i] == MUSTlOOKaHEADsTATE) {
-
- /* Print out empty productions in closure: */
- FORaLLwORKINGsETS( y1WorkingSet+(y1StateItem[i+1]-y1StateItem[i]), u ){
-
- if( *(u->pitem) < 0 ) {
- fprintf( y2OutputFD, "\t%s\n", y1WriteItem(u->pitem) );
- }
- }
- }
-
- /* Check for state equal to another: */
-
- FORaLLtERMINALS(j0) {
-
- if (j1 = y1Temp[ j0 ]) {
-
- fprintf( y2OutputFD, "\n\t%s ", y1SymbolName(j0) );
-
- if (j1 <= 0) {
- fprintf( y2OutputFD, "reduce %d",-j1 );
- } else {
-
- /* Shift, error, or accept: */
- if (j1 == ACCEPTaCTION ) fprintf( y2OutputFD, "accept" );
- else if (j1 == ERRORaCTION ) fprintf( y2OutputFD, "error" );
- else fprintf( y2OutputFD, "shift %d", j1 );
- }
- }
- }
-
- /* Write the final production: */
-
- if (y3LastReduction) {
- fprintf( y2OutputFD, "\n\t. reduce %d\n\n", y3LastReduction );
- } else {
- fprintf( y2OutputFD, "\n\t. error\n\n" );
- }
-
- /* Now, output nonterminal actions: */
-
- j1 = y2NextTerminal;
-
- for (j0 = 1; j0 <= y2LastNonterminal; ++j0) {
- if (y1Temp[ ++j1 ]) {
- fprintf(
- y2OutputFD,
- "\t%s goto %d\n",
- y1SymbolName( j0+FIRSTnONTERMINAL),
- y1Temp[j1]
- );
- }
- }
- }
-
-
-