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

📄 lemon.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
    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);}static int nDefine = 0;      /* Number of -D options on the command line */static char **azDefine = 0;  /* Name of the -D macros *//* This routine is called with the argument to each -D command-line option.** Add the macro defined to the azDefine array.*/static void handle_D_option(char *z){  char **paz;  nDefine++;  azDefine = realloc(azDefine, sizeof(azDefine[0])*nDefine);  if( azDefine==0 ){    fprintf(stderr,"out of memory\n");    exit(1);  }  paz = &azDefine[nDefine-1];  *paz = malloc( strlen(z)+1 );  if( *paz==0 ){    fprintf(stderr,"out of memory\n");    exit(1);  }  strcpy(*paz, z);  for(z=*paz; *z && *z!='='; z++){}  *z = 0;}/* 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_FSTR, "D", (char*)handle_D_option, "Define an %ifdef macro."},    {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);  }  memset(&lem, 0, sizeof(lem));  lem.errorcnt = 0;  /* Initialize the machine */  Strsafe_init();  Symbol_init();  State_init();  lem.argv0 = argv[0];  lem.filename = OptArg(0);  lem.basisflag = basisflag;  Symbol_new("$");  lem.errsym = Symbol_new("error");  /* Parse the input file */  Parse(&lem);  if( lem.errorcnt ) exit(lem.errorcnt);  if( lem.nrule==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();  for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;  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);    /* Reorder and renumber the states so that states with fewer choices    ** occur at the end. */    ResortStates(&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);  return (lem.errorcnt + lem.nconflict);}/******************** From the file "msort.c" *******************************//*** A generic merge-sort program.**** USAGE:** Let "ptr" be a pointer to some structure which is at the head of** a null-terminated list.  Then to sort the list call:****     ptr = msort(ptr,&(ptr->next),cmpfnc);**** In the above, "cmpfnc" is a pointer to a function which compares** two instances of the structure and returns an integer, as in** strcmp.  The second argument is a pointer to the pointer to the** second element of the linked list.  This address is used to compute** the offset to the "next" field within the structure.  The offset to** the "next" field must be constant for all structures in the list.**** The function returns a new pointer which is the head of the list** after sorting.**** ALGORITHM:** Merge-sort.*//*** Return a pointer to the next structure in the linked list.*/#define NEXT(A) (*(char**)(((unsigned long)A)+offset))/*** Inputs:**   a:       A sorted, null-terminated linked list.  (May be null).**   b:       A sorted, null-terminated linked list.  (May be null).**   cmp:     A pointer to the comparison function.**   offset:  Offset in the structure to the "next" field.**** Return Value:**   A pointer to the head of a sorted list containing the elements**   of both a and b.**** Side effects:**   The "next" pointers for elements in the lists a and b are**   changed.*/static char *merge(  char *a,  char *b,  int (*cmp)(const char*,const char*),  int offset){  char *ptr, *head;  if( a==0 ){    head = b;  }else if( b==0 ){    head = a;  }else{    if( (*cmp)(a,b)<0 ){      ptr = a;      a = NEXT(a);    }else{      ptr = b;      b = NEXT(b);    }    head = ptr;    while( a && b ){      if( (*cmp)(a,b)<0 ){        NEXT(ptr) = a;        ptr = a;        a = NEXT(a);      }else{        NEXT(ptr) = b;        ptr = b;        b = NEXT(b);      }    }    if( a ) NEXT(ptr) = a;    else    NEXT(ptr) = b;  }  return head;}/*** Inputs:**   list:      Pointer to a singly-linked list of structures.**   next:      Pointer to pointer to the second element of the list.**   cmp:       A comparison function.**** Return Value:**   A pointer to the head of a sorted list containing the elements**   orginally in list.**** Side effects:**   The "next" pointers for elements in list are changed.*/#define LISTSIZE 30static char *msort(  char *list,  char **next,  int (*cmp)(const char*,const char*)){  unsigned long offset;  char *ep;  char *set[LISTSIZE];  int i;  offset = (unsigned long)next - (unsigned long)list;  for(i=0; i<LISTSIZE; i++) set[i] = 0;  while( list ){    ep = list;    list = NEXT(list);    NEXT(ep) = 0;    for(i=0; i<LISTSIZE-1 && set[i]!=0; i++){      ep = merge(ep,set[i],cmp,offset);      set[i] = 0;    }    set[i] = ep;  }  ep = 0;  for(i=0; i<LISTSIZE; i++) if( set[i] ) ep = merge(ep,set[i],cmp,offset);  return ep;}/************************ From the file "option.c" **************************/static char **argv;static struct s_options *op;static FILE *errstream;#define ISOPT(X) ((X)[0]=='-'||(X)[0]=='+'||strchr((X),'=')!=0)/*** Print the command line with a carrot pointing to the k-th character** of the n-th field.*/static void errline(n,k,err)int n;int k;FILE *err;{  int spcnt, i;  if( argv[0] ) fprintf(err,"%s",argv[0]);  spcnt = strlen(argv[0]) + 1;  for(i=1; i<n && argv[i]; i++){    fprintf(err," %s",argv[i]);    spcnt += strlen(argv[i])+1;  }  spcnt += k;  for(; argv[i]; i++) fprintf(err," %s",argv[i]);  if( spcnt<20 ){    fprintf(err,"\n%*s^-- here\n",spcnt,"");  }else{    fprintf(err,"\n%*shere --^\n",spcnt-7,"");  }}/*** Return the index of the N-th non-switch argument.  Return -1** if N is out of range.*/static int argindex(n)int n;{  int i;  int dashdash = 0;  if( argv!=0 && *argv!=0 ){    for(i=1; argv[i]; i++){      if( dashdash || !ISOPT(argv[i]) ){        if( n==0 ) return i;        n--;      }      if( strcmp(argv[i],"--")==0 ) dashdash = 1;    }  }  return -1;}static char emsg[] = "Command line syntax error: ";/*** Process a flag command line argument.*/static int handleflags(i,err)int i;FILE *err;{  int v;  int errcnt = 0;  int j;  for(j=0; op[j].label; j++){    if( strncmp(&argv[i][1],op[j].label,strlen(op[j].label))==0 ) break;  }  v = argv[i][0]=='-' ? 1 : 0;  if( op[j].label==0 ){    if( err ){      fprintf(err,"%sundefined option.\n",emsg);      errline(i,1,err);    }    errcnt++;  }else if( op[j].type==OPT_FLAG ){    *((int*)op[j].arg) = v;  }else if( op[j].type==OPT_FFLAG ){    (*(void(*)())(op[j].arg))(v);  }else if( op[j].type==OPT_FSTR ){    (*(void(*)())(op[j].arg))(&argv[i][2]);  }else{    if( err ){      fprintf(err,"%smissing argument on switch.\n",emsg);      errline(i,1,err);    }    errcnt++;  }  return errcnt;

⌨️ 快捷键说明

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