SQLite

Check-in [d8bab8cf0b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added %expect directive, to consider a certain number of conflicts "correct."

This has the side effect of changing the process exit code to never overflow.

Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | lemon-update-2010
Files: files | file ages | folders
SHA1: d8bab8cf0bc3fbd4c489c31a65d724dda2944d83
User & Date: icculus 2010-02-14 05:19:56.000
Context
2010-02-14
05:34
Delete output files if this is a failed run.

Otherwise, the fail will stop a Makefile from progressing, but if you immediately run the build again, Make will think the output files are up to date, since they are newer (albeit incomplete/incorrect). (check-in: e38c08d9cd user: icculus tags: lemon-update-2010)

05:19
Added %expect directive, to consider a certain number of conflicts "correct."

This has the side effect of changing the process exit code to never overflow. (check-in: d8bab8cf0b user: icculus tags: lemon-update-2010)

00:48
Added -T option, to specify a template filename on the command line.

The default is still "lempar.c", though. (check-in: e6cbe1e5ee user: icculus tags: lemon-update-2010)

Changes
Unified Diff Ignore Whitespace Patch
Changes to tool/lemon.c.
264
265
266
267
268
269
270

271
272
273
274
275
276
277
  char *extracode;         /* Code appended to the generated file */
  char *tokendest;         /* Code to execute to destroy token data */
  char *vardest;           /* Code for the default non-terminal destructor */
  char *filename;          /* Name of the input file */
  char *outname;           /* Name of the current output file */
  char *tokenprefix;       /* A prefix added to token names in the .h file */
  int nconflict;           /* Number of parsing conflicts */

  int tablesize;           /* Size of the parse tables */
  int basisflag;           /* Print only basis configurations */
  int has_fallback;        /* True if any %fallback is seen in the grammar */
  int nolinenosflag;       /* True if #line statements should not be printed */
  char *argv0;             /* Name of the program */
};








>







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  char *extracode;         /* Code appended to the generated file */
  char *tokendest;         /* Code to execute to destroy token data */
  char *vardest;           /* Code for the default non-terminal destructor */
  char *filename;          /* Name of the input file */
  char *outname;           /* Name of the current output file */
  char *tokenprefix;       /* A prefix added to token names in the .h file */
  int nconflict;           /* Number of parsing conflicts */
  int nexpected;           /* Number of expected parsing conflicts */
  int tablesize;           /* Size of the parse tables */
  int basisflag;           /* Print only basis configurations */
  int has_fallback;        /* True if any %fallback is seen in the grammar */
  int nolinenosflag;       /* True if #line statements should not be printed */
  char *argv0;             /* Name of the program */
};

1462
1463
1464
1465
1466
1467
1468

1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488
    {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);







>













>







1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
    {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;
  int exitcode;
  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;
  lem.nexpected = -1;

  /* Initialize the machine */
  Strsafe_init();
  Symbol_init();
  State_init();
  lem.argv0 = argv[0];
  lem.filename = OptArg(0);
1560
1561
1562
1563
1564
1565
1566



1567
1568
1569
1570



1571
1572
1573
1574
1575
1576
1577
1578
  }
  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







>
>
>
|
|

|
>
>
>
|







1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
  }
  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.nexpected < 0 ) {
    lem.nexpected = 0;  /* grammar didn't have an %expect declaration. */
  }
  if( lem.nconflict != lem.nexpected ){
    fprintf(stderr,"%d parsing conflicts (%d expected).\n",lem.nconflict,lem.nexpected);
  }

  /* return 0 on success, 1 on failure. */
  exitcode = ((lem.errorcnt > 0) || (lem.nconflict != lem.nexpected)) ? 1 : 0;
  exit(exitcode);
  return (exitcode);
}
/******************** 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
2006
2007
2008
2009
2010
2011
2012

2013
2014
2015
2016
2017
2018
2019
    PRECEDENCE_MARK_1,
    PRECEDENCE_MARK_2,
    RESYNC_AFTER_RULE_ERROR,
    RESYNC_AFTER_DECL_ERROR,
    WAITING_FOR_DESTRUCTOR_SYMBOL,
    WAITING_FOR_DATATYPE_SYMBOL,
    WAITING_FOR_FALLBACK_ID,

    WAITING_FOR_WILDCARD_ID
  } state;                   /* The state of the parser */
  struct symbol *fallback;   /* The fallback token */
  struct symbol *lhs;        /* Left-hand side of current rule */
  char *lhsalias;            /* Alias for the LHS */
  int nrhs;                  /* Number of right-hand side symbols seen */
  struct symbol *rhs[MAXRHS];  /* RHS symbols */







>







2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
    PRECEDENCE_MARK_1,
    PRECEDENCE_MARK_2,
    RESYNC_AFTER_RULE_ERROR,
    RESYNC_AFTER_DECL_ERROR,
    WAITING_FOR_DESTRUCTOR_SYMBOL,
    WAITING_FOR_DATATYPE_SYMBOL,
    WAITING_FOR_FALLBACK_ID,
    WAITING_FOR_EXPECT_VALUE,
    WAITING_FOR_WILDCARD_ID
  } state;                   /* The state of the parser */
  struct symbol *fallback;   /* The fallback token */
  struct symbol *lhs;        /* Left-hand side of current rule */
  char *lhsalias;            /* Alias for the LHS */
  int nrhs;                  /* Number of right-hand side symbols seen */
  struct symbol *rhs[MAXRHS];  /* RHS symbols */
2029
2030
2031
2032
2033
2034
2035

2036
2037
2038
2039
2040
2041
2042
  struct rule *lastrule;     /* Pointer to the most recently parsed rule */
};

/* Parse a single token */
static void parseonetoken(psp)
struct pstate *psp;
{

  char *x;
  x = Strsafe(psp->tokenstart);     /* Save the token permanently */
#if 0
  printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno,
    x,psp->state);
#endif
  switch( psp->state ){







>







2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
  struct rule *lastrule;     /* Pointer to the most recently parsed rule */
};

/* Parse a single token */
static void parseonetoken(psp)
struct pstate *psp;
{
  char *endptr;
  char *x;
  x = Strsafe(psp->tokenstart);     /* Save the token permanently */
#if 0
  printf("%s:%d: Token=[%s] state=%d\n",psp->filename,psp->tokenlineno,
    x,psp->state);
#endif
  switch( psp->state ){
2313
2314
2315
2316
2317
2318
2319








2320
2321
2322
2323
2324
2325
2326
	}else if( strcmp(x,"type")==0 ){
          psp->state = WAITING_FOR_DATATYPE_SYMBOL;
        }else if( strcmp(x,"fallback")==0 ){
          psp->fallback = 0;
          psp->state = WAITING_FOR_FALLBACK_ID;
        }else if( strcmp(x,"wildcard")==0 ){
          psp->state = WAITING_FOR_WILDCARD_ID;








        }else{
          ErrorMsg(psp->filename,psp->tokenlineno,
            "Unknown declaration keyword: \"%%%s\".",x);
          psp->errorcnt++;
          psp->state = RESYNC_AFTER_DECL_ERROR;
	}
      }else{







>
>
>
>
>
>
>
>







2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
	}else if( strcmp(x,"type")==0 ){
          psp->state = WAITING_FOR_DATATYPE_SYMBOL;
        }else if( strcmp(x,"fallback")==0 ){
          psp->fallback = 0;
          psp->state = WAITING_FOR_FALLBACK_ID;
        }else if( strcmp(x,"wildcard")==0 ){
          psp->state = WAITING_FOR_WILDCARD_ID;
        }else if( strcmp(x,"expect")==0 ){
          if (psp->gp->nexpected >= 0) {
            ErrorMsg(psp->filename,psp->tokenlineno, "Multiple %expect declarations.");
            psp->errorcnt++;
            psp->state = RESYNC_AFTER_DECL_ERROR;
          } else {
            psp->state = WAITING_FOR_EXPECT_VALUE;
          }
        }else{
          ErrorMsg(psp->filename,psp->tokenlineno,
            "Unknown declaration keyword: \"%%%s\".",x);
          psp->errorcnt++;
          psp->state = RESYNC_AFTER_DECL_ERROR;
	}
      }else{
2340
2341
2342
2343
2344
2345
2346













2347
2348
2349
2350
2351
2352
2353
        struct symbol *sp = Symbol_new(x);
        psp->declargslot = &sp->destructor;
        psp->decllinenoslot = &sp->destLineno;
        psp->insertLineMacro = 1;
        psp->state = WAITING_FOR_DECL_ARG;
      }
      break;













    case WAITING_FOR_DATATYPE_SYMBOL:
      if( !isalpha(x[0]) ){
        ErrorMsg(psp->filename,psp->tokenlineno,
          "Symbol name missing after %destructor keyword");
        psp->errorcnt++;
        psp->state = RESYNC_AFTER_DECL_ERROR;
      }else{







>
>
>
>
>
>
>
>
>
>
>
>
>







2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
        struct symbol *sp = Symbol_new(x);
        psp->declargslot = &sp->destructor;
        psp->decllinenoslot = &sp->destLineno;
        psp->insertLineMacro = 1;
        psp->state = WAITING_FOR_DECL_ARG;
      }
      break;
    case WAITING_FOR_EXPECT_VALUE:
        psp->gp->nexpected = (int) strtol(x, &endptr, 10);
        if( (*endptr != '\0') || (endptr == x) ) {
          ErrorMsg(psp->filename,psp->tokenlineno,
            "Integer expected after %%expect keyword");
          psp->errorcnt++;
        } else if (psp->gp->nexpected < 0) {
          ErrorMsg(psp->filename,psp->tokenlineno,
            "Integer can't be negative after %%expect keyword");
          psp->errorcnt++;
        }
        psp->state = WAITING_FOR_DECL_OR_RULE;
        break;
    case WAITING_FOR_DATATYPE_SYMBOL:
      if( !isalpha(x[0]) ){
        ErrorMsg(psp->filename,psp->tokenlineno,
          "Symbol name missing after %destructor keyword");
        psp->errorcnt++;
        psp->state = RESYNC_AFTER_DECL_ERROR;
      }else{