⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lr0.c

📁 伯克利的语法分析器的创建工具
💻 C
字号:
#include "defs.h"extern short *itemset;extern short *itemsetend;extern unsigned *ruleset;int nstates;core *first_state;shifts *first_shift;reductions *first_reduction;int get_state();core *new_state();static core *this_state;static core *last_state;static shifts *last_shift;static reductions *last_reduction;static int nshifts;static short *shift_symbol;static short *redset;static short *shiftset;static short **kernel_base;static short **kernel_end;static short *kernel_items;static core **state_table;allocate_itemsets(){  register short *itemp;  register short *item_end;  register int symbol;  register int i;  register int count;  register int max;  register short *symbol_count;  count = 0;  symbol_count = NEW2(nsyms, short);  item_end = ritem + nitems;  for (itemp = ritem; itemp < item_end; itemp++)    {      symbol = *itemp;      if (symbol >= 0)	{	  count++;	  symbol_count[symbol]++;	}    }  kernel_base = NEW2(nsyms, short *);  kernel_items = NEW2(count, short);  count = 0;  max = 0;  for (i = 0; i < nsyms; i++)    {      kernel_base[i] = kernel_items + count;      count += symbol_count[i];      if (max < symbol_count[i])	max = symbol_count[i];    }  shift_symbol = symbol_count;  kernel_end = NEW2(nsyms, short *);}allocate_storage(){  allocate_itemsets();  shiftset = NEW2(nsyms, short);  redset = NEW2(nrules + 1, short);  state_table = NEW2(nitems, core *);}append_states(){  register int i;  register int j;  register int symbol;#ifdef	TRACE  fprintf(stderr, "Entering append_states\n");#endif  for (i = 1; i < nshifts; i++)    {      symbol = shift_symbol[i];      j = i;      while (j > 0 && shift_symbol[j - 1] > symbol)	{	  shift_symbol[j] = shift_symbol[j - 1];	  j--;	}      shift_symbol[j] = symbol;    }  for (i = 0; i < nshifts; i++)    {      symbol = shift_symbol[i];      shiftset[i] = get_state(symbol);    }}free_storage(){  FREE(shift_symbol);  FREE(redset);  FREE(shiftset);  FREE(kernel_base);  FREE(kernel_end);  FREE(kernel_items);  FREE(state_table);}generate_states(){  allocate_storage();  itemset = NEW2(nitems, short);  ruleset = NEW2(WORDSIZE(nrules), unsigned);  set_first_derives();  initialize_states();  while (this_state)    {      closure(this_state->items, this_state->nitems);      save_reductions();      new_itemsets();      append_states();      if (nshifts > 0)        save_shifts();      this_state = this_state->next;    }  finalize_closure();  free_storage();}intget_state(symbol)int symbol;{  register int key;  register short *isp1;  register short *isp2;  register short *iend;  register core *sp;  register int found;  int n;#ifdef	TRACE  fprintf(stderr, "Entering get_state, symbol = %d\n", symbol);#endif  isp1 = kernel_base[symbol];  iend = kernel_end[symbol];  n = iend - isp1;  key = *isp1;  assert(0 <= key && key < nitems);  sp = state_table[key];  if (sp)    {      found = 0;      while (!found)	{	  if (sp->nitems == n)	    {	      found = 1;	      isp1 = kernel_base[symbol];	      isp2 = sp->items;	      while (found && isp1 < iend)		{		  if (*isp1++ != *isp2++)		    found = 0;		}	    }	  if (!found)	    {	      if (sp->link)		{		  sp = sp->link;		}	      else		{		  sp = sp->link = new_state(symbol);		  found = 1;		}	    }	}    }  else    {      state_table[key] = sp = new_state(symbol);    }  return (sp->number);}initialize_states(){    register int i;    register short *start_derives;    register core *p;    start_derives = derives[start_symbol];    for (i = 0; start_derives[i] >= 0; ++i)	continue;    p = (core *) MALLOC(sizeof(core) + i*sizeof(short));    if (p == 0) no_space();    p->next = 0;    p->link = 0;    p->number = 0;    p->accessing_symbol = 0;    p->nitems = i;    for (i = 0;  start_derives[i] >= 0; ++i)	p->items[i] = rrhs[start_derives[i]];    first_state = last_state = this_state = p;    nstates = 1;}new_itemsets(){  register int i;  register int shiftcount;  register short *isp;  register short *ksp;  register int symbol;  for (i = 0; i < nsyms; i++)    kernel_end[i] = 0;  shiftcount = 0;  isp = itemset;  while (isp < itemsetend)    {      i = *isp++;      symbol = ritem[i];      if (symbol > 0)	{          ksp = kernel_end[symbol];          if (!ksp)	    {	      shift_symbol[shiftcount++] = symbol;	      ksp = kernel_base[symbol];	    }          *ksp++ = i + 1;          kernel_end[symbol] = ksp;	}    }  nshifts = shiftcount;}core *new_state(symbol)int symbol;{  register int n;  register core *p;  register short *isp1;  register short *isp2;  register short *iend;#ifdef	TRACE  fprintf(stderr, "Entering new_state, symbol = %d\n", symbol);#endif  if (nstates >= MAXSHORT)    fatal("too many states");  isp1 = kernel_base[symbol];  iend = kernel_end[symbol];  n = iend - isp1;  p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));  p->accessing_symbol = symbol;  p->number = nstates;  p->nitems = n;  isp2 = p->items;  while (isp1 < iend)    *isp2++ = *isp1++;  last_state->next = p;  last_state = p;  nstates++;  return (p);}/* show_cores is used for debugging */show_cores(){    core *p;    int i, j, k, n;    int itemno;    k = 0;    for (p = first_state; p; ++k, p = p->next)    {	if (k) printf("\n");	printf("state %d, number = %d, accessing symbol = %s\n",		k, p->number, symbol_name[p->accessing_symbol]);	n = p->nitems;	for (i = 0; i < n; ++i)	{	    itemno = p->items[i];	    printf("%4d  ", itemno);	    j = itemno;	    while (ritem[j] >= 0) ++j;	    printf("%s :", symbol_name[rlhs[-ritem[j]]]);	    j = rrhs[-ritem[j]];	    while (j < itemno)		printf(" %s", symbol_name[ritem[j++]]);	    printf(" .");	    while (ritem[j] >= 0)		printf(" %s", symbol_name[ritem[j++]]);	    printf("\n");	    fflush(stdout);	}    }}/* show_ritems is used for debugging */show_ritems(){    int i;    for (i = 0; i < nitems; ++i)	printf("ritem[%d] = %d\n", i, ritem[i]);}/* show_rrhs is used for debugging */show_rrhs(){    int i;    for (i = 0; i < nrules; ++i)	printf("rrhs[%d] = %d\n", i, rrhs[i]);}/* show_shifts is used for debugging */show_shifts(){    shifts *p;    int i, j, k;    k = 0;    for (p = first_shift; p; ++k, p = p->next)    {	if (k) printf("\n");	printf("shift %d, number = %d, nshifts = %d\n", k, p->number,		p->nshifts);	j = p->nshifts;	for (i = 0; i < j; ++i)	    printf("\t%d\n", p->shift[i]);    }}save_shifts(){  register shifts *p;  register short *sp1;  register short *sp2;  register short *send;  p = (shifts *) allocate((unsigned) (sizeof(shifts) +			(nshifts - 1) * sizeof(short)));  p->number = this_state->number;  p->nshifts = nshifts;  sp1 = shiftset;  sp2 = p->shift;  send = shiftset + nshifts;  while (sp1 < send)    *sp2++ = *sp1++;  if (last_shift)    {      last_shift->next = p;      last_shift = p;    }  else    {      first_shift = p;      last_shift = p;    }}save_reductions(){  register short *isp;  register short *rp1;  register short *rp2;  register int item;  register int count;  register reductions *p;  short *rend;  count = 0;  for (isp = itemset; isp < itemsetend; isp++)    {      item = ritem[*isp];      if (item < 0)	{	  redset[count++] = -item;	}    }  if (count)    {      p = (reductions *) allocate((unsigned) (sizeof(reductions) +					(count - 1) * sizeof(short)));      p->number = this_state->number;      p->nreds = count;      rp1 = redset;      rp2 = p->rules;      rend = rp1 + count;      while (rp1 < rend)	*rp2++ = *rp1++;      if (last_reduction)	{	  last_reduction->next = p;	  last_reduction = p;	}      else	{	  first_reduction = p;	  last_reduction = p;	}    }}set_derives(){  register int i, k;  register int lhs;  register short *rules;  derives = NEW2(nsyms, short *);  rules = NEW2(nvars + nrules, short);  k = 0;  for (lhs = start_symbol; lhs < nsyms; lhs++)    {      derives[lhs] = rules + k;      for (i = 0; i < nrules; i++)	{	  if (rlhs[i] == lhs)	    {	      rules[k] = i;	      k++;	    }	}      rules[k] = -1;      k++;    }#ifdef	DEBUG  print_derives();#endif}free_derives(){  FREE(derives[start_symbol]);  FREE(derives);}#ifdef	DEBUGprint_derives(){  register int i;  register short *sp;  printf("\nDERIVES\n\n");  for (i = start_symbol; i < nsyms; i++)    {      printf("%s derives ", symbol_name[i]);      for (sp = derives[i]; *sp >= 0; sp++)	{	  printf("  %d", *sp);	}      putchar('\n');    }  putchar('\n');}#endifset_nullable(){    register int i, j;    register int empty;    int done;    nullable = MALLOC(nsyms);    if (nullable == 0) no_space();    for (i = 0; i < nsyms; ++i)	nullable[i] = 0;    done = 0;    while (!done)    {	done = 1;	for (i = 1; i < nitems; i++)	{	    empty = 1;	    while ((j = ritem[i]) >= 0)	    {		if (!nullable[j])		    empty = 0;		++i;	    }	    if (empty)	    {		j = rlhs[-j];		if (!nullable[j])		{		    nullable[j] = 1;		    done = 0;		}	    }	}    }#ifdef DEBUG    for (i = 0; i < nsyms; i++)    {	if (nullable[i])	    printf("%s is nullable\n", symbol_name[i]);	else	    printf("%s is not nullable\n", symbol_name[i]);    }#endif}free_nullable(){  FREE(nullable);}lr0(){    set_derives();    set_nullable();    generate_states();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -