[BACK]Return to lalr.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / yacc

Diff for /src/usr.bin/yacc/lalr.c between version 1.14 and 1.15

version 1.14, 2014/01/10 11:19:31 version 1.15, 2014/03/08 01:05:39
Line 35 
Line 35 
   
 #include "defs.h"  #include "defs.h"
   
 typedef  typedef struct shorts {
   struct shorts          struct shorts *next;
     {          short value;
       struct shorts *next;  } shorts;
       short value;  
     }  
   shorts;  
   
 int tokensetsize;  int tokensetsize;
 short *lookaheads;  short *lookaheads;
Line 86 
Line 83 
 void  void
 lalr(void)  lalr(void)
 {  {
     tokensetsize = WORDSIZE(ntokens);          tokensetsize = WORDSIZE(ntokens);
   
     set_state_table();          set_state_table();
     set_accessing_symbol();          set_accessing_symbol();
     set_shift_table();          set_shift_table();
     set_reduction_table();          set_reduction_table();
     set_maxrhs();          set_maxrhs();
     initialize_LA();          initialize_LA();
     set_goto_map();          set_goto_map();
     initialize_F();          initialize_F();
     build_relations();          build_relations();
     compute_FOLLOWS();          compute_FOLLOWS();
     compute_lookaheads();          compute_lookaheads();
     free_derives();          free_derives();
     free_nullable();          free_nullable();
 }  }
   
   
 void  void
 set_state_table(void)  set_state_table(void)
 {  {
     core *sp;          core *sp;
   
     state_table = NEW2(nstates, core *);          state_table = NEW2(nstates, core *);
     for (sp = first_state; sp; sp = sp->next)          for (sp = first_state; sp; sp = sp->next)
         state_table[sp->number] = sp;                  state_table[sp->number] = sp;
 }  }
   
   
 void  void
 set_accessing_symbol(void)  set_accessing_symbol(void)
 {  {
     core *sp;          core *sp;
   
     accessing_symbol = NEW2(nstates, short);          accessing_symbol = NEW2(nstates, short);
     for (sp = first_state; sp; sp = sp->next)          for (sp = first_state; sp; sp = sp->next)
         accessing_symbol[sp->number] = sp->accessing_symbol;                  accessing_symbol[sp->number] = sp->accessing_symbol;
 }  }
   
   
 void  void
 set_shift_table(void)  set_shift_table(void)
 {  {
     shifts *sp;          shifts *sp;
   
     shift_table = NEW2(nstates, shifts *);          shift_table = NEW2(nstates, shifts *);
     for (sp = first_shift; sp; sp = sp->next)          for (sp = first_shift; sp; sp = sp->next)
         shift_table[sp->number] = sp;                  shift_table[sp->number] = sp;
 }  }
   
   
 void  void
 set_reduction_table(void)  set_reduction_table(void)
 {  {
     reductions *rp;          reductions *rp;
   
     reduction_table = NEW2(nstates, reductions *);          reduction_table = NEW2(nstates, reductions *);
     for (rp = first_reduction; rp; rp = rp->next)          for (rp = first_reduction; rp; rp = rp->next)
         reduction_table[rp->number] = rp;                  reduction_table[rp->number] = rp;
 }  }
   
   
 void  void
 set_maxrhs(void)  set_maxrhs(void)
 {  {
   short *itemp;          short *itemp;
   short *item_end;          short *item_end;
   int length;          int length;
   int max;          int max;
   
   length = 0;          length = 0;
   max = 0;          max = 0;
   item_end = ritem + nitems;          item_end = ritem + nitems;
   for (itemp = ritem; itemp < item_end; itemp++)          for (itemp = ritem; itemp < item_end; itemp++) {
     {                  if (*itemp >= 0) {
       if (*itemp >= 0)                          length++;
         {                  } else {
           length++;                          if (length > max) max = length;
                           length = 0;
                   }
         }          }
       else  
         {  
           if (length > max) max = length;  
           length = 0;  
         }  
     }  
   
   maxrhs = max;          maxrhs = max;
 }  }
   
   
 void  void
 initialize_LA(void)  initialize_LA(void)
 {  {
   int i, j, k;          int i, j, k;
   reductions *rp;          reductions *rp;
   
   lookaheads = NEW2(nstates + 1, short);          lookaheads = NEW2(nstates + 1, short);
   
   k = 0;          k = 0;
   for (i = 0; i < nstates; i++)          for (i = 0; i < nstates; i++) {
     {                  lookaheads[i] = k;
       lookaheads[i] = k;                  rp = reduction_table[i];
       rp = reduction_table[i];                  if (rp)
       if (rp)                          k += rp->nreds;
         k += rp->nreds;          }
     }          lookaheads[nstates] = k;
   lookaheads[nstates] = k;  
   
   LA = NEW2(k * tokensetsize, unsigned);          LA = NEW2(k * tokensetsize, unsigned);
   LAruleno = NEW2(k, short);          LAruleno = NEW2(k, short);
   lookback = NEW2(k, shorts *);          lookback = NEW2(k, shorts *);
   
   k = 0;          k = 0;
   for (i = 0; i < nstates; i++)          for (i = 0; i < nstates; i++) {
     {                  rp = reduction_table[i];
       rp = reduction_table[i];                  if (rp) {
       if (rp)                          for (j = 0; j < rp->nreds; j++) {
         {                                  LAruleno[k] = rp->rules[j];
           for (j = 0; j < rp->nreds; j++)                                  k++;
             {                          }
               LAruleno[k] = rp->rules[j];                  }
               k++;  
             }  
         }          }
     }  
 }  }
   
 void  void
 set_goto_map(void)  set_goto_map(void)
 {  {
   shifts *sp;          shifts *sp;
   int i;          int i;
   int symbol;          int symbol;
   int k;          int k;
   short *temp_map;          short *temp_map;
   int state2;          int state2;
   int state1;          int state1;
   
   goto_map = NEW2(nvars + 1, short) - ntokens;          goto_map = NEW2(nvars + 1, short) - ntokens;
   temp_map = NEW2(nvars + 1, short) - ntokens;          temp_map = NEW2(nvars + 1, short) - ntokens;
   
   ngotos = 0;          ngotos = 0;
   for (sp = first_shift; sp; sp = sp->next)          for (sp = first_shift; sp; sp = sp->next) {
     {                  for (i = sp->nshifts - 1; i >= 0; i--) {
       for (i = sp->nshifts - 1; i >= 0; i--)                          symbol = accessing_symbol[sp->shift[i]];
         {  
           symbol = accessing_symbol[sp->shift[i]];  
   
           if (ISTOKEN(symbol)) break;                          if (ISTOKEN(symbol)) break;
   
           if (ngotos == MAXSHORT)                          if (ngotos == MAXSHORT)
             fatal("too many gotos");                                  fatal("too many gotos");
   
           ngotos++;                          ngotos++;
           goto_map[symbol]++;                          goto_map[symbol]++;
         }                  }
     }          }
   
   k = 0;          k = 0;
   for (i = ntokens; i < nsyms; i++)          for (i = ntokens; i < nsyms; i++) {
     {                  temp_map[i] = k;
       temp_map[i] = k;                  k += goto_map[i];
       k += goto_map[i];          }
     }  
   
   for (i = ntokens; i < nsyms; i++)          for (i = ntokens; i < nsyms; i++)
     goto_map[i] = temp_map[i];                  goto_map[i] = temp_map[i];
   
   goto_map[nsyms] = ngotos;          goto_map[nsyms] = ngotos;
   temp_map[nsyms] = ngotos;          temp_map[nsyms] = ngotos;
   
   from_state = NEW2(ngotos, short);          from_state = NEW2(ngotos, short);
   to_state = NEW2(ngotos, short);          to_state = NEW2(ngotos, short);
   
   for (sp = first_shift; sp; sp = sp->next)          for (sp = first_shift; sp; sp = sp->next) {
     {                  state1 = sp->number;
       state1 = sp->number;                  for (i = sp->nshifts - 1; i >= 0; i--) {
       for (i = sp->nshifts - 1; i >= 0; i--)                          state2 = sp->shift[i];
         {                          symbol = accessing_symbol[state2];
           state2 = sp->shift[i];  
           symbol = accessing_symbol[state2];  
   
           if (ISTOKEN(symbol)) break;                          if (ISTOKEN(symbol)) break;
   
           k = temp_map[symbol]++;                          k = temp_map[symbol]++;
           from_state[k] = state1;                          from_state[k] = state1;
           to_state[k] = state2;                          to_state[k] = state2;
                   }
         }          }
     }  
   
   free(temp_map + ntokens);          free(temp_map + ntokens);
 }  }
   
   
Line 286 
Line 270 
 int  int
 map_goto(int state, int symbol)  map_goto(int state, int symbol)
 {  {
     int high;          int high;
     int low;          int low;
     int middle;          int middle;
     int s;          int s;
   
     low = goto_map[symbol];          low = goto_map[symbol];
     high = goto_map[symbol + 1];          high = goto_map[symbol + 1];
   
     for (;;)          for (;;) {
     {                  assert(low <= high);
         assert(low <= high);                  middle = (low + high) >> 1;
         middle = (low + high) >> 1;                  s = from_state[middle];
         s = from_state[middle];                  if (s == state)
         if (s == state)                          return (middle);
             return (middle);                  else if (s < state)
         else if (s < state)                          low = middle + 1;
             low = middle + 1;                  else
         else                          high = middle - 1;
             high = middle - 1;          }
     }  
 }  }
   
   
 void  void
 initialize_F(void)  initialize_F(void)
 {  {
   int i;          int i;
   int j;          int j;
   int k;          int k;
   shifts *sp;          shifts *sp;
   short *edge;          short *edge;
   unsigned *rowp;          unsigned *rowp;
   short *rp;          short *rp;
   short **reads;          short **reads;
   int nedges;          int nedges;
   int stateno;          int stateno;
   int symbol;          int symbol;
   int nwords;          int nwords;
   
   nwords = ngotos * tokensetsize;          nwords = ngotos * tokensetsize;
   F = NEW2(nwords, unsigned);          F = NEW2(nwords, unsigned);
   
   reads = NEW2(ngotos, short *);          reads = NEW2(ngotos, short *);
   edge = NEW2(ngotos + 1, short);          edge = NEW2(ngotos + 1, short);
   nedges = 0;          nedges = 0;
   
   rowp = F;          rowp = F;
   for (i = 0; i < ngotos; i++)          for (i = 0; i < ngotos; i++) {
     {                  stateno = to_state[i];
       stateno = to_state[i];                  sp = shift_table[stateno];
       sp = shift_table[stateno];  
   
       if (sp)                  if (sp) {
         {                          k = sp->nshifts;
           k = sp->nshifts;  
   
           for (j = 0; j < k; j++)                          for (j = 0; j < k; j++) {
             {                                  symbol = accessing_symbol[sp->shift[j]];
               symbol = accessing_symbol[sp->shift[j]];                                  if (ISVAR(symbol))
               if (ISVAR(symbol))                                          break;
                 break;                                  SETBIT(rowp, symbol);
               SETBIT(rowp, symbol);                          }
             }  
   
           for (; j < k; j++)                          for (; j < k; j++) {
             {                                  symbol = accessing_symbol[sp->shift[j]];
               symbol = accessing_symbol[sp->shift[j]];                                  if (nullable[symbol])
               if (nullable[symbol])                                          edge[nedges++] = map_goto(stateno, symbol);
                 edge[nedges++] = map_goto(stateno, symbol);                          }
             }  
                           if (nedges) {
           if (nedges)                                  reads[i] = rp = NEW2(nedges + 1, short);
             {  
               reads[i] = rp = NEW2(nedges + 1, short);  
   
               for (j = 0; j < nedges; j++)                                  for (j = 0; j < nedges; j++)
                 rp[j] = edge[j];                                          rp[j] = edge[j];
   
               rp[nedges] = -1;                                  rp[nedges] = -1;
               nedges = 0;                                  nedges = 0;
             }                          }
                   }
   
                   rowp += tokensetsize;
         }          }
   
       rowp += tokensetsize;          SETBIT(F, 0);
     }          digraph(reads);
   
   SETBIT(F, 0);          for (i = 0; i < ngotos; i++) {
   digraph(reads);                  if (reads[i])
                           free(reads[i]);
           }
   
   for (i = 0; i < ngotos; i++)          free(reads);
     {          free(edge);
       if (reads[i])  
         free(reads[i]);  
     }  
   
   free(reads);  
   free(edge);  
 }  }
   
   
 void  void
 build_relations(void)  build_relations(void)
 {  {
   int i;          int i;
   int j;          int j;
   int k;          int k;
   short *rulep;          short *rulep;
   short *rp;          short *rp;
   shifts *sp;          shifts *sp;
   int length;          int length;
   int nedges;          int nedges;
   int done;          int done;
   int state1;          int state1;
   int stateno;          int stateno;
   int symbol1;          int symbol1;
   int symbol2;          int symbol2;
   short *shortp;          short *shortp;
   short *edge;          short *edge;
   short *states;          short *states;
   short **new_includes;          short **new_includes;
   
   includes = NEW2(ngotos, short *);          includes = NEW2(ngotos, short *);
   edge = NEW2(ngotos + 1, short);          edge = NEW2(ngotos + 1, short);
   states = NEW2(maxrhs + 1, short);          states = NEW2(maxrhs + 1, short);
   
   for (i = 0; i < ngotos; i++)          for (i = 0; i < ngotos; i++) {
     {                  nedges = 0;
       nedges = 0;                  state1 = from_state[i];
       state1 = from_state[i];                  symbol1 = accessing_symbol[to_state[i]];
       symbol1 = accessing_symbol[to_state[i]];  
   
       for (rulep = derives[symbol1]; *rulep >= 0; rulep++)                  for (rulep = derives[symbol1]; *rulep >= 0; rulep++) {
         {                          length = 1;
           length = 1;                          states[0] = state1;
           states[0] = state1;                          stateno = state1;
           stateno = state1;  
   
           for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)                          for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++) {
             {                                  symbol2 = *rp;
               symbol2 = *rp;                                  sp = shift_table[stateno];
               sp = shift_table[stateno];                                  k = sp->nshifts;
               k = sp->nshifts;  
   
               for (j = 0; j < k; j++)                                  for (j = 0; j < k; j++) {
                 {                                          stateno = sp->shift[j];
                   stateno = sp->shift[j];                                          if (accessing_symbol[stateno] == symbol2)
                   if (accessing_symbol[stateno] == symbol2) break;                                                  break;
                 }                                  }
   
               states[length++] = stateno;                                  states[length++] = stateno;
             }                          }
   
           add_lookback_edge(stateno, *rulep, i);                          add_lookback_edge(stateno, *rulep, i);
   
           length--;                          length--;
           done = 0;                          done = 0;
           while (!done)                          while (!done) {
             {                                  done = 1;
               done = 1;                                  rp--;
               rp--;                                  if (ISVAR(*rp)) {
               if (ISVAR(*rp))                                          stateno = states[--length];
                 {                                          edge[nedges++] = map_goto(stateno, *rp);
                   stateno = states[--length];                                          if (nullable[*rp] && length > 0)
                   edge[nedges++] = map_goto(stateno, *rp);                                                  done = 0;
                   if (nullable[*rp] && length > 0) done = 0;                                  }
                           }
                 }                  }
             }  
         }  
   
       if (nedges)                  if (nedges) {
         {                          includes[i] = shortp = NEW2(nedges + 1, short);
           includes[i] = shortp = NEW2(nedges + 1, short);                          for (j = 0; j < nedges; j++)
           for (j = 0; j < nedges; j++)                                  shortp[j] = edge[j];
             shortp[j] = edge[j];                          shortp[nedges] = -1;
           shortp[nedges] = -1;                  }
         }          }
     }  
   
   new_includes = transpose(includes, ngotos);          new_includes = transpose(includes, ngotos);
   
   for (i = 0; i < ngotos; i++)          for (i = 0; i < ngotos; i++)
     if (includes[i])                  if (includes[i])
       free(includes[i]);                          free(includes[i]);
   
   free(includes);          free(includes);
   
   includes = new_includes;          includes = new_includes;
   
   free(edge);          free(edge);
   free(states);          free(states);
 }  }
   
 void  void
 add_lookback_edge(int stateno, int ruleno, int gotono)  add_lookback_edge(int stateno, int ruleno, int gotono)
 {  {
     int i, k;          int i, k;
     int found;          int found;
     shorts *sp;          shorts *sp;
   
     i = lookaheads[stateno];          i = lookaheads[stateno];
     k = lookaheads[stateno + 1];          k = lookaheads[stateno + 1];
     found = 0;          found = 0;
     while (!found && i < k)          while (!found && i < k) {
     {                  if (LAruleno[i] == ruleno)
         if (LAruleno[i] == ruleno)                          found = 1;
             found = 1;                  else
         else                          ++i;
             ++i;          }
     }          assert(found);
     assert(found);  
   
     sp = NEW(shorts);          sp = NEW(shorts);
     sp->next = lookback[i];          sp->next = lookback[i];
     sp->value = gotono;          sp->value = gotono;
     lookback[i] = sp;          lookback[i] = sp;
 }  }
   
   
Line 508 
Line 479 
 short **  short **
 transpose(short **R, int n)  transpose(short **R, int n)
 {  {
   short **new_R;          short **new_R;
   short **temp_R;          short **temp_R;
   short *nedges;          short *nedges;
   short *sp;          short *sp;
   int i;          int i;
   int k;          int k;
   
   nedges = NEW2(n, short);          nedges = NEW2(n, short);
   
   for (i = 0; i < n; i++)          for (i = 0; i < n; i++) {
     {                  sp = R[i];
       sp = R[i];                  if (sp) {
       if (sp)                          while (*sp >= 0)
         {                                  nedges[*sp++]++;
           while (*sp >= 0)                  }
             nedges[*sp++]++;  
         }          }
     }  
   
   new_R = NEW2(n, short *);          new_R = NEW2(n, short *);
   temp_R = NEW2(n, short *);          temp_R = NEW2(n, short *);
   
   for (i = 0; i < n; i++)          for (i = 0; i < n; i++) {
     {                  k = nedges[i];
       k = nedges[i];                  if (k > 0) {
       if (k > 0)                          sp = NEW2(k + 1, short);
         {                          new_R[i] = sp;
           sp = NEW2(k + 1, short);                          temp_R[i] = sp;
           new_R[i] = sp;                          sp[k] = -1;
           temp_R[i] = sp;                  }
           sp[k] = -1;  
         }          }
     }  
   
   free(nedges);          free(nedges);
   
   for (i = 0; i < n; i++)          for (i = 0; i < n; i++) {
     {                  sp = R[i];
       sp = R[i];                  if (sp) {
       if (sp)                          while (*sp >= 0)
         {                                  *temp_R[*sp++]++ = i;
           while (*sp >= 0)                  }
             *temp_R[*sp++]++ = i;  
         }          }
     }  
   
   free(temp_R);          free(temp_R);
   
   return (new_R);          return (new_R);
 }  }
   
   
 void  void
 compute_FOLLOWS(void)  compute_FOLLOWS(void)
 {  {
   digraph(includes);          digraph(includes);
 }  }
   
 void  void
 compute_lookaheads(void)  compute_lookaheads(void)
 {  {
   int i, n;          int i, n;
   unsigned *fp1, *fp2, *fp3;          unsigned *fp1, *fp2, *fp3;
   shorts *sp, *next;          shorts *sp, *next;
   unsigned *rowp;          unsigned *rowp;
   
   rowp = LA;          rowp = LA;
   n = lookaheads[nstates];          n = lookaheads[nstates];
   for (i = 0; i < n; i++)          for (i = 0; i < n; i++) {
     {                  fp3 = rowp + tokensetsize;
       fp3 = rowp + tokensetsize;                  for (sp = lookback[i]; sp; sp = sp->next) {
       for (sp = lookback[i]; sp; sp = sp->next)                          fp1 = rowp;
         {                          fp2 = F + tokensetsize * sp->value;
           fp1 = rowp;                          while (fp1 < fp3)
           fp2 = F + tokensetsize * sp->value;                                  *fp1++ |= *fp2++;
           while (fp1 < fp3)                  }
             *fp1++ |= *fp2++;                  rowp = fp3;
         }          }
       rowp = fp3;  
     }  
   
   for (i = 0; i < n; i++)          for (i = 0; i < n; i++)
     for (sp = lookback[i]; sp; sp = next)                  for (sp = lookback[i]; sp; sp = next) {
       {                          next = sp->next;
         next = sp->next;                          free(sp);
         free(sp);                  }
       }  
   
   free(lookback);          free(lookback);
   free(F);          free(F);
 }  }
   
 void  void
 digraph(short **relation)  digraph(short **relation)
 {  {
   int i;          int i;
   
   infinity = ngotos + 2;          infinity = ngotos + 2;
   INDEX = NEW2(ngotos + 1, short);          INDEX = NEW2(ngotos + 1, short);
   VERTICES = NEW2(ngotos + 1, short);          VERTICES = NEW2(ngotos + 1, short);
   top = 0;          top = 0;
   R = relation;          R = relation;
   
   memset(INDEX, 0, ngotos * sizeof(short));          memset(INDEX, 0, ngotos * sizeof(short));
   for (i = 0; i < ngotos; i++)          for (i = 0; i < ngotos; i++)
       if (R[i])                  if (R[i])
           traverse(i);                          traverse(i);
   
   free(INDEX);          free(INDEX);
   free(VERTICES);          free(VERTICES);
 }  }
   
   
 void  void
 traverse(int i)  traverse(int i)
 {  {
   unsigned *fp1;          unsigned *fp1;
   unsigned *fp2;          unsigned *fp2;
   unsigned *fp3;          unsigned *fp3;
   int j;          int j;
   short *rp;          short *rp;
   
   int height;          int height;
   unsigned *base;          unsigned *base;
   
   VERTICES[++top] = i;          VERTICES[++top] = i;
   INDEX[i] = height = top;          INDEX[i] = height = top;
   
   base = F + i * tokensetsize;          base = F + i * tokensetsize;
   fp3 = base + tokensetsize;          fp3 = base + tokensetsize;
   
   rp = R[i];          rp = R[i];
   if (rp)          if (rp) {
     {                  while ((j = *rp++) >= 0) {
       while ((j = *rp++) >= 0)                          if (INDEX[j] == 0)
         {                                  traverse(j);
           if (INDEX[j] == 0)  
             traverse(j);  
   
           if (INDEX[i] > INDEX[j])                          if (INDEX[i] > INDEX[j])
             INDEX[i] = INDEX[j];                                  INDEX[i] = INDEX[j];
   
           fp1 = base;                          fp1 = base;
           fp2 = F + j * tokensetsize;                          fp2 = F + j * tokensetsize;
   
           while (fp1 < fp3)                          while (fp1 < fp3)
             *fp1++ |= *fp2++;                                  *fp1++ |= *fp2++;
                   }
         }          }
     }  
   
   if (INDEX[i] == height)          if (INDEX[i] == height) {
     {                  for (;;) {
       for (;;)                          j = VERTICES[top--];
         {                          INDEX[j] = infinity;
           j = VERTICES[top--];  
           INDEX[j] = infinity;  
   
           if (i == j)                          if (i == j)
             break;                                  break;
   
           fp1 = base;                          fp1 = base;
           fp2 = F + j * tokensetsize;                          fp2 = F + j * tokensetsize;
   
           while (fp1 < fp3)                          while (fp1 < fp3)
             *fp2++ = *fp1++;                                  *fp2++ = *fp1++;
                   }
         }          }
     }  
 }  }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15