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

📄 lemon.c

📁 ethereal公司开发的aodv路由协议代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    spy = apy->x.rp->precsym;    if( spy==0 || spx->prec<0 || spy->prec<0 ){      /* Not enough precedence information. */      apy->type = CONFLICT;      errcnt++;    }else if( spx->prec>spy->prec ){    /* Lower precedence wins */      apy->type = RD_RESOLVED;    }else if( spx->prec<spy->prec ){      apx->type = SH_RESOLVED;    }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */      apy->type = RD_RESOLVED;                             /* associativity */    }else if( spx->prec==spy->prec && spx->assoc==LEFT ){  /* to break tie */      apx->type = SH_RESOLVED;    }else{      assert( spx->prec==spy->prec && spx->assoc==NONE );      apy->type = CONFLICT;      errcnt++;    }  }else if( apx->type==REDUCE && apy->type==REDUCE ){    spx = apx->x.rp->precsym;    spy = apy->x.rp->precsym;    if( spx==0 || spy==0 || spx->prec<0 ||    spy->prec<0 || spx->prec==spy->prec ){      apy->type = CONFLICT;      errcnt++;    }else if( spx->prec>spy->prec ){      apy->type = RD_RESOLVED;    }else if( spx->prec<spy->prec ){      apx->type = RD_RESOLVED;    }  }else{    /* Can't happen.  Shifts have to come before Reduces on the    ** list because the reduces were added last.  Hence, if apx->type==REDUCE    ** then it is impossible for apy->type==SHIFT */  }  return errcnt;}/********************* From the file "configlist.c" *************************//*** Routines to processing a configuration list and building a state** in the LEMON parser generator.*/static struct config *freelist = 0;      /* List of free configurations */static struct config *current = 0;       /* Top of list of configurations */static struct config **currentend = 0;   /* Last on list of configs */static struct config *basis = 0;         /* Top of list of basis configs */static struct config **basisend = 0;     /* End of list of basis configs *//* Return a pointer to a new configuration */PRIVATE struct config *newconfig(void){  struct config *new;  if( freelist==0 ){    int i;    int amt = 3;    freelist = (struct config *)malloc( sizeof(struct config)*amt );    if( freelist==0 ){      fprintf(stderr,"Unable to allocate memory for a new configuration.");      exit(1);    }    for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];    freelist[amt-1].next = 0;  }  new = freelist;  freelist = freelist->next;  return new;}/* The configuration "old" is no longer used */PRIVATE void deleteconfig(struct config *old){  old->next = freelist;  freelist = old;}/* Initialized the configuration list builder */void Configlist_init(void){  current = 0;  currentend = &current;  basis = 0;  basisend = &basis;  Configtable_init();  return;}/* Initialized the configuration list builder */void Configlist_reset(void){  current = 0;  currentend = &current;  basis = 0;  basisend = &basis;  Configtable_clear(0);  return;}/* Add another configuration to the configuration list */struct config *Configlist_add(    struct rule *rp,    /* The rule */    int dot)            /* Index into the RHS of the rule where the dot goes */{  struct config *cfp, model;  assert( currentend!=0 );  model.rp = rp;  model.dot = dot;  cfp = Configtable_find(&model);  if( cfp==0 ){    cfp = newconfig();    cfp->rp = rp;    cfp->dot = dot;    cfp->fws = SetNew();    cfp->stp = 0;    cfp->fplp = cfp->bplp = 0;    cfp->next = 0;    cfp->bp = 0;    *currentend = cfp;    currentend = &cfp->next;    Configtable_insert(cfp);  }  return cfp;}/* Add a basis configuration to the configuration list */struct config *Configlist_addbasis(struct rule *rp, int dot){  struct config *cfp, model;  assert( basisend!=0 );  assert( currentend!=0 );  model.rp = rp;  model.dot = dot;  cfp = Configtable_find(&model);  if( cfp==0 ){    cfp = newconfig();    cfp->rp = rp;    cfp->dot = dot;    cfp->fws = SetNew();    cfp->stp = 0;    cfp->fplp = cfp->bplp = 0;    cfp->next = 0;    cfp->bp = 0;    *currentend = cfp;    currentend = &cfp->next;    *basisend = cfp;    basisend = &cfp->bp;    Configtable_insert(cfp);  }  return cfp;}/* Compute the closure of the configuration list */void Configlist_closure(struct lemon *lemp){  struct config *cfp, *newcfp;  struct rule *rp, *newrp;  struct symbol *sp, *xsp;  int i, dot;  assert( currentend!=0 );  for(cfp=current; cfp; cfp=cfp->next){    rp = cfp->rp;    dot = cfp->dot;    if( dot>=rp->nrhs ) continue;    sp = rp->rhs[dot];    if( sp->type==NONTERMINAL ){      if( sp->rule==0 && sp!=lemp->errsym ){        ErrorMsg(lemp->filename,rp->line,"Nonterminal \"%s\" has no rules.",          sp->name);        lemp->errorcnt++;      }      for(newrp=sp->rule; newrp; newrp=newrp->nextlhs){        newcfp = Configlist_add(newrp,0);        for(i=dot+1; i<rp->nrhs; i++){          xsp = rp->rhs[i];          if( xsp->type==TERMINAL ){            SetAdd(newcfp->fws,xsp->index);            break;	  }else{            SetUnion(newcfp->fws,xsp->firstset);            if( xsp->lambda==BOOL_FALSE ) break;	  }	}        if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);      }    }  }  return;}/* Sort the configuration list */void Configlist_sort(void){  current = (struct config *)msort((char *)current,(char **)&(current->next),Configcmp);  currentend = 0;  return;}/* Sort the basis configuration list */void Configlist_sortbasis(void){  basis = (struct config *)msort((char *)current,(char **)&(current->bp),Configcmp);  basisend = 0;  return;}/* Return a pointer to the head of the configuration list and** reset the list */struct config *Configlist_return(void){  struct config *old;  old = current;  current = 0;  currentend = 0;  return old;}/* Return a pointer to the head of the configuration list and** reset the list */struct config *Configlist_basis(void){  struct config *old;  old = basis;  basis = 0;  basisend = 0;  return old;}/* Free all elements of the given configuration list */void Configlist_eat(struct config *cfp){  struct config *nextcfp;  for(; cfp; cfp=nextcfp){    nextcfp = cfp->next;    assert( cfp->fplp==0 );    assert( cfp->bplp==0 );    if( cfp->fws ) SetFree(cfp->fws);    deleteconfig(cfp);  }  return;}/***************** From the file "error.c" *********************************//*** Code for printing error message.*//* Find a good place to break "msg" so that its length is at least "min"** but no more than "max".  Make the point as close to max as possible.*/static int findbreak(char *msg, int min, int max){  int i,spot;  char c;  for(i=spot=min; i<=max; i++){    c = msg[i];    if( c=='\t' ) msg[i] = ' ';    if( c=='\n' ){ msg[i] = ' '; spot = i; break; }    if( c==0 ){ spot = i; break; }    if( c=='-' && i<max-1 ) spot = i+1;    if( c==' ' ) spot = i;  }  return spot;}/*** The error message is split across multiple lines if necessary.  The** splits occur at a space, if there is a space available near the end** of the line.*/#define ERRMSGSIZE  10000 /* Hope this is big enough.  No way to error check */#define LINEWIDTH      79 /* Max width of any output line */#define PREFIXLIMIT    30 /* Max width of the prefix on each line */void ErrorMsg(char *filename, int lineno, char *format, ...){  char errmsg[ERRMSGSIZE];  char prefix[PREFIXLIMIT+10];  int errmsgsize;  int prefixsize;  int availablewidth;  va_list ap;  int end, restart, base;  va_start(ap, format);  /* Prepare a prefix to be prepended to every output line */  if( lineno>0 ){    sprintf(prefix,"%.*s:%d: ",PREFIXLIMIT-10,filename,lineno);  }else{    sprintf(prefix,"%.*s: ",PREFIXLIMIT-10,filename);  }  prefixsize = strlen(prefix);  availablewidth = LINEWIDTH - prefixsize;  /* Generate the error message */  vsprintf(errmsg,format,ap);  va_end(ap);  errmsgsize = strlen(errmsg);  /* Remove trailing '\n's from the error message. */  while( errmsgsize>0 && errmsg[errmsgsize-1]=='\n' ){     errmsg[--errmsgsize] = 0;  }  /* Print the error message */  base = 0;  while( errmsg[base]!=0 ){    end = restart = findbreak(&errmsg[base],0,availablewidth);    restart += base;    while( errmsg[restart]==' ' ) restart++;    fprintf(stdout,"%s%.*s\n",prefix,end,&errmsg[base]);    base = restart;  }}/**************** From the file "main.c" ************************************//*** Main program file for the LEMON parser generator.*//* Report an out-of-memory condition and abort.  This function** is used mostly by the "MemoryCheck" macro in struct.h*/void memory_error(void){  fprintf(stderr,"Out of memory.  Aborting...\n");  exit(1);}/* Locates the basename in a string possibly containing paths, * including forward-slash and backward-slash delimiters on Windows, * and allocates a new string containing just the basename. * Returns the pointer to that string. */PRIVATE char*make_basename(char* fullname){	char	*cp;	char	*new_string;	/* Find the last forward slash */	cp = strrchr(fullname, '/');#ifdef WIN32	/* On Windows, if no forward slash was found, look ofr	 * backslash also */	if (!cp)		cp = strrchr(fullname, '\\');#endif	if (!cp) {		new_string = malloc( strlen(fullname) );		strcpy(new_string, fullname);	}	else {		/* skip the slash */		cp++;		new_string = malloc( strlen(cp) );		strcpy(new_string, cp);	}	return new_string;}/* The main program.  Parse the command line and do it... */int main(int argc, char **argv){  static int version = 0;  static int rpflag = 0;  static int basisflag = 0;  static int compress = 0;  static int quiet = 0;  static int statistics = 0;  static int mhflag = 0;  static char *outdirname = NULL;  static char *templatename = NULL;  static struct s_options options[] = {    {OPT_FLAG, "b", (char*)&basisflag, "Print only the basis in report."},    {OPT_FLAG, "c", (char*)&compress, "Don't compress the action table."},    {OPT_STR,  "d", (char*)&outdirname, "Output directory name."},    {OPT_FLAG, "g", (char*)&rpflag, "Print grammar without actions."},    {OPT_FLAG, "m", (char*)&mhflag, "Output a makeheaders compatible file"},    {OPT_FLAG, "q", (char*)&quiet, "(Quiet) Don't print the report file."},    {OPT_FLAG, "s", (char*)&statistics, "Print parser stats to standard output."},    {OPT_STR,  "t", (char*)&templatename, "Template file to use."},    {OPT_FLAG, "x", (char*)&version, "Print the version number."},    {OPT_FLAG,0,0,0}  };  int i;  struct lemon lem;  optinit(argv,options,stderr);  if( version ){     printf("Lemon version 1.0\n"       "Copyright 1991-1997 by D. Richard Hipp\n"       "Freely distributable under the GNU Public License.\n"     );     exit(0);   }  if( optnargs()!=1 ){    fprintf(stderr,"Exactly one filename argument is required.\n");    exit(1);  }  lem.errorcnt = 0;  /* Initialize the machine */  Strsafe_init();  Symbol_init();  State_init();  lem.argv0 = argv[0];  lem.filename = get_optarg(0);  lem.basisflag = basisflag;  lem.nconflict = 0;  lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0;  lem.stacksize = 0;  lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest =     lem.tokenprefix = lem.outname = lem.extracode = 0;  lem.tablesize = 0;  Symbol_new("$");  lem.errsym = Symbol_new("error");  lem.outdirname = outdirname;  lem.templatename = templatename;  lem.basename = make_basename(lem.filename);  /* Parse the input file */  Parse(&lem);

⌨️ 快捷键说明

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