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

📄 output.c

📁 生成C++词法/语法分析的GNU语法分析器
💻 C
📖 第 1 页 / 共 3 页
字号:
	  else if (*p < 040 || *p >= 0177)	    {	      fprintf(ftable, "\\%03o", *p);	      j += 4;	    }	  else	    {	      putc(*p, ftable);	      j++;	    }	}      putc ('\"', ftable);      j++;    }  fprintf(ftable, "\n};\n#endif\n\nstatic const short yyr1[] = {     0");  j = 10;  for (i = 1; i <= nrules; i++)    {      putc(',', ftable);      if (j >= 10)	{	  putc('\n', ftable);	  j = 1;	}      else	{	  j++;	}      fprintf(ftable, "%6d", rlhs[i]);    }  FREE(rlhs + 1);  fprintf(ftable, "\n};\n\nstatic const short yyr2[] = {     0");  j = 10;  for (i = 1; i < nrules; i++)    {      putc(',', ftable);      if (j >= 10)	{	  putc('\n', ftable);	  j = 1;	}      else	{	  j++;	}      fprintf(ftable, "%6d", rrhs[i + 1] - rrhs[i] - 1);    }  putc(',', ftable);  if (j >= 10)    putc('\n', ftable);  fprintf(ftable, "%6d\n};\n", nitems - rrhs[nrules] - 1);  FREE(rrhs + 1);}voidoutput_defines(){  fprintf(ftable, "\n\n#define\tYYFINAL\t\t%d\n", final_state);  fprintf(ftable, "#define\tYYFLAG\t\t%d\n", MINSHORT);  fprintf(ftable, "#define\tYYNTBASE\t%d\n", ntokens);}/* compute and output yydefact, yydefgoto, yypact, yypgoto, yytable and yycheck.  */voidoutput_actions(){  nvectors = nstates + nvars;  froms = NEW2(nvectors, short *);  tos = NEW2(nvectors, short *);  tally = NEW2(nvectors, short);  width = NEW2(nvectors, short);  token_actions();  free_shifts();  free_reductions();  FREE(lookaheads);  FREE(LA);  FREE(LAruleno);  FREE(accessing_symbol);  goto_actions();  FREE(goto_map + ntokens);  FREE(from_state);  FREE(to_state);  sort_actions();  pack_table();  output_base();  output_table();  output_check();}/* figure out the actions for the specified state, indexed by lookahead token type.   The yydefact table is output now.  The detailed info   is saved for putting into yytable later.  */voidtoken_actions(){  register int i;  register int j;  register int k;  actrow = NEW2(ntokens, short);  k = action_row(0);  fprintf(ftable, "\nstatic const short yydefact[] = {%6d", k);  save_row(0);  j = 10;  for (i = 1; i < nstates; i++)    {      putc(',', ftable);      if (j >= 10)	{	  putc('\n', ftable);	  j = 1;	}      else	{	  j++;	}      k = action_row(i);      fprintf(ftable, "%6d", k);      save_row(i);    }  fprintf(ftable, "\n};\n");  FREE(actrow);}/* Decide what to do for each type of token if seen as the lookahead token in specified state.   The value returned is used as the default action (yydefact) for the state.   In addition, actrow is filled with what to do for each kind of token,   index by symbol number, with zero meaning do the default action.   The value MINSHORT, a very negative number, means this situation   is an error.  The parser recognizes this value specially.   This is where conflicts are resolved.  The loop over lookahead rules   considered lower-numbered rules last, and the last rule considered that likes   a token gets to handle it.  */intaction_row(state)int state;{  register int i;  register int j;  register int k;  register int m;  register int n;  register int count;  register int default_rule;  register int nreds;  register int max;  register int rule;  register int shift_state;  register int symbol;  register unsigned mask;  register unsigned *wordp;  register reductions *redp;  register shifts *shiftp;  register errs *errp;  int nodefault = 0;  /* set nonzero to inhibit having any default reduction */  for (i = 0; i < ntokens; i++)    actrow[i] = 0;  default_rule = 0;  nreds = 0;  redp = reduction_table[state];  if (redp)    {      nreds = redp->nreds;      if (nreds >= 1)	{	  /* loop over all the rules available here which require lookahead */	  m = lookaheads[state];	  n = lookaheads[state + 1];	  for (i = n - 1; i >= m; i--)	    {	      rule = - LAruleno[i];	      wordp = LA + i * tokensetsize;	      mask = 1;	      /* and find each token which the rule finds acceptable to come next */	      for (j = 0; j < ntokens; j++)		{		  /* and record this rule as the rule to use if that token follows.  */		  if (mask & *wordp)		    actrow[j] = rule;		  mask <<= 1;		  if (mask == 0)		    {		      mask = 1;		      wordp++;		    }		}	    }	}    }  shiftp = shift_table[state];  /* now see which tokens are allowed for shifts in this state.     For them, record the shift as the thing to do.  So shift is preferred to reduce.  */  if (shiftp)    {      k = shiftp->nshifts;      for (i = 0; i < k; i++)	{	  shift_state = shiftp->shifts[i];	  if (! shift_state) continue;	  symbol = accessing_symbol[shift_state];	  if (ISVAR(symbol))	    break;	  actrow[symbol] = shift_state;	  /* do not use any default reduction if there is a shift for error */	  if (symbol == error_token_number) nodefault = 1;	}    }  errp = err_table[state];  /* See which tokens are an explicit error in this state     (due to %nonassoc).  For them, record MINSHORT as the action.  */  if (errp)    {      k = errp->nerrs;      for (i = 0; i < k; i++)	{	  symbol = errp->errs[i];	  actrow[symbol] = MINSHORT;	}    }  /* now find the most common reduction and make it the default action for this state.  */  if (nreds >= 1 && ! nodefault)    {      if (consistent[state])	default_rule = redp->rules[0];      else	{	  max = 0;	  for (i = m; i < n; i++)	    {	      count = 0;	      rule = - LAruleno[i];    	      for (j = 0; j < ntokens; j++)		{		  if (actrow[j] == rule)		    count++;		}    	      if (count > max)		{		  max = count;		  default_rule = rule;		}	    }    	  /* actions which match the default are replaced with zero,	     which means "use the default" */    	  if (max > 0)	    {	      for (j = 0; j < ntokens; j++)		{		  if (actrow[j] == default_rule)		    actrow[j] = 0;		}    	      default_rule = - default_rule;	    }	}    }  /* If have no default rule, the default is an error.     So replace any action which says "error" with "use default".  */  if (default_rule == 0)    for (j = 0; j < ntokens; j++)      {	if (actrow[j] == MINSHORT)	  actrow[j] = 0;      }  return (default_rule);}voidsave_row(state)int state;{  register int i;  register int count;  register short *sp;  register short *sp1;  register short *sp2;  count = 0;  for (i = 0; i < ntokens; i++)    {      if (actrow[i] != 0)	count++;    }  if (count == 0)    return;  froms[state] = sp1 = sp = NEW2(count, short);  tos[state] = sp2 = NEW2(count, short);  for (i = 0; i < ntokens; i++)    {      if (actrow[i] != 0)	{	  *sp1++ = i;	  *sp2++ = actrow[i];	}    }  tally[state] = count;  width[state] = sp1[-1] - sp[0] + 1;}/* figure out what to do after reducing with each rule,   depending on the saved state from before the beginning   of parsing the data that matched this rule.   The yydefgoto table is output now.  The detailed info   is saved for putting into yytable later.  */voidgoto_actions(){  register int i;  register int j;  register int k;  state_count = NEW2(nstates, short);  k = default_goto(ntokens);  fprintf(ftable, "\nstatic const short yydefgoto[] = {%6d", k);  save_column(ntokens, k);  j = 10;  for (i = ntokens + 1; i < nsyms; i++)    {      putc(',', ftable);      if (j >= 10)	{	  putc('\n', ftable);	  j = 1;	}      else	{	  j++;	}      k = default_goto(i);      fprintf(ftable, "%6d", k);      save_column(i, k);    }  fprintf(ftable, "\n};\n");  FREE(state_count);}intdefault_goto(symbol)int symbol;{  register int i;  register int m;  register int n;  register int default_state;  register int max;  m = goto_map[symbol];  n = goto_map[symbol + 1];  if (m == n)    return (-1);  for (i = 0; i < nstates; i++)    state_count[i] = 0;  for (i = m; i < n; i++)    state_count[to_state[i]]++;  max = 0;  default_state = -1;  for (i = 0; i < nstates; i++)    {      if (state_count[i] > max)	{	  max = state_count[i];	  default_state = i;	}    }  return (default_state);}voidsave_column(symbol, default_state)int symbol;int default_state;{  register int i;  register int m;  register int n;  register short *sp;  register short *sp1;  register short *sp2;  register int count;  register int symno;  m = goto_map[symbol];  n = goto_map[symbol + 1];  count = 0;  for (i = m; i < n; i++)    {      if (to_state[i] != default_state)	count++;    }  if (count == 0)    return;  symno = symbol - ntokens + nstates;  froms[symno] = sp1 = sp = NEW2(count, short);  tos[symno] = sp2 = NEW2(count, short);  for (i = m; i < n; i++)    {      if (to_state[i] != default_state)	{	  *sp1++ = from_state[i];	  *sp2++ = to_state[i];	}    }  tally[symno] = count;  width[symno] = sp1[-1] - sp[0] + 1;}/* the next few functions decide how to pack    the actions and gotos information into yytable. */voidsort_actions(){  register int i;  register int j;  register int k;  register int t;  register int w;  order = NEW2(nvectors, short);  nentries = 0;  for (i = 0; i < nvectors; i++)    {      if (tally[i] > 0)	{	  t = tally[i];	  w = width[i];	  j = nentries - 1;	  while (j >= 0 && (width[order[j]] < w))	    j--;	  while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))	    j--;	  for (k = nentries - 1; k > j; k--)	    order[k + 1] = order[k];	  order[j + 1] = i;	  nentries++;	}    }}voidpack_table(){  register int i;  register int place;  register int state;  base = NEW2(nvectors, short);  pos = NEW2(nentries, short);  table = NEW2(MAXTABLE, short);  check = NEW2(MAXTABLE, short);  lowzero = 0;  high = 0;

⌨️ 快捷键说明

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