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

📄 lemon.c

📁 一个小型的嵌入式数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
  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);  }  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();  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);    /* 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(a,b,cmp,offset)char *a;char *b;int (*cmp)();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 30char *msort(list,next,cmp)char *list;char **next;int (*cmp)();{  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;}/*** Process a command line switch which has an argument.*/static int handleswitch(i,err)int i;FILE *err;{  int lv = 0;  double dv = 0.0;  char *sv = 0, *end;  char *cp;  int j;  int errcnt = 0;  cp = strchr(argv[i],'=');  *cp = 0;  for(j=0; op[j].label; j++){    if( strcmp(argv[i],op[j].label)==0 ) break;  }  *cp = '=';  if( op[j].label==0 ){    if( err ){      fprintf(err,"%sundefined option.\n",emsg);      errline(i,0,err);    }    errcnt++;  }else{    cp++;    switch( op[j].type ){      case OPT_FLAG:      case OPT_FFLAG:

⌨️ 快捷键说明

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