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

📄 conflicts.c

📁 Bison语法分析器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Find and resolve or report look-ahead conflicts for bison,   Copyright (C) 1984, 1989, 1992 Free Software Foundation, Inc.This file is part of Bison, the GNU Compiler Compiler.Bison is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.Bison is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with Bison; see the file COPYING.  If not, write tothe Free Software Foundation, Inc., 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#include <stdio.h>#include "system.h"#include "machine.h"#include "alloc.h"#include "files.h"#include "gram.h"#include "state.h"extern char **tags;extern int tokensetsize;extern char *consistent;extern short *accessing_symbol;extern shifts **shift_table;extern unsigned *LA;extern short *LAruleno;extern short *lookaheads;extern int verboseflag;extern int fixed_outfiles;void initialize_conflicts PARAMS((void));void set_conflicts PARAMS((int));void resolve_sr_conflict PARAMS((int, int));void flush_shift PARAMS((int, int));void log_resolution PARAMS((int, int, int, char *));void conflict_log PARAMS((void));void verbose_conflict_log PARAMS((void));void total_conflicts PARAMS((void));void count_sr_conflicts PARAMS((int));void count_rr_conflicts PARAMS((int));void print_reductions PARAMS((int));void finalize_conflicts PARAMS((void));char any_conflicts;char *conflicts;errs **err_table;int expected_conflicts;static unsigned *shiftset;static unsigned *lookaheadset;static int src_total;static int rrc_total;static int src_count;static int rrc_count;voidinitialize_conflicts (void){  register int i;/*  register errs *sp; JF unused */  conflicts = NEW2(nstates, char);  shiftset = NEW2(tokensetsize, unsigned);  lookaheadset = NEW2(tokensetsize, unsigned);  err_table = NEW2(nstates, errs *);  any_conflicts = 0;  for (i = 0; i < nstates; i++)    set_conflicts(i);}voidset_conflicts (int state){  register int i;  register int k;  register shifts *shiftp;  register unsigned *fp2;  register unsigned *fp3;  register unsigned *fp4;  register unsigned *fp1;  register int symbol;  if (consistent[state]) return;  for (i = 0; i < tokensetsize; i++)    lookaheadset[i] = 0;  shiftp = shift_table[state];  if (shiftp)    {      k = shiftp->nshifts;      for (i = 0; i < k; i++)	{	  symbol = accessing_symbol[shiftp->shifts[i]];	  if (ISVAR(symbol)) break;	  SETBIT(lookaheadset, symbol);	}    }  k = lookaheads[state + 1];  fp4 = lookaheadset + tokensetsize;  /* loop over all rules which require lookahead in this state */  /* first check for shift-reduce conflict, and try to resolve using precedence  */  for (i = lookaheads[state]; i < k; i++)    if (rprec[LAruleno[i]])      {	fp1 = LA + i * tokensetsize;	fp2 = fp1;	fp3 = lookaheadset;  	while (fp3 < fp4)	  {	    if (*fp2++ & *fp3++)	      {		resolve_sr_conflict(state, i);		break;	      }	  }      }  /* loop over all rules which require lookahead in this state */  /* Check for conflicts not resolved above.  */  for (i = lookaheads[state]; i < k; i++)    {      fp1 = LA + i * tokensetsize;      fp2 = fp1;      fp3 = lookaheadset;      while (fp3 < fp4)	{	  if (*fp2++ & *fp3++)	    {	      conflicts[state] = 1;	      any_conflicts = 1;	    }	}      fp2 = fp1;      fp3 = lookaheadset;      while (fp3 < fp4)	*fp3++ |= *fp2++;    }}/* Attempt to resolve shift-reduce conflict for one ruleby means of precedence declarations.It has already been checked that the rule has a precedence.A conflict is resolved by modifying the shift or reduce tablesso that there is no longer a conflict.  */voidresolve_sr_conflict (int state, int lookaheadnum){  register int i;  register int mask;  register unsigned *fp1;  register unsigned *fp2;  register int redprec;  errs *errp = (errs *) xmalloc (sizeof(errs) + ntokens * sizeof(short));  short *errtokens = errp->errs;  /* find the rule to reduce by to get precedence of reduction  */  redprec = rprec[LAruleno[lookaheadnum]];  mask = 1;  fp1 = LA + lookaheadnum * tokensetsize;  fp2 = lookaheadset;  for (i = 0; i < ntokens; i++)    {      if ((mask & *fp2 & *fp1) && sprec[i])	/* Shift-reduce conflict occurs for token number i	   and it has a precedence.	   The precedence of shifting is that of token i.  */	{	  if (sprec[i] < redprec)	    {	      if (verboseflag) log_resolution(state, lookaheadnum, i, _("reduce"));	      *fp2 &= ~mask;  /* flush the shift for this token */	      flush_shift(state, i);	    }	  else if (sprec[i] > redprec)	    {	      if (verboseflag) log_resolution(state, lookaheadnum, i, _("shift"));	      *fp1 &= ~mask;  /* flush the reduce for this token */	    }	  else	    {	      /* Matching precedence levels.		 For left association, keep only the reduction.		 For right association, keep only the shift.		 For nonassociation, keep neither.  */	      switch (sassoc[i])		{		case RIGHT_ASSOC:	          if (verboseflag) log_resolution(state, lookaheadnum, i, _("shift"));		  break;		case LEFT_ASSOC:	          if (verboseflag) log_resolution(state, lookaheadnum, i, _("reduce"));		  break;		case NON_ASSOC:	          if (verboseflag) log_resolution(state, lookaheadnum, i, _("an error"));		  break;		}	      if (sassoc[i] != RIGHT_ASSOC)		{		  *fp2 &= ~mask;  /* flush the shift for this token */		  flush_shift(state, i);		}	      if (sassoc[i] != LEFT_ASSOC)	        {		  *fp1 &= ~mask;  /* flush the reduce for this token */		}	      if (sassoc[i] == NON_ASSOC)		{		  /* Record an explicit error for this token.  */		  *errtokens++ = i;		}	    }	}      mask <<= 1;      if (mask == 0)	{	  mask = 1;	  fp2++;  fp1++;	}    }  errp->nerrs = errtokens - errp->errs;  if (errp->nerrs)    {      /* Some tokens have been explicitly made errors.  Allocate	 a permanent errs structure for this state, to record them.  */      i = (char *) errtokens - (char *) errp;      err_table[state] = (errs *) xmalloc ((unsigned int)i);      bcopy (errp, err_table[state], i);    }  else    err_table[state] = 0;  free(errp);}/* turn off the shift recorded for the specified token in the specified state.Used when we resolve a shift-reduce conflict in favor of the reduction.  */voidflush_shift (int state, int token){  register shifts *shiftp;  register int k, i;/*  register unsigned symbol; JF unused */  shiftp = shift_table[state];  if (shiftp)    {      k = shiftp->nshifts;      for (i = 0; i < k; i++)	{	  if (shiftp->shifts[i] && token == accessing_symbol[shiftp->shifts[i]])	    (shiftp->shifts[i]) = 0;	}    }}voidlog_resolution (int state, int LAno, int token, char *resolution){  fprintf(foutput,	  _("Conflict in state %d between rule %d and token %s resolved as %s.\n"),	  state, LAruleno[LAno], tags[token], resolution);}voidconflict_log (void){  register int i;  src_total = 0;  rrc_total = 0;  for (i = 0; i < nstates; i++)    {      if (conflicts[i])	{	  count_sr_conflicts(i);	  count_rr_conflicts(i);	  src_total += src_count;	  rrc_total += rrc_count;	}    }  total_conflicts();}  voidverbose_conflict_log (void){  register int i;  src_total = 0;  rrc_total = 0;  for (i = 0; i < nstates; i++)    {      if (conflicts[i])	{	  count_sr_conflicts(i);	  count_rr_conflicts(i);	  src_total += src_count;	  rrc_total += rrc_count;	  fprintf(foutput, _("State %d contains"), i);	  if (src_count == 1)	    fprintf(foutput, _(" 1 shift/reduce conflict"));	  else if (src_count > 1)	    fprintf(foutput, _(" %d shift/reduce conflicts"), src_count);	  if (src_count > 0 && rrc_count > 0)	    fprintf(foutput, _(" and"));	  if (rrc_count == 1)	    fprintf(foutput, _(" 1 reduce/reduce conflict"));	  else if (rrc_count > 1)	    fprintf(foutput, _(" %d reduce/reduce conflicts"), rrc_count);	  putc('.', foutput);	  putc('\n', foutput);	}    }  total_conflicts();}voidtotal_conflicts (void){  if (src_total == expected_conflicts && rrc_total == 0)    return;  if (fixed_outfiles)    {

⌨️ 快捷键说明

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