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

Diff for /src/usr.bin/yacc/lr0.c between version 1.16 and 1.17

version 1.16, 2014/01/13 23:14:17 version 1.17, 2014/03/13 00:59:34
Line 1 
Line 1 
 /*      $OpenBSD$       */  /* $OpenBSD$     */
 /*      $NetBSD: lr0.c,v 1.4 1996/03/19 03:21:35 jtc Exp $      */  /* $NetBSD: lr0.c,v 1.4 1996/03/19 03:21:35 jtc Exp $    */
   
 /*  /*
  * Copyright (c) 1989 The Regents of the University of California.   * Copyright (c) 1989 The Regents of the University of California.
Line 79 
Line 79 
 void  void
 allocate_itemsets(void)  allocate_itemsets(void)
 {  {
     short *itemp;          short *itemp;
     short *item_end;          short *item_end;
     int symbol;          int symbol;
     int i;          int i;
     int count;          int count;
     int max;          int max;
     short *symbol_count;          short *symbol_count;
   
     count = 0;          count = 0;
     symbol_count = NEW2(nsyms, short);          symbol_count = NEW2(nsyms, short);
   
     item_end = ritem + nitems;          item_end = ritem + nitems;
     for (itemp = ritem; itemp < item_end; itemp++)          for (itemp = ritem; itemp < item_end; itemp++) {
     {                  symbol = *itemp;
         symbol = *itemp;                  if (symbol >= 0) {
         if (symbol >= 0)                          count++;
         {                          symbol_count[symbol]++;
             count++;                  }
             symbol_count[symbol]++;  
         }          }
     }  
   
     kernel_base = NEW2(nsyms, short *);          kernel_base = NEW2(nsyms, short *);
     kernel_items = NEW2(count, short);          kernel_items = NEW2(count, short);
   
     count = 0;          count = 0;
     max = 0;          max = 0;
     for (i = 0; i < nsyms; i++)          for (i = 0; i < nsyms; i++) {
     {                  kernel_base[i] = kernel_items + count;
         kernel_base[i] = kernel_items + count;                  count += symbol_count[i];
         count += symbol_count[i];                  if (max < symbol_count[i])
         if (max < symbol_count[i])                          max = symbol_count[i];
             max = symbol_count[i];          }
     }  
   
     shift_symbol = symbol_count;          shift_symbol = symbol_count;
     kernel_end = NEW2(nsyms, short *);          kernel_end = NEW2(nsyms, short *);
 }  }
   
 void  void
 allocate_storage(void)  allocate_storage(void)
 {  {
     allocate_itemsets();          allocate_itemsets();
     shiftset = NEW2(nsyms, short);          shiftset = NEW2(nsyms, short);
     redset = NEW2(nrules + 1, short);          redset = NEW2(nrules + 1, short);
     state_set = NEW2(nitems, core *);          state_set = NEW2(nitems, core *);
 }  }
   
 void  void
 append_states(void)  append_states(void)
 {  {
     int i;          int i;
     int j;          int j;
     int symbol;          int symbol;
   
 #ifdef  TRACE  #ifdef  TRACE
     fprintf(stderr, "Entering append_states()\n");          fprintf(stderr, "Entering append_states()\n");
 #endif  #endif
     for (i = 1; i < nshifts; i++)          for (i = 1; i < nshifts; i++) {
     {                  symbol = shift_symbol[i];
         symbol = shift_symbol[i];                  j = i;
         j = i;                  while (j > 0 && shift_symbol[j - 1] > symbol) {
         while (j > 0 && shift_symbol[j - 1] > symbol)                          shift_symbol[j] = shift_symbol[j - 1];
         {                          j--;
             shift_symbol[j] = shift_symbol[j - 1];                  }
             j--;                  shift_symbol[j] = symbol;
         }          }
         shift_symbol[j] = symbol;  
     }  
   
     for (i = 0; i < nshifts; i++)          for (i = 0; i < nshifts; i++) {
     {                  symbol = shift_symbol[i];
         symbol = shift_symbol[i];                  shiftset[i] = get_state(symbol);
         shiftset[i] = get_state(symbol);          }
     }  
 }  }
   
 void  void
 free_storage(void)  free_storage(void)
 {  {
     free(shift_symbol);          free(shift_symbol);
     free(redset);          free(redset);
     free(shiftset);          free(shiftset);
     free(kernel_base);          free(kernel_base);
     free(kernel_end);          free(kernel_end);
     free(kernel_items);          free(kernel_items);
     free(state_set);          free(state_set);
 }  }
   
   
 void  void
 generate_states(void)  generate_states(void)
 {  {
     allocate_storage();          allocate_storage();
     itemset = NEW2(nitems, short);          itemset = NEW2(nitems, short);
     ruleset = NEW2(WORDSIZE(nrules), unsigned);          ruleset = NEW2(WORDSIZE(nrules), unsigned);
     set_first_derives();          set_first_derives();
     initialize_states();          initialize_states();
   
     while (this_state)          while (this_state) {
     {                  closure(this_state->items, this_state->nitems);
         closure(this_state->items, this_state->nitems);                  save_reductions();
         save_reductions();                  new_itemsets();
         new_itemsets();                  append_states();
         append_states();  
   
         if (nshifts > 0)                  if (nshifts > 0)
             save_shifts();                          save_shifts();
   
         this_state = this_state->next;                  this_state = this_state->next;
     }          }
   
     finalize_closure();          finalize_closure();
     free_storage();          free_storage();
 }  }
   
   
Line 200 
Line 193 
 short  short
 get_state(int symbol)  get_state(int symbol)
 {  {
     int key;          int key;
     short *isp1;          short *isp1;
     short *isp2;          short *isp2;
     short *iend;          short *iend;
     core *sp;          core *sp;
     int found;          int found;
     int n;          int n;
   
 #ifdef  TRACE  #ifdef  TRACE
     fprintf(stderr, "Entering get_state(%d)\n", symbol);          fprintf(stderr, "Entering get_state(%d)\n", symbol);
 #endif  #endif
   
     isp1 = kernel_base[symbol];          isp1 = kernel_base[symbol];
     iend = kernel_end[symbol];          iend = kernel_end[symbol];
     n = iend - isp1;          n = iend - isp1;
   
     key = *isp1;          key = *isp1;
     assert(0 <= key && key < nitems);          assert(0 <= key && key < nitems);
     sp = state_set[key];          sp = state_set[key];
     if (sp)          if (sp) {
     {                  found = 0;
         found = 0;                  while (!found) {
         while (!found)                          if (sp->nitems == n) {
         {                                  found = 1;
             if (sp->nitems == n)                                  isp1 = kernel_base[symbol];
             {                                  isp2 = sp->items;
                 found = 1;  
                 isp1 = kernel_base[symbol];  
                 isp2 = sp->items;  
   
                 while (found && isp1 < iend)                                  while (found && isp1 < iend) {
                 {                                          if (*isp1++ != *isp2++)
                     if (*isp1++ != *isp2++)                                                  found = 0;
                         found = 0;                                  }
                           }
                           if (!found) {
                                   if (sp->link) {
                                           sp = sp->link;
                                   } else {
                                           sp = sp->link = new_state(symbol);
                                           found = 1;
                                   }
                           }
                 }                  }
             }          } else {
                   state_set[key] = sp = new_state(symbol);
             if (!found)  
             {  
                 if (sp->link)  
                 {  
                     sp = sp->link;  
                 }  
                 else  
                 {  
                     sp = sp->link = new_state(symbol);  
                     found = 1;  
                 }  
             }  
         }          }
     }  
     else  
     {  
         state_set[key] = sp = new_state(symbol);  
     }  
   
     return (sp->number);          return (sp->number);
 }  }
   
   
 void  void
 initialize_states(void)  initialize_states(void)
 {  {
     int i;          int i;
     short *start_derives;          short *start_derives;
     core *p;          core *p;
   
     start_derives = derives[start_symbol];          start_derives = derives[start_symbol];
     for (i = 0; start_derives[i] >= 0; ++i)          for (i = 0; start_derives[i] >= 0; ++i)
         continue;                  continue;
   
     p = (core *) malloc(sizeof(core) + i*sizeof(short));          p = malloc(sizeof(core) + i * sizeof(short));
     if (p == 0) no_space();          if (p == NULL)
                   no_space();
   
     p->next = 0;          p->next = 0;
     p->link = 0;          p->link = 0;
     p->number = 0;          p->number = 0;
     p->accessing_symbol = 0;          p->accessing_symbol = 0;
     p->nitems = i;          p->nitems = i;
   
     for (i = 0;  start_derives[i] >= 0; ++i)          for (i = 0; start_derives[i] >= 0; ++i)
         p->items[i] = rrhs[start_derives[i]];                  p->items[i] = rrhs[start_derives[i]];
   
     first_state = last_state = this_state = p;          first_state = last_state = this_state = p;
     nstates = 1;          nstates = 1;
 }  }
   
 void  void
 new_itemsets(void)  new_itemsets(void)
 {  {
     int i;          int i;
     int shiftcount;          int shiftcount;
     short *isp;          short *isp;
     short *ksp;          short *ksp;
     int symbol;          int symbol;
   
     memset(kernel_end, 0, nsyms * sizeof(short *));          memset(kernel_end, 0, nsyms * sizeof(short *));
   
     shiftcount = 0;          shiftcount = 0;
     isp = itemset;          isp = itemset;
     while (isp < itemsetend)          while (isp < itemsetend) {
     {                  i = *isp++;
         i = *isp++;                  symbol = ritem[i];
         symbol = ritem[i];                  if (symbol > 0) {
         if (symbol > 0)                          ksp = kernel_end[symbol];
         {                          if (!ksp) {
             ksp = kernel_end[symbol];                                  shift_symbol[shiftcount++] = symbol;
             if (!ksp)                                  ksp = kernel_base[symbol];
             {                          }
                 shift_symbol[shiftcount++] = symbol;                          *ksp++ = i + 1;
                 ksp = kernel_base[symbol];                          kernel_end[symbol] = ksp;
             }                  }
   
             *ksp++ = i + 1;  
             kernel_end[symbol] = ksp;  
         }          }
     }  
   
     nshifts = shiftcount;          nshifts = shiftcount;
 }  }
   
   
Line 326 
Line 305 
 core *  core *
 new_state(int symbol)  new_state(int symbol)
 {  {
     int n;          int n;
     core *p;          core *p;
     short *isp1;          short *isp1;
     short *isp2;          short *isp2;
     short *iend;          short *iend;
   
 #ifdef  TRACE  #ifdef  TRACE
     fprintf(stderr, "Entering new_state(%d)\n", symbol);          fprintf(stderr, "Entering new_state(%d)\n", symbol);
 #endif  #endif
   
     if (nstates >= MAXSHORT)          if (nstates >= MAXSHORT)
         fatal("too many states");                  fatal("too many states");
   
     isp1 = kernel_base[symbol];          isp1 = kernel_base[symbol];
     iend = kernel_end[symbol];          iend = kernel_end[symbol];
     n = iend - isp1;          n = iend - isp1;
   
     p = allocate(sizeof(core) + (n - 1) * sizeof(short));          p = allocate(sizeof(core) + (n - 1) * sizeof(short));
     p->accessing_symbol = symbol;          p->accessing_symbol = symbol;
     p->number = nstates;          p->number = nstates;
     p->nitems = n;          p->nitems = n;
   
     isp2 = p->items;          isp2 = p->items;
     while (isp1 < iend)          while (isp1 < iend)
         *isp2++ = *isp1++;                  *isp2++ = *isp1++;
   
     last_state->next = p;          last_state->next = p;
     last_state = p;          last_state = p;
   
     nstates++;          nstates++;
   
     return (p);          return (p);
 }  }
   
   
 void  void
 save_shifts(void)  save_shifts(void)
 {  {
     shifts *p;          shifts *p;
     short *sp1;          short *sp1;
     short *sp2;          short *sp2;
     short *send;          short *send;
   
     p = allocate(sizeof(shifts) + (nshifts - 1) * sizeof(short));          p = allocate(sizeof(shifts) + (nshifts - 1) * sizeof(short));
   
     p->number = this_state->number;          p->number = this_state->number;
     p->nshifts = nshifts;          p->nshifts = nshifts;
   
     sp1 = shiftset;          sp1 = shiftset;
     sp2 = p->shift;          sp2 = p->shift;
     send = shiftset + nshifts;          send = shiftset + nshifts;
   
     while (sp1 < send)          while (sp1 < send)
         *sp2++ = *sp1++;                  *sp2++ = *sp1++;
   
     if (last_shift)          if (last_shift) {
     {                  last_shift->next = p;
         last_shift->next = p;                  last_shift = p;
         last_shift = p;          } else {
     }                  first_shift = p;
     else                  last_shift = p;
     {          }
         first_shift = p;  
         last_shift = p;  
     }  
 }  }
   
   
 void  void
 save_reductions(void)  save_reductions(void)
 {  {
     short *isp;          short *isp;
     short *rp1;          short *rp1;
     short *rp2;          short *rp2;
     int item;          int item;
     int count;          int count;
     reductions *p;          reductions *p;
     short *rend;          short *rend;
   
     count = 0;          count = 0;
     for (isp = itemset; isp < itemsetend; isp++)          for (isp = itemset; isp < itemsetend; isp++) {
     {                  item = ritem[*isp];
         item = ritem[*isp];                  if (item < 0) {
         if (item < 0)                          redset[count++] = -item;
         {                  }
             redset[count++] = -item;  
         }          }
     }  
   
     if (count)          if (count) {
     {                  p = allocate(sizeof(reductions) + (count - 1) * sizeof(short));
         p = allocate(sizeof(reductions) + (count - 1) * sizeof(short));  
   
         p->number = this_state->number;                  p->number = this_state->number;
         p->nreds = count;                  p->nreds = count;
   
         rp1 = redset;                  rp1 = redset;
         rp2 = p->rules;                  rp2 = p->rules;
         rend = rp1 + count;                  rend = rp1 + count;
   
         while (rp1 < rend)                  while (rp1 < rend)
             *rp2++ = *rp1++;                          *rp2++ = *rp1++;
   
         if (last_reduction)                  if (last_reduction) {
         {                          last_reduction->next = p;
             last_reduction->next = p;                          last_reduction = p;
             last_reduction = p;                  } else {
                           first_reduction = p;
                           last_reduction = p;
                   }
         }          }
         else  
         {  
             first_reduction = p;  
             last_reduction = p;  
         }  
     }  
 }  }
   
 void  void
 set_derives(void)  set_derives(void)
 {  {
     int i, k;          int i, k;
     int lhs;          int lhs;
     short *rules;          short *rules;
   
     derives = NEW2(nsyms, short *);          derives = NEW2(nsyms, short *);
     rules = NEW2(nvars + nrules, short);          rules = NEW2(nvars + nrules, short);
   
     k = 0;          k = 0;
     for (lhs = start_symbol; lhs < nsyms; lhs++)          for (lhs = start_symbol; lhs < nsyms; lhs++) {
     {                  derives[lhs] = rules + k;
         derives[lhs] = rules + k;                  for (i = 0; i < nrules; i++) {
         for (i = 0; i < nrules; i++)                          if (rlhs[i] == lhs) {
         {                                  rules[k] = i;
             if (rlhs[i] == lhs)                                  k++;
             {                          }
                 rules[k] = i;                  }
                   rules[k] = -1;
                 k++;                  k++;
             }  
         }          }
         rules[k] = -1;  
         k++;  
     }  
   
 #ifdef  DEBUG  #ifdef  DEBUG
     print_derives();          print_derives();
 #endif  #endif
 }  }
   
 void  void
 free_derives(void)  free_derives(void)
 {  {
     free(derives[start_symbol]);          free(derives[start_symbol]);
     free(derives);          free(derives);
 }  }
   
 #ifdef  DEBUG  #ifdef  DEBUG
 void  void
 print_derives(void)  print_derives(void)
 {  {
     int i;          int i;
     short *sp;          short *sp;
   
     printf("\nDERIVES\n\n");          printf("\nDERIVES\n\n");
   
     for (i = start_symbol; i < nsyms; i++)          for (i = start_symbol; i < nsyms; i++) {
     {                  printf("%s derives ", symbol_name[i]);
         printf("%s derives ", symbol_name[i]);                  for (sp = derives[i]; *sp >= 0; sp++) {
         for (sp = derives[i]; *sp >= 0; sp++)                          printf("  %d", *sp);
         {                  }
             printf("  %d", *sp);                  putchar('\n');
         }          }
         putchar('\n');  
     }  
   
     putchar('\n');          putchar('\n');
 }  }
 #endif  #endif
   
 void  void
 set_nullable(void)  set_nullable(void)
 {  {
     int i, j;          int i, j;
     int empty;          int empty;
     int done;          int done;
   
     nullable = calloc(1, nsyms);          nullable = calloc(1, nsyms);
     if (nullable == 0) no_space();          if (nullable == NULL)
                   no_space();
   
     done = 0;          done = 0;
     while (!done)          while (!done) {
     {                  done = 1;
         done = 1;                  for (i = 1; i < nitems; i++) {
         for (i = 1; i < nitems; i++)                          empty = 1;
         {                          while ((j = ritem[i]) >= 0) {
             empty = 1;                                  if (!nullable[j])
             while ((j = ritem[i]) >= 0)                                          empty = 0;
             {                                  ++i;
                 if (!nullable[j])                          }
                     empty = 0;                          if (empty) {
                 ++i;                                  j = rlhs[-j];
             }                                  if (!nullable[j]) {
             if (empty)                                          nullable[j] = 1;
             {                                          done = 0;
                 j = rlhs[-j];                                  }
                 if (!nullable[j])                          }
                 {  
                     nullable[j] = 1;  
                     done = 0;  
                 }                  }
             }  
         }          }
     }  
   
 #ifdef DEBUG  #ifdef DEBUG
     for (i = 0; i < nsyms; i++)          for (i = 0; i < nsyms; i++) {
     {                  if (nullable[i])
         if (nullable[i])                          printf("%s is nullable\n", symbol_name[i]);
             printf("%s is nullable\n", symbol_name[i]);                  else
         else                          printf("%s is not nullable\n", symbol_name[i]);
             printf("%s is not nullable\n", symbol_name[i]);          }
     }  
 #endif  #endif
 }  }
   
 void  void
 free_nullable(void)  free_nullable(void)
 {  {
     free(nullable);          free(nullable);
 }  }
   
 void  void
 lr0(void)  lr0(void)
 {  {
     set_derives();          set_derives();
     set_nullable();          set_nullable();
     generate_states();          generate_states();
 }  }

Legend:
Removed from v.1.16  
changed lines
  Added in v.1.17