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

📄 lemon.c

📁 SQLite 2.8.6 源代码,用来在Linux/Unix/Windows上编译安装.它是一个小型的数据库,但是非常好用,速度也快,一般的数据库查询之类的操作据统计比MySQL,PostgreSQL
💻 C
📖 第 1 页 / 共 5 页
字号:
      apy->type==SH_RESOLVED ||      apy->type==RD_RESOLVED ||      apy->type==CONFLICT    );    /* The REDUCE/SHIFT case cannot happen because SHIFTs come before    ** REDUCEs on the list.  If we reach this point it must be because    ** the parser conflict had already been resolved. */  }  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(){  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(old)struct config *old;{  old->next = freelist;  freelist = old;}/* Initialized the configuration list builder */void Configlist_init(){  current = 0;  currentend = &current;  basis = 0;  basisend = &basis;  Configtable_init();  return;}/* Initialized the configuration list builder */void Configlist_reset(){  current = 0;  currentend = &current;  basis = 0;  basisend = &basis;  Configtable_clear(0);  return;}/* Add another configuration to the configuration list */struct config *Configlist_add(rp,dot)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(rp,dot)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(lemp)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==B_FALSE ) break;	  }	}        if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);      }    }  }  return;}/* Sort the configuration list */void Configlist_sort(){  current = (struct config *)msort(current,&(current->next),Configcmp);  currentend = 0;  return;}/* Sort the basis configuration list */void Configlist_sortbasis(){  basis = (struct config *)msort(current,&(current->bp),Configcmp);  basisend = 0;  return;}/* Return a pointer to the head of the configuration list and** reset the list */struct config *Configlist_return(){  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(){  struct config *old;  old = basis;  basis = 0;  basisend = 0;  return old;}/* Free all elements of the given configuration list */void Configlist_eat(cfp)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(msg,min,max)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(const char *filename, int lineno, const 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(){  fprintf(stderr,"Out of memory.  Aborting...\n");  exit(1);}/* The main program.  Parse the command line and do it... */int main(argc,argv)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 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_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_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");     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 = OptArg(0);  lem.basisflag = basisflag;  lem.has_fallback = 0;  lem.nconflict = 0;  lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0;  lem.vartype = 0;  lem.stacksize = 0;  lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest =     lem.tokenprefix = lem.outname = lem.extracode = 0;  lem.vardest = 0;  lem.tablesize = 0;  Symbol_new("$");  lem.errsym = Symbol_new("error");  /* Parse the input file */  Parse(&lem);  if( lem.errorcnt ) exit(lem.errorcnt);  if( lem.rule==0 ){    fprintf(stderr,"Empty grammar.\n");    exit(1);  }  /* Count and index the symbols of the grammar */  lem.nsymbol = Symbol_count();  Symbol_new("{default}");  lem.symbols = Symbol_arrayof();  qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*),        (int(*)())Symbolcmpp);  for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;  for(i=1; isupper(lem.symbols[i]->name[0]); i++);  lem.nterminal = i;  /* Generate a reprint of the grammar, if requested on the command line */  if( rpflag ){    Reprint(&lem);  }else{    /* Initialize the size for all follow and first sets */    SetSize(lem.nterminal);    /* Find the precedence for every production rule (that has one) */    FindRulePrecedences(&lem);    /* Compute the lambda-nonterminals and the first-sets for every    ** nonterminal */    FindFirstSets(&lem);    /* Compute all LR(0) states.  Also record follow-set propagation    ** links so that the follow-set can be computed later */    lem.nstate = 0;    FindStates(&lem);    lem.sorted = State_arrayof();    /* Tie up loose ends on the propagation links */    FindLinks(&lem);    /* Compute the follow set of every reducible configuration */    FindFollowSets(&lem);    /* Compute the action tables */    FindActions(&lem);    /* Compress the action tables */    if( compress==0 ) CompressTables(&lem);    /* Generate a report of the parser generated.  (the "y.output" file) */    if( !quiet ) ReportOutput(&lem);    /* Generate the source code for the parser */    ReportTable(&lem, mhflag);    /* Produce a header file for use by the scanner.  (This step is    ** omitted if the "-m" option is used because makeheaders will    ** generate the file for us.) */    if( !mhflag ) ReportHeader(&lem);  }  if( statistics ){    printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n",      lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule);    printf("                   %d states, %d parser table entries, %d conflicts\n",      lem.nstate, lem.tablesize, lem.nconflict);  }  if( lem.nconflict ){    fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);  }  exit(lem.errorcnt + lem.nconflict);}/******************** From the file "msort.c" *******************************/

⌨️ 快捷键说明

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