- Undid some of the changes from lempar.c v1.30->v1.31, because it broke

error handling.
- Fixed: dehsupp/scanner.re defined "}" as the token RPAREN. dehsupp/parse.y
  also defined action_list_def as needing a RBARCE. I'm surprised it worked
  at all before. I guess Lemon really was too accepting.
- Changed the way that xlatcc handles include statements so that I don't need
  to modify the logic of lempar.c. I also discovered that the grammar was
  improperly defined and only accepted the first statement. It worked before
  because Lemon used to accept multiple times before reaching the EOF token.
  I have also verified that it is still generating the proper lumps.
- Removed some unused wadsrc files from the repository.
- Fixed my re2c upgrade.
- Updated lemon.c to v1.53.

SVN r711 (trunk)
This commit is contained in:
Randy Heit 2008-01-26 04:33:34 +00:00
parent e5572a1c4e
commit ec17f5a5b9
46 changed files with 9134 additions and 8988 deletions

View file

@ -1,4 +1,22 @@
January 25, 2008
- Undid some of the changes from lempar.c v1.30->v1.31, because it broke
error handling.
- Fixed: dehsupp/scanner.re defined "}" as the token RPAREN. dehsupp/parse.y
also defined action_list_def as needing a RBARCE. I'm surprised it worked
at all before. I guess Lemon really was too accepting. I have verified that
the lump it outputs is unchanged from before.
- Changed the way that xlatcc handles include statements so that I don't need
to modify the logic of lempar.c. I also discovered that the grammar was
improperly defined and only accepted the first statement. It worked before
because Lemon used to accept multiple times before reaching the EOF token.
I have also verified that it is still generating the proper lumps.
- Removed some unused wadsrc files from the repository.
- Fixed my re2c upgrade.
- Back to lemon.c v1.53 now. The bad change was v1.51: "Changes lemon so
that the generated parser does not accept prior to seeing the EOF token."
This seems like a valid change, which means I need to rethink my strategy
for handling include statements, since this change breaks what I was
doing before.
- Lemon is now producing parsers that don't accept anything, so I'm going
back to v1.43 and trying each intermediate version to see where things
went wrong.

View file

@ -1,4 +1,4 @@
/* Generated by re2c 0.10.5 */
/* Generated by re2c 0.12.3 */
#line 1 "src/sc_man_scanner.re"
#define YYCTYPE char
#define YYCURSOR cursor
@ -42,7 +42,7 @@ std2:
if((YYLIMIT - YYCURSOR) < 18) YYFILL(18);
yych = *YYCURSOR;
switch(yych){
switch(yych) {
case 0x09:
case 0x0B:
case 0x0C:
@ -181,7 +181,7 @@ yy5:
#line 182 "src/sc_man_scanner.h"
yy6:
yych = *++YYCURSOR;
switch(yych){
switch(yych) {
case 'A':
case 'a': goto yy536;
case 'H':
@ -309,7 +309,7 @@ yy12:
goto yy174;
yy13:
yych = *++YYCURSOR;
switch(yych){
switch(yych) {
case 'B':
case 'b': goto yy346;
case 'E':
@ -330,7 +330,7 @@ yy13:
}
yy14:
yych = *++YYCURSOR;
switch(yych){
switch(yych) {
case 'I':
case 'i': goto yy326;
case 'L':

View file

@ -48,6 +48,9 @@ int main (int argc, char **argv)
printf ("Could not open %s\n", argv[1]);
return -2;
}
#if !defined(NDEBUG) && 0
ParseTrace(fopen("trace.txt", "w"), "");
#endif
SourceLine = 1;
yyparse ();
fclose (Source);

View file

@ -424,7 +424,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating scanner.c from scanner.re"
CommandLine="..\re2c\re2c -s -o &quot;scanner.c&quot; &quot;$(InputFileName)&quot;&#x0D;&#x0A;"
CommandLine="..\re2c\re2c -s --no-generation-date -o &quot;scanner.c&quot; &quot;$(InputFileName)&quot;&#x0D;&#x0A;"
Outputs="$(InputDir)scanner.c"
/>
</FileConfiguration>
@ -444,7 +444,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating scanner.c from scanner.re"
CommandLine="..\re2c\re2c -s -o &quot;scanner.c&quot; &quot;$(InputFileName)&quot;&#x0D;&#x0A;"
CommandLine="..\re2c\re2c -s --no-generation-date -o &quot;scanner.c&quot; &quot;$(InputFileName)&quot;&#x0D;&#x0A;"
Outputs="$(InputDir)scanner.c"
/>
</FileConfiguration>

File diff suppressed because it is too large Load diff

View file

@ -21,14 +21,13 @@
#define SYM 21
#define OrgHeights 22
#define ActionList 23
#define RBARCE 24
#define CodePConv 25
#define OrgSprNames 26
#define StateMap 27
#define FirstState 28
#define SpawnState 29
#define DeathState 30
#define SoundMap 31
#define InfoNames 32
#define ThingBits 33
#define RenderStyles 34
#define CodePConv 24
#define OrgSprNames 25
#define StateMap 26
#define FirstState 27
#define SpawnState 28
#define DeathState 29
#define SoundMap 30
#define InfoNames 31
#define ThingBits 32
#define RenderStyles 33

View file

@ -5,6 +5,8 @@
%token_type {struct Token}
%syntax_error { yyerror("Syntax error"); }
%token_destructor { if ($$.string) free($$.string); }
%left OR.
@ -60,6 +62,7 @@ exp(A) ::= LPAREN exp(B) RPAREN. { A = B; }
actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON.
actions_def ::= Actions LBRACE error RBRACE SEMICOLON.
actions_list ::= . /* empty */
actions_list ::= SYM(A). { AddAction (A.string); }
@ -67,13 +70,15 @@ actions_list ::= actions_list COMMA SYM(A). { AddAction (A.string); }
org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON.
org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON.
org_heights_list ::= . /* empty */
org_heights_list ::= exp(A). { AddHeight (A); }
org_heights_list ::= org_heights_list COMMA exp(A). { AddHeight (A); }
action_list_def ::= ActionList LBRACE action_list_list RBARCE SEMICOLON.
action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON.
action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON.
action_list_list ::= . /* empty */
action_list_list ::= SYM(A). { AddActionMap (A.string); }
@ -81,6 +86,7 @@ action_list_list ::= action_list_list COMMA SYM(A). { AddActionMap (A.string); }
codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON.
codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON.
codep_conv_list ::= . /* empty */
codep_conv_list ::= exp(A). { AddCodeP (A); }
@ -88,6 +94,7 @@ codep_conv_list ::= codep_conv_list COMMA exp(A). { AddCodeP (A); }
org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON.
org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON.
org_spr_names_list ::= . /* empty */
org_spr_names_list ::= SYM(A). { AddSpriteName (A.string); }
@ -95,6 +102,7 @@ org_spr_names_list ::= org_spr_names_list COMMA SYM(A). { AddSpriteName (A.strin
state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON.
state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON.
state_map_list ::= . /* empty */
state_map_list ::= state_map_entry.
@ -109,6 +117,7 @@ state_type(A) ::= DeathState. { A = 2; }
sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON.
sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON.
sound_map_list ::= . /* empty */
sound_map_list ::= STRING(A). { AddSoundMap (A.string); }
@ -116,6 +125,7 @@ sound_map_list ::= sound_map_list COMMA STRING(A). { AddSoundMap (A.string); }
info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON.
info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON.
info_names_list ::= . /* empty */
info_names_list ::= SYM(A). { AddInfoName (A.string); }
@ -123,6 +133,7 @@ info_names_list ::= info_names_list COMMA SYM(A). { AddInfoName (A.string); }
thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON.
thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON.
thing_bits_list ::= . /* empty */
thing_bits_list ::= thing_bits_entry.
@ -132,6 +143,7 @@ thing_bits_entry ::= exp(A) COMMA exp(B) COMMA SYM(C). { AddThingBits (C.string,
render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON.
render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON.
render_styles_list ::= . /* empty */
render_styles_list ::= render_styles_entry.

File diff suppressed because it is too large Load diff

View file

@ -106,7 +106,7 @@ ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
"*" { RET(MULTIPLY); }
"/" { RET(DIVIDE); }
"(" { RET(LPAREN); }
"}" { RET(RPAREN); }
")" { RET(RPAREN); }
"," { RET(COMMA); }
"{" { RET(LBRACE); }
"}" { RET(RBRACE); }

View file

@ -15,6 +15,7 @@
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#ifndef __WIN32__
# if defined(_WIN32) || defined(WIN32)
@ -22,6 +23,12 @@
# endif
#endif
#ifdef __WIN32__
extern int access();
#else
#include <unistd.h>
#endif
/* #define PRIVATE static */
#define PRIVATE
@ -31,19 +38,11 @@
#define MAXRHS 1000
#endif
void *msort(void *list, void *next, int (*cmp)());
static void *msort(void *list, void *next, int (*cmp)());
/******** From the file "action.h" *************************************/
struct action *Action_new();
struct action *Action_sort();
/********* From the file "assert.h" ************************************/
void myassert();
#ifndef NDEBUG
# define assert(X) if(!(X))myassert(__FILE__,__LINE__)
#else
# define assert(X)
#endif
static struct action *Action_new(void);
static struct action *Action_sort(struct action *);
/********** From the file "build.h" ************************************/
void FindRulePrecedences();
@ -114,7 +113,7 @@ int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */
** Principal data structures for the LEMON parser generator.
*/
typedef enum {B_FALSE=0, B_TRUE} Boolean;
typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean;
/* Symbols (terminals and nonterminals) of the grammar are stored
** in the following: */
@ -137,6 +136,7 @@ struct symbol {
} assoc; /* Associativity if predecence is defined */
char *firstset; /* First-set for all rules of this symbol */
Boolean lambda; /* True if NT and can generate an empty string */
int useCnt; /* Number of times used */
char *destructor; /* Code which executes whenever this symbol is
** popped from the stack during error processing */
int destructorln; /* Line number of destructor code */
@ -155,6 +155,7 @@ struct symbol {
struct rule {
struct symbol *lhs; /* Left-hand side of the rule */
char *lhsalias; /* Alias for the LHS (NULL if none) */
int lhsStart; /* True if left-hand side is the start symbol */
int ruleline; /* Line number for the rule */
int nrhs; /* Number of RHS symbols */
struct symbol **rhs; /* The RHS symbols */
@ -196,7 +197,9 @@ struct action {
ACCEPT,
REDUCE,
ERROR,
CONFLICT, /* Was a reduce, but part of a conflict */
SSCONFLICT, /* A shift/shift conflict */
SRCONFLICT, /* Was a reduce, but part of a conflict */
RRCONFLICT, /* Was a reduce, but part of a conflict */
SH_RESOLVED, /* Was a shift. Precedence resolved conflict */
RD_RESOLVED, /* Was reduce. Precedence resolved conflict */
NOT_USED /* Deleted by compression */
@ -335,14 +338,14 @@ void Configtable_clear(/* int(*)(struct config *) */);
*/
/* Allocate a new parser action */
struct action *Action_new(){
static struct action *Action_new(void){
static struct action *freelist = 0;
struct action *new;
if( freelist==0 ){
int i;
int amt = 100;
freelist = (struct action *)malloc( sizeof(struct action)*amt );
freelist = (struct action *)calloc(amt, sizeof(struct action));
if( freelist==0 ){
fprintf(stderr,"Unable to allocate memory for a new parser action.");
exit(1);
@ -355,23 +358,27 @@ struct action *Action_new(){
return new;
}
/* Compare two actions */
/* Compare two actions for sorting purposes. Return negative, zero, or
** positive if the first action is less than, equal to, or greater than
** the first
*/
static int actioncmp(ap1,ap2)
struct action *ap1;
struct action *ap2;
{
int rc;
rc = ap1->sp->index - ap2->sp->index;
if( rc==0 ) rc = (int)ap1->type - (int)ap2->type;
if( rc==0 ){
rc = (int)ap1->type - (int)ap2->type;
}
if( rc==0 && ap1->type==REDUCE ){
rc = ap1->x.rp->index - ap2->x.rp->index;
}
return rc;
}
/* Sort parser actions */
struct action *Action_sort(ap)
struct action *ap;
static struct action *Action_sort(struct action *ap)
{
ap = (struct action *)msort(ap,&ap->next,actioncmp);
return ap;
@ -438,7 +445,7 @@ void acttab_free(acttab *p){
/* Allocate a new acttab structure */
acttab *acttab_alloc(void){
acttab *p = malloc( sizeof(*p) );
acttab *p = calloc( 1, sizeof(*p) );
if( p==0 ){
fprintf(stderr,"Unable to allocate memory for a new acttab.");
exit(1);
@ -559,17 +566,6 @@ int acttab_insert(acttab *p){
return i - p->mnLookahead;
}
/********************** From the file "assert.c" ****************************/
/*
** A more efficient way of handling assertions.
*/
void myassert(file,line)
char *file;
int line;
{
fprintf(stderr,"Assertion failed on line %d of file \"%s\"\n",line,file);
exit(1);
}
/********************** From the file "build.c" *****************************/
/*
** Routines to construction the finite state machine for the LEMON
@ -623,7 +619,7 @@ struct lemon *lemp;
int progress;
for(i=0; i<lemp->nsymbol; i++){
lemp->symbols[i]->lambda = B_FALSE;
lemp->symbols[i]->lambda = LEMON_FALSE;
}
for(i=lemp->nterminal; i<lemp->nsymbol; i++){
lemp->symbols[i]->firstset = SetNew();
@ -636,10 +632,10 @@ struct lemon *lemp;
if( rp->lhs->lambda ) continue;
for(i=0; i<rp->nrhs; i++){
struct symbol *sp = rp->rhs[i];
if( sp->type!=TERMINAL || sp->lambda==B_FALSE ) break;
if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break;
}
if( i==rp->nrhs ){
rp->lhs->lambda = B_TRUE;
rp->lhs->lambda = LEMON_TRUE;
progress = 1;
}
}
@ -662,10 +658,10 @@ struct lemon *lemp;
}
break;
}else if( s1==s2 ){
if( s1->lambda==B_FALSE ) break;
if( s1->lambda==LEMON_FALSE ) break;
}else{
progress += SetUnion(s1->firstset,s2->firstset);
if( s2->lambda==B_FALSE ) break;
if( s2->lambda==LEMON_FALSE ) break;
}
}
}
@ -722,6 +718,7 @@ does not work properly.",sp->name);
** left-hand side */
for(rp=sp->rule; rp; rp=rp->nextlhs){
struct config *newcfp;
rp->lhsStart = 1;
newcfp = Configlist_addbasis(rp,0);
SetAdd(newcfp->fws,0);
}
@ -973,7 +970,7 @@ struct lemon *lemp;
struct action *ap, *nap;
struct state *stp;
stp = lemp->sorted[i];
assert( stp->ap );
/* assert( stp->ap ); */
stp->ap = Action_sort(stp->ap);
for(ap=stp->ap; ap && ap->next; ap=ap->next){
for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
@ -985,11 +982,11 @@ struct lemon *lemp;
}
/* Report an error for each rule that can never be reduced. */
for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = B_FALSE;
for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE;
for(i=0; i<lemp->nstate; i++){
struct action *ap;
for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
if( ap->type==REDUCE ) ap->x.rp->canReduce = B_TRUE;
if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE;
}
}
for(rp=lemp->rule; rp; rp=rp->next){
@ -1021,7 +1018,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
int errcnt = 0;
assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */
if( apx->type==SHIFT && apy->type==SHIFT ){
apy->type = CONFLICT;
apy->type = SSCONFLICT;
errcnt++;
}
if( apx->type==SHIFT && apy->type==REDUCE ){
@ -1029,7 +1026,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
spy = apy->x.rp->precsym;
if( spy==0 || spx->prec<0 || spy->prec<0 ){
/* Not enough precedence information. */
apy->type = CONFLICT;
apy->type = SRCONFLICT;
errcnt++;
}else if( spx->prec>spy->prec ){ /* Lower precedence wins */
apy->type = RD_RESOLVED;
@ -1041,7 +1038,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
apx->type = SH_RESOLVED;
}else{
assert( spx->prec==spy->prec && spx->assoc==NONE );
apy->type = CONFLICT;
apy->type = SRCONFLICT;
errcnt++;
}
}else if( apx->type==REDUCE && apy->type==REDUCE ){
@ -1049,7 +1046,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
spy = apy->x.rp->precsym;
if( spx==0 || spy==0 || spx->prec<0 ||
spy->prec<0 || spx->prec==spy->prec ){
apy->type = CONFLICT;
apy->type = RRCONFLICT;
errcnt++;
}else if( spx->prec>spy->prec ){
apy->type = RD_RESOLVED;
@ -1060,10 +1057,14 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */
assert(
apx->type==SH_RESOLVED ||
apx->type==RD_RESOLVED ||
apx->type==CONFLICT ||
apx->type==SSCONFLICT ||
apx->type==SRCONFLICT ||
apx->type==RRCONFLICT ||
apy->type==SH_RESOLVED ||
apy->type==RD_RESOLVED ||
apy->type==CONFLICT
apy->type==SSCONFLICT ||
apy->type==SRCONFLICT ||
apy->type==RRCONFLICT
);
/* The REDUCE/SHIFT case cannot happen because SHIFTs come before
** REDUCEs on the list. If we reach this point it must be because
@ -1089,7 +1090,7 @@ PRIVATE struct config *newconfig(){
if( freelist==0 ){
int i;
int amt = 3;
freelist = (struct config *)malloc( sizeof(struct config)*amt );
freelist = (struct config *)calloc( amt, sizeof(struct config) );
if( freelist==0 ){
fprintf(stderr,"Unable to allocate memory for a new configuration.");
exit(1);
@ -1223,7 +1224,7 @@ struct lemon *lemp;
break;
}else{
SetUnion(newcfp->fws,xsp->firstset);
if( xsp->lambda==B_FALSE ) break;
if( xsp->lambda==LEMON_FALSE ) break;
}
}
if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
@ -1452,6 +1453,7 @@ char **argv;
lem.basisflag = basisflag;
Symbol_new("$");
lem.errsym = Symbol_new("error");
lem.errsym->useCnt = 0;
/* Parse the input file */
Parse(&lem);
@ -1477,7 +1479,7 @@ char **argv;
Reprint(&lem);
}else{
/* Initialize the size for all follow and first sets */
SetSize(lem.nterminal);
SetSize(lem.nterminal+1);
/* Find the precedence for every production rule (that has one) */
FindRulePrecedences(&lem);
@ -1623,7 +1625,7 @@ static void *merge(void *a,void *b,int (*cmp)(),size_t offset)
** The "next" pointers for elements in list are changed.
*/
#define LISTSIZE 30
void *msort(void *list,void *next,int (*cmp)())
static void *msort(void *list,void *next,int (*cmp)())
{
size_t offset;
char *ep;
@ -2108,8 +2110,8 @@ to follow the previous rule.");
case IN_RHS:
if( x[0]=='.' ){
struct rule *rp;
rp = (struct rule *)malloc( sizeof(struct rule) +
sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs );
rp = (struct rule *)calloc( sizeof(struct rule) +
sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1);
if( rp==0 ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Can't allocate enough memory for this rule.");
@ -2145,7 +2147,7 @@ to follow the previous rule.");
}else if( isalpha(x[0]) ){
if( psp->nrhs>=MAXRHS ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Too many symbols on RHS or rule beginning at \"%s\".",
"Too many symbols on RHS of rule beginning at \"%s\".",
x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_RULE_ERROR;
@ -2158,11 +2160,10 @@ to follow the previous rule.");
struct symbol *msp = psp->rhs[psp->nrhs-1];
if( msp->type!=MULTITERMINAL ){
struct symbol *origsp = msp;
msp = malloc(sizeof(*msp));
memset(msp, 0, sizeof(*msp));
msp = calloc(1,sizeof(*msp));
msp->type = MULTITERMINAL;
msp->nsubsym = 1;
msp->subsym = malloc(sizeof(struct symbol*));
msp->subsym = calloc(1,sizeof(struct symbol*));
msp->subsym[0] = origsp;
msp->name = origsp->name;
psp->rhs[psp->nrhs-1] = msp;
@ -2407,7 +2408,7 @@ to follow the previous rule.");
static void preprocess_input(char *z){
int i, j, k, n;
int exclude = 0;
int start = 1;
int start = 0;
int lineno = 1;
int start_lineno = 1;
for(i=0; z[i]; i++){
@ -2484,7 +2485,7 @@ struct lemon *gp;
char *cp, *nextcp;
int startline = 0;
memset(&ps, 0, sizeof ps);
memset(&ps, '\0', sizeof(ps));
ps.gp = gp;
ps.filename = gp->filename;
ps.errorcnt = 0;
@ -2633,7 +2634,7 @@ struct plink *Plink_new(){
if( plink_freelist==0 ){
int i;
int amt = 100;
plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt );
plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) );
if( plink_freelist==0 ){
fprintf(stderr,
"Unable to allocate memory for a new follow-set propagation link.\n");
@ -2859,10 +2860,15 @@ int PrintAction(struct action *ap, FILE *fp, int indent){
case ERROR:
fprintf(fp,"%*s error",indent,ap->sp->name);
break;
case CONFLICT:
case SRCONFLICT:
case RRCONFLICT:
fprintf(fp,"%*s reduce %-3d ** Parsing conflict **",
indent,ap->sp->name,ap->x.rp->index);
break;
case SSCONFLICT:
fprintf(fp,"%*s shift %d ** Parsing conflict **",
indent,ap->sp->name,ap->x.stp->statenum);
break;
case SH_RESOLVED:
case RD_RESOLVED:
case NOT_USED:
@ -2884,7 +2890,6 @@ struct lemon *lemp;
fp = file_open(lemp,".out","wb");
if( fp==0 ) return;
fprintf(fp," \b");
for(i=0; i<lemp->nstate; i++){
stp = lemp->sorted[i];
fprintf(fp,"State %d:\n",stp->statenum);
@ -2914,6 +2919,27 @@ struct lemon *lemp;
}
fprintf(fp,"\n");
}
fprintf(fp, "----------------------------------------------------\n");
fprintf(fp, "Symbols:\n");
for(i=0; i<lemp->nsymbol; i++){
int j;
struct symbol *sp;
sp = lemp->symbols[i];
fprintf(fp, " %3d: %s", i, sp->name);
if( sp->type==NONTERMINAL ){
fprintf(fp, ":");
if( sp->lambda ){
fprintf(fp, " <lambda>");
}
for(j=0; j<lemp->nterminal; j++){
if( sp->firstset && SetFind(sp->firstset, j) ){
fprintf(fp, " %s", lemp->symbols[j]->name);
}
}
}
fprintf(fp, "\n");
}
fclose(fp);
return;
}
@ -2928,7 +2954,6 @@ int modemask;
char *pathlist;
char *path,*cp;
char c;
extern int access();
#ifdef __WIN32__
for (cp = argv0 + strlen(argv0); cp-- > argv0; )
@ -3229,8 +3254,13 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
for(i=0; i<rp->nrhs; i++) used[i] = 0;
lhsused = 0;
if( rp->code==0 ){
rp->code = "\n";
rp->line = rp->ruleline;
}
append_str(0,0,0,0,0);
for(cp=(rp->code?rp->code:""); *cp; cp++){
for(cp=rp->code; *cp; cp++){
if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){
char saved;
for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++);
@ -3351,8 +3381,7 @@ int mhflag; /* True if generating makeheaders output */
/* Allocate and initialize types[] and allocate stddt[] */
arraysize = lemp->nsymbol * 2;
types = (char**)malloc( arraysize * sizeof(char*) );
for(i=0; i<arraysize; i++) types[i] = 0;
types = (char**)calloc( arraysize, sizeof(char*) );
maxdtlength = 0;
if( lemp->vartype ){
maxdtlength = (int)strlen(lemp->vartype);
@ -3432,7 +3461,9 @@ int mhflag; /* True if generating makeheaders output */
fprintf(out," %s yy%d;\n",types[i],i+1); lineno++;
free(types[i]);
}
fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++;
if( lemp->errsym->useCnt ){
fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++;
}
free(stddt);
free(types);
fprintf(out,"} YYMINORTYPE;\n"); lineno++;
@ -3482,6 +3513,25 @@ static int axset_compare(const void *a, const void *b){
return p2->nAction - p1->nAction;
}
/*
** Write text on "out" that describes the rule "rp".
*/
static void writeRuleText(FILE *out, struct rule *rp){
int j;
fprintf(out,"%s ::=", rp->lhs->name);
for(j=0; j<rp->nrhs; j++){
struct symbol *sp = rp->rhs[j];
fprintf(out," %s", sp->name);
if( sp->type==MULTITERMINAL ){
int k;
for(k=1; k<sp->nsubsym; k++){
fprintf(out,"|%s",sp->subsym[k]->name);
}
}
}
}
/* Generate C source code for the parser */
void ReportTable(lemp, mhflag)
struct lemon *lemp;
@ -3544,18 +3594,13 @@ int mhflag; /* Output in makeheaders format if true */
lemp->wildcard->index); lineno++;
}
print_stack_union(out,lemp,&lineno,mhflag);
fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++;
if( lemp->stacksize ){
if( atoi(lemp->stacksize)<=0 ){
ErrorMsg(lemp->filename,0,
"Illegal stack size: [%s]. The stack size should be an integer constant.",
lemp->stacksize);
lemp->errorcnt++;
lemp->stacksize = "100";
}
fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++;
}else{
fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++;
}
fprintf(out, "#endif\n"); lineno++;
if( mhflag ){
fprintf(out,"#if INTERFACE\n"); lineno++;
}
@ -3582,8 +3627,10 @@ int mhflag; /* Output in makeheaders format if true */
}
fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++;
fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++;
fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
if( lemp->errsym->useCnt ){
fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++;
fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++;
}
if( lemp->has_fallback ){
fprintf(out,"#define YYFALLBACK 1\n"); lineno++;
}
@ -3602,7 +3649,7 @@ int mhflag; /* Output in makeheaders format if true */
*/
/* Compute the actions on all states and count them up */
ax = malloc( sizeof(ax[0])*lemp->nstate*2 );
ax = calloc(lemp->nstate*2 , sizeof(ax[0]));
if( ax==0 ){
fprintf(stderr,"malloc failed\n");
exit(1);
@ -3782,17 +3829,8 @@ int mhflag; /* Output in makeheaders format if true */
*/
for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
assert( rp->index==i );
fprintf(out," /* %3d */ \"%s ::=", i, rp->lhs->name);
for(j=0; j<rp->nrhs; j++){
struct symbol *sp = rp->rhs[j];
fprintf(out," %s", sp->name);
if( sp->type==MULTITERMINAL ){
int k;
for(k=1; k<sp->nsubsym; k++){
fprintf(out,"|%s",sp->subsym[k]->name);
}
}
}
fprintf(out," /* %3d */ \"", i);
writeRuleText(out, rp);
fprintf(out,"\",\n"); lineno++;
}
tplt_xfer(lemp->name,in,out,&lineno);
@ -3805,7 +3843,8 @@ int mhflag; /* Output in makeheaders format if true */
for(i=0; i<lemp->nsymbol; i++){
struct symbol *sp = lemp->symbols[i];
if( sp==0 || sp->type!=TERMINAL ) continue;
fprintf(out," case %d:\n",sp->index); lineno++;
fprintf(out," case %d: /* %s */\n",
sp->index, sp->name); lineno++;
}
for(i=0; i<lemp->nsymbol && lemp->symbols[i]->type!=TERMINAL; i++);
if( i<lemp->nsymbol ){
@ -3819,7 +3858,8 @@ int mhflag; /* Output in makeheaders format if true */
struct symbol *sp = lemp->symbols[i];
if( sp==0 || sp->type==TERMINAL ||
sp->index<=0 || sp->destructor!=0 ) continue;
fprintf(out," case %d:\n",sp->index); lineno++;
fprintf(out," case %d: /* %s */\n",
sp->index, sp->name); lineno++;
dflt_sp = sp;
}
if( dflt_sp!=0 ){
@ -3830,7 +3870,8 @@ int mhflag; /* Output in makeheaders format if true */
for(i=0; i<lemp->nsymbol; i++){
struct symbol *sp = lemp->symbols[i];
if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue;
fprintf(out," case %d:\n",sp->index); lineno++;
fprintf(out," case %d: /* %s */\n",
sp->index, sp->name); lineno++;
/* Combine duplicate destructors into a single case */
for(j=i+1; j<lemp->nsymbol; j++){
@ -3838,7 +3879,8 @@ int mhflag; /* Output in makeheaders format if true */
if( sp2 && sp2->type!=TERMINAL && sp2->destructor
&& sp2->dtnum==sp->dtnum
&& strcmp(sp->destructor,sp2->destructor)==0 ){
fprintf(out," case %d:\n",sp2->index); lineno++;
fprintf(out," case %d: /* %s */\n",
sp2->index, sp2->name); lineno++;
sp2->destructor = 0;
}
}
@ -3869,10 +3911,14 @@ int mhflag; /* Output in makeheaders format if true */
for(rp=lemp->rule; rp; rp=rp->next){
struct rule *rp2;
if( rp->code==0 ) continue;
fprintf(out," case %d:\n",rp->index); lineno++;
fprintf(out," case %d: /* ",rp->index);
writeRuleText(out, rp);
fprintf(out, " */\n"); lineno++;
for(rp2=rp->next; rp2; rp2=rp2->next){
if( rp2->code==rp->code ){
fprintf(out," case %d:\n",rp2->index); lineno++;
fprintf(out," case %d: /*",rp2->index);
writeRuleText(out, rp2);
fprintf(out," */\n"); lineno++;
rp2->code = 0;
}
}
@ -3964,6 +4010,7 @@ struct lemon *lemp;
}
if( ap->type!=REDUCE ) continue;
rp = ap->x.rp;
if( rp->lhsStart ) continue;
if( rp==rbest ) continue;
n = 1;
for(ap2=ap->next; ap2; ap2=ap2->next){
@ -4072,13 +4119,11 @@ int n;
/* Allocate a new set */
char *SetNew(){
char *s;
int i;
s = (char*)malloc( size );
s = (char*)calloc( size, 1);
if( s==0 ){
extern void memory_error();
memory_error();
}
for(i=0; i<size; i++) s[i] = 0;
return s;
}
@ -4096,6 +4141,7 @@ char *s;
int e;
{
int rv;
assert( e>=0 && e<size );
rv = s[e];
s[e] = 1;
return !rv;
@ -4285,7 +4331,7 @@ char *x;
sp = Symbol_find(x);
if( sp==0 ){
sp = (struct symbol *)malloc( sizeof(struct symbol) );
sp = (struct symbol *)calloc(1, sizeof(struct symbol) );
MemoryCheck(sp);
sp->name = Strsafe(x);
sp->type = isupper(*x) ? TERMINAL : NONTERMINAL;
@ -4294,11 +4340,13 @@ char *x;
sp->prec = -1;
sp->assoc = UNK;
sp->firstset = 0;
sp->lambda = B_FALSE;
sp->lambda = LEMON_FALSE;
sp->destructor = 0;
sp->datatype = 0;
sp->useCnt = 0;
Symbol_insert(sp,sp->name);
}
sp->useCnt++;
return sp;
}
@ -4468,7 +4516,7 @@ struct symbol **Symbol_arrayof()
int i,size;
if( x2a==0 ) return 0;
size = x2a->count;
array = (struct symbol **)malloc( sizeof(struct symbol *)*size );
array = (struct symbol **)calloc(size, sizeof(struct symbol *));
if( array ){
for(i=0; i<size; i++) array[i] = x2a->tbl[i].data;
}
@ -4519,7 +4567,7 @@ struct config *a;
struct state *State_new()
{
struct state *new;
new = (struct state *)malloc( sizeof(struct state) );
new = (struct state *)calloc(1, sizeof(struct state) );
MemoryCheck(new);
return new;
}

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,57 @@
Version 0.12.3 (2007-08-24)
---------------------------
- Fixed issue with some compilers.
- Fixed #1776177 Build on AIX.
- Fixed #1743180 fwrite with 0 length crashes on OS X.
Version 0.12.2 (2007-06-26)
---------------------------
- Fixed #1743180 fwrite with 0 length crashes on OS X.
Version 0.12.1 (2007-05-23)
---------------------------
- Fixed #1711240 problem with '"' and 7F on EBCDIC plattforms.
Version 0.12.0 (2007-05-01)
---------------------------
- Re-release of 0.11.3 as new stable branch.
- Fixed issue with short form of switches and parameter if not first switch.
- Fixed #1708378 segfault in actions.cc.
Version 0.11.3 (2007-04-01)
---------------------------
- Added support for underscores in named definitions.
- Added new option --no-generation-date.
- Fixed issue with long form of switches.
Version 0.11.2 (2007-03-01)
---------------------------
- Added inplace configuration 're2c:yyfill:parameter'.
- Added inplace configuration 're2c:yych:conversion'.
- Fixed -u switch code generation.
- Added ability to avoid defines and overwrite variable and label names.
Version 0.11.1 (2007-02-20)
---------------------------
- Applied #1647875 add const to yybm vector.
Version 0.11.0 (2007-01-01)
---------------------------
- Added -u switch to support unicode.
Version 0.10.8 (2007-04-01)
---------------------------
- Fixed issue with long form of switches.
Version 0.10.7 (2007-02-20)
---------------------------
- Applied #1647875 add const to yybm vector.
Version 0.10.6 (2006-08-05)
---------------------------
- Fixed #1529351 Segv bug on unterminated code blocks.
- Fixed #1528269 Invalid code generation.
Version 0.10.5 (2006-06-11)
---------------------------
- Fixed long form of -1 switch to --single-pass as noted in man page and help.
@ -20,7 +74,7 @@ Version 0.10.2 (2006-05-01)
- Fixed -i switch.
- Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks.
- Added tutorial like lessons to re2c.
- Added /*!ignore!re2c */ to support documenting of re2c source.
- Added /*!ignore:re2c */ to support documenting of re2c source.
- Fixed issue with multiline re2c comments (/*!max:re2c ... */ and alike).
- Fixed generation of YYDEBUG() when using -d switch.
- Added /*!getstate:re2c */ which triggers generation of the YYGETSTATE() block.

View file

@ -1,11 +1,11 @@
ifeq (Windows_NT,$(OS))
WIN=1
WINCMD=1
endif
ifeq (msys,$(OSTYPE))
WIN=1
WINCMD=0
endif
ifeq (Windows_NT,$(OS))
WIN=1
WINCMD=1
endif
ifeq (msys,$(OSTYPE))
WIN=1
WINCMD=0
endif
ifeq (1,$(WIN))
EXE = re2c.exe

View file

@ -1,4 +1,4 @@
re2c Version 0.10.5
re2c Version 0.12.3
------------------
Originally written by Peter Bumbulis (peter@csg.uwaterloo.ca)
@ -17,7 +17,7 @@ platforms in 32 bit and 64 bit mode:
- GCC 3.3 ... 4.1
- Microsoft VC 7, 7.1, 8
- Intel 9.0
- Sun C++ 5.8 (CXXFLAGS='-compat5 -library=stlport4')
- Sun C++ 5.8 (CXXFLAGS='-library=stlport4')
- MIPSpro Compilers: Version 7.4.4m
GCC 2.x and Microsoft VC 6 are not capable of compiling re2c.
@ -41,7 +41,7 @@ re2c) you need the following steps:
Or you can create a rpm package and install it by the following commands:
./configure
make rpm
rpm -Uhv <packagedir>/re2c-0.10.5-1.rpm
rpm -Uhv <packagedir>/re2c-0.12.3-1.rpm
If you want to build from CVS then the first thing you should do is
regenerating all build files using the following command:
@ -51,7 +51,7 @@ need to generate RPM packages for cvs builds use these commands:
./autogen.sh
./configure
./makerpm <release>
rpm -Uhv <packagedir>/re2c-0.10.5-<release>.rpm
rpm -Uhv <packagedir>/re2c-0.12.3-<release>.rpm
Here <realease> should be a number like 1. And <packagedir> must equal
the directory where the makerpm step has written the generated rpm to.

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id: basics.h,v 1.6 2005/12/29 14:32:09 helly Exp $ */
/* $Id: basics.h 520 2006-05-25 13:31:06Z helly $ */
#ifndef _basics_h
#define _basics_h

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id: code.h,v 1.7 2006/01/21 15:51:02 helly Exp $ */
/* $Id: code.h 525 2006-05-25 13:32:49Z helly $ */
#ifndef _code_h
#define _code_h

View file

@ -1,4 +1,4 @@
/* $Id: dfa.h,v 1.23 2006/05/14 13:38:26 helly Exp $ */
/* $Id: dfa.h 569 2006-06-05 22:14:00Z helly $ */
#ifndef _dfa_h
#define _dfa_h

View file

@ -1,4 +1,4 @@
/* $Id: globals.h,v 1.31 2006/05/14 13:38:26 helly Exp $ */
/* $Id: globals.h 713 2007-04-29 15:33:47Z helly $ */
#ifndef _globals_h
#define _globals_h

View file

@ -1,4 +1,4 @@
/* $Id: ins.h,v 1.7 2006/01/03 11:40:38 helly Exp $ */
/* $Id: ins.h 535 2006-05-25 13:36:14Z helly $ */
#ifndef _ins_h
#define _ins_h

View file

@ -1,4 +1,4 @@
/* $Id: main.cc,v 1.53 2006/05/14 13:38:26 helly Exp $ */
/* $Id: main.cc 691 2007-04-22 15:07:39Z helly $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_WIN32)
@ -139,7 +139,7 @@ static void usage()
" with -f and disables YYMAXFILL generation prior to last\n"
" re2c block.\n"
"\n"
"--no-generation-date Suppress the date output in the generated output so that it\n"
"--no-generation-date Suppress date output in the generated output so that it\n"
" only shows the re2c version.\n"
;
}

View file

@ -2,7 +2,7 @@
Author: Marcus Boerger <helly@users.sourceforge.net>
*/
/* $Id: mbo_getopt.cc,v 1.5 2006/04/17 19:28:47 helly Exp $ */
/* $Id: mbo_getopt.cc 698 2007-04-23 21:06:56Z helly $ */
#include <stdio.h>
#include <string.h>

View file

@ -2,7 +2,7 @@
Author: Marcus Boerger <helly@users.sourceforge.net>
*/
/* $Id: mbo_getopt.h,v 1.5 2006/04/17 19:28:47 helly Exp $ */
/* $Id: mbo_getopt.h 539 2006-05-25 13:37:38Z helly $ */
/* Define structure for one recognized option (both single char and long name).
* If short_open is '-' this is the last option.

View file

@ -95,7 +95,7 @@
#line 1 "./parser.y"
/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */
/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */
#ifdef HAVE_CONFIG_H
#include "config.h"

View file

@ -1,4 +1,4 @@
/* $Id: parser.h,v 1.10 2006/01/21 15:51:02 helly Exp $ */
/* $Id: parser.h 565 2006-06-05 22:07:13Z helly $ */
#ifndef _parser_h
#define _parser_h

View file

@ -1,6 +1,6 @@
%{
/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */
/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */
#ifdef HAVE_CONFIG_H
#include "config.h"

View file

@ -1,16 +1,16 @@
/* $Id: re.h,v 1.17 2006/04/09 00:06:33 helly Exp $ */
#ifndef _re_h
#define _re_h
#include <iostream>
#include <set>
#include "token.h"
#include "ins.h"
#include "globals.h"
namespace re2c
{
/* $Id: re.h 775 2007-07-10 19:33:17Z helly $ */
#ifndef _re_h
#define _re_h
#include <iostream>
#include <set>
#include "token.h"
#include "ins.h"
#include "globals.h"
namespace re2c
{
template<class _Ty>
class free_list: protected std::set<_Ty>
{
@ -55,436 +55,442 @@ public:
protected:
bool in_clear;
};
typedef struct extop
{
char op;
int minsize;
int maxsize;
}
ExtOp;
struct CharPtn
{
uint card;
CharPtn *fix;
CharPtn *nxt;
};
typedef CharPtn *CharPtr;
struct CharSet
{
CharSet();
~CharSet();
CharPtn *fix;
CharPtn *freeHead, **freeTail;
CharPtr *rep;
CharPtn *ptn;
};
class Range
{
public:
Range *next;
uint lb, ub; // [lb,ub)
static free_list<Range*> vFreeList;
public:
Range(uint l, uint u) : next(NULL), lb(l), ub(u)
{
vFreeList.insert(this);
}
Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
{
vFreeList.insert(this);
}
friend std::ostream& operator<<(std::ostream&, const Range&);
friend std::ostream& operator<<(std::ostream&, const Range*);
};
inline std::ostream& operator<<(std::ostream &o, const Range *r)
{
return r ? o << *r : o;
}
class RegExp
{
public:
uint size;
static free_list<RegExp*> vFreeList;
public:
RegExp() : size(0)
{
}
virtual ~RegExp()
{
vFreeList.erase(this);
}
virtual const char *typeOf() = 0;
RegExp *isA(const char *t)
{
return typeOf() == t ? this : NULL;
}
virtual void split(CharSet&) = 0;
virtual void calcSize(Char*) = 0;
virtual uint fixedLength();
virtual void compile(Char*, Ins*) = 0;
virtual void display(std::ostream&) const = 0;
friend std::ostream& operator<<(std::ostream&, const RegExp&);
friend std::ostream& operator<<(std::ostream&, const RegExp*);
};
inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
{
re.display(o);
return o;
}
inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
{
return o << *re;
}
class NullOp: public RegExp
{
public:
static const char *type;
public:
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << "_";
}
};
class MatchOp: public RegExp
{
public:
static const char *type;
Range *match;
public:
MatchOp(Range *m) : match(m)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream&) const;
#ifdef PEDANTIC
private:
MatchOp(const MatchOp& oth)
: RegExp(oth)
, match(oth.match)
{
}
MatchOp& operator = (const MatchOp& oth)
{
new(this) MatchOp(oth);
return *this;
}
#endif
};
class RuleOp: public RegExp
{
public:
static const char *type;
private:
RegExp *exp;
public:
RegExp *ctx;
Ins *ins;
uint accept;
Token *code;
uint line;
public:
RuleOp(RegExp*, RegExp*, Token*, uint);
~RuleOp()
{
delete code;
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp << "/" << ctx << ";";
}
#ifdef PEDANTIC
private:
RuleOp(const RuleOp& oth)
: RegExp(oth)
, exp(oth.exp)
, ctx(oth.ctx)
, ins(oth.ins)
, accept(oth.accept)
, code(oth.code)
, line(oth.line)
{
}
RuleOp& operator = (const RuleOp& oth)
{
new(this) RuleOp(oth);
return *this;
}
#endif
};
class RuleLine: public line_number
{
public:
RuleLine(const RuleOp& _op)
: op(_op)
{
}
uint get_line() const
{
return op.code->line;
}
const RuleOp& op;
};
RegExp *mkAlt(RegExp*, RegExp*);
class AltOp: public RegExp
{
private:
RegExp *exp1, *exp2;
public:
static const char *type;
public:
AltOp(RegExp *e1, RegExp *e2)
: exp1(e1)
, exp2(e2)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp1 << "|" << exp2;
}
friend RegExp *mkAlt(RegExp*, RegExp*);
#ifdef PEDANTIC
private:
AltOp(const AltOp& oth)
: RegExp(oth)
, exp1(oth.exp1)
, exp2(oth.exp2)
{
}
AltOp& operator = (const AltOp& oth)
{
new(this) AltOp(oth);
return *this;
}
#endif
};
class CatOp: public RegExp
{
private:
RegExp *exp1, *exp2;
public:
static const char *type;
public:
CatOp(RegExp *e1, RegExp *e2)
: exp1(e1)
, exp2(e2)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp1 << exp2;
}
#ifdef PEDANTIC
private:
CatOp(const CatOp& oth)
: RegExp(oth)
, exp1(oth.exp1)
, exp2(oth.exp2)
{
}
CatOp& operator = (const CatOp& oth)
{
new(this) CatOp(oth);
return *this;
}
#endif
};
class CloseOp: public RegExp
{
private:
RegExp *exp;
public:
static const char *type;
public:
CloseOp(RegExp *e)
: exp(e)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp << "+";
}
#ifdef PEDANTIC
private:
CloseOp(const CloseOp& oth)
: RegExp(oth)
, exp(oth.exp)
{
}
CloseOp& operator = (const CloseOp& oth)
{
new(this) CloseOp(oth);
return *this;
}
#endif
};
class CloseVOp: public RegExp
{
private:
RegExp *exp;
int min;
int max;
public:
static const char *type;
public:
CloseVOp(RegExp *e, int lb, int ub)
: exp(e)
, min(lb)
, max(ub)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp << "+";
}
#ifdef PEDANTIC
private:
CloseVOp(const CloseVOp& oth)
: RegExp(oth)
, exp(oth.exp)
, min(oth.min)
, max(oth.max)
{
}
CloseVOp& operator = (const CloseVOp& oth)
{
new(this) CloseVOp(oth);
return *this;
}
#endif
};
extern void genCode(std::ostream&, RegExp*);
extern void genCode(std::ostream&, uint, RegExp*);
extern void genGetState(std::ostream&, uint&, uint);
extern RegExp *mkDiff(RegExp*, RegExp*);
extern RegExp *mkAlt(RegExp*, RegExp*);
} // end namespace re2c
#endif
typedef struct extop
{
char op;
int minsize;
int maxsize;
}
ExtOp;
struct CharPtn
{
uint card;
CharPtn *fix;
CharPtn *nxt;
};
typedef CharPtn *CharPtr;
struct CharSet
{
CharSet();
~CharSet();
CharPtn *fix;
CharPtn *freeHead, **freeTail;
CharPtr *rep;
CharPtn *ptn;
};
class Range
{
public:
Range *next;
uint lb, ub; // [lb,ub)
static free_list<Range*> vFreeList;
public:
Range(uint l, uint u) : next(NULL), lb(l), ub(u)
{
vFreeList.insert(this);
}
Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
{
vFreeList.insert(this);
}
~Range()
{
vFreeList.erase(this);
}
friend std::ostream& operator<<(std::ostream&, const Range&);
friend std::ostream& operator<<(std::ostream&, const Range*);
};
inline std::ostream& operator<<(std::ostream &o, const Range *r)
{
return r ? o << *r : o;
}
class RegExp
{
public:
uint size;
static free_list<RegExp*> vFreeList;
public:
RegExp() : size(0)
{
vFreeList.insert(this);
}
virtual ~RegExp()
{
vFreeList.erase(this);
}
virtual const char *typeOf() = 0;
RegExp *isA(const char *t)
{
return typeOf() == t ? this : NULL;
}
virtual void split(CharSet&) = 0;
virtual void calcSize(Char*) = 0;
virtual uint fixedLength();
virtual void compile(Char*, Ins*) = 0;
virtual void display(std::ostream&) const = 0;
friend std::ostream& operator<<(std::ostream&, const RegExp&);
friend std::ostream& operator<<(std::ostream&, const RegExp*);
};
inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
{
re.display(o);
return o;
}
inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
{
return o << *re;
}
class NullOp: public RegExp
{
public:
static const char *type;
public:
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << "_";
}
};
class MatchOp: public RegExp
{
public:
static const char *type;
Range *match;
public:
MatchOp(Range *m) : match(m)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream&) const;
#ifdef PEDANTIC
private:
MatchOp(const MatchOp& oth)
: RegExp(oth)
, match(oth.match)
{
}
MatchOp& operator = (const MatchOp& oth)
{
new(this) MatchOp(oth);
return *this;
}
#endif
};
class RuleOp: public RegExp
{
public:
static const char *type;
private:
RegExp *exp;
public:
RegExp *ctx;
Ins *ins;
uint accept;
Token *code;
uint line;
public:
RuleOp(RegExp*, RegExp*, Token*, uint);
~RuleOp()
{
delete code;
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp << "/" << ctx << ";";
}
#ifdef PEDANTIC
private:
RuleOp(const RuleOp& oth)
: RegExp(oth)
, exp(oth.exp)
, ctx(oth.ctx)
, ins(oth.ins)
, accept(oth.accept)
, code(oth.code)
, line(oth.line)
{
}
RuleOp& operator = (const RuleOp& oth)
{
new(this) RuleOp(oth);
return *this;
}
#endif
};
class RuleLine: public line_number
{
public:
RuleLine(const RuleOp& _op)
: op(_op)
{
}
uint get_line() const
{
return op.code->line;
}
const RuleOp& op;
};
RegExp *mkAlt(RegExp*, RegExp*);
class AltOp: public RegExp
{
private:
RegExp *exp1, *exp2;
public:
static const char *type;
public:
AltOp(RegExp *e1, RegExp *e2)
: exp1(e1)
, exp2(e2)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp1 << "|" << exp2;
}
friend RegExp *mkAlt(RegExp*, RegExp*);
#ifdef PEDANTIC
private:
AltOp(const AltOp& oth)
: RegExp(oth)
, exp1(oth.exp1)
, exp2(oth.exp2)
{
}
AltOp& operator = (const AltOp& oth)
{
new(this) AltOp(oth);
return *this;
}
#endif
};
class CatOp: public RegExp
{
private:
RegExp *exp1, *exp2;
public:
static const char *type;
public:
CatOp(RegExp *e1, RegExp *e2)
: exp1(e1)
, exp2(e2)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
uint fixedLength();
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp1 << exp2;
}
#ifdef PEDANTIC
private:
CatOp(const CatOp& oth)
: RegExp(oth)
, exp1(oth.exp1)
, exp2(oth.exp2)
{
}
CatOp& operator = (const CatOp& oth)
{
new(this) CatOp(oth);
return *this;
}
#endif
};
class CloseOp: public RegExp
{
private:
RegExp *exp;
public:
static const char *type;
public:
CloseOp(RegExp *e)
: exp(e)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp << "+";
}
#ifdef PEDANTIC
private:
CloseOp(const CloseOp& oth)
: RegExp(oth)
, exp(oth.exp)
{
}
CloseOp& operator = (const CloseOp& oth)
{
new(this) CloseOp(oth);
return *this;
}
#endif
};
class CloseVOp: public RegExp
{
private:
RegExp *exp;
int min;
int max;
public:
static const char *type;
public:
CloseVOp(RegExp *e, int lb, int ub)
: exp(e)
, min(lb)
, max(ub)
{
}
const char *typeOf()
{
return type;
}
void split(CharSet&);
void calcSize(Char*);
void compile(Char*, Ins*);
void display(std::ostream &o) const
{
o << exp << "+";
}
#ifdef PEDANTIC
private:
CloseVOp(const CloseVOp& oth)
: RegExp(oth)
, exp(oth.exp)
, min(oth.min)
, max(oth.max)
{
}
CloseVOp& operator = (const CloseVOp& oth)
{
new(this) CloseVOp(oth);
return *this;
}
#endif
};
extern void genCode(std::ostream&, RegExp*);
extern void genCode(std::ostream&, uint, RegExp*);
extern void genGetState(std::ostream&, uint&, uint);
extern RegExp *mkDiff(RegExp*, RegExp*);
extern RegExp *mkAlt(RegExp*, RegExp*);
} // end namespace re2c
#endif

View file

@ -1,7 +1,7 @@
./"
./" $Id: re2c.1.in 523 2006-05-25 13:32:09Z helly $
./" $Id: re2c.1.in 663 2007-04-01 11:22:15Z helly $
./"
.TH RE2C 1 "22 April 2005" "Version 0.10.5"
.TH RE2C 1 "22 April 2005" "Version 0.12.3"
.ds re \fBre2c\fP
.ds le \fBlex\fP
.ds rx regular expression
@ -10,7 +10,7 @@
re2c \- convert regular expressions to C/C++
.SH SYNOPSIS
\*(re [\fB-bdefghisvVw1\fP] [\fB-o output\fP] file\fP
\*(re [\fB-bdefghisuvVw1\fP] [\fB-o output\fP] file\fP
.SH DESCRIPTION
\*(re is a preprocessor that generates C-based recognizers from regular
@ -26,61 +26,51 @@ For example, given the following code
.in +3
.nf
#define NULL ((char*) 0)
char *scan(char *p)
{
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT p
#define YYFILL(n)
/*!re2c
[0-9]+ {return YYCURSOR;}
[\\000-\\377] {return NULL;}
re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = p;
re2c:yyfill:enable = 0;
re2c:yych:conversion = 1;
re2c:indent:top = 1;
[0-9]+ {return p;}
[\000-\377] {return (char*)0;}
*/
}
.fi
.in -3
\*(re will generate
\*(re -is will generate
.in +3
.nf
/* Generated by re2c on Sat Apr 16 11:40:58 1994 */
#line 1 "simple.re"
#define NULL ((char*) 0)
char *scan(char *p)
{
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT p
#define YYFILL(n)
{
YYCTYPE yych;
unsigned int yyaccept;
goto yy0;
yy1: ++YYCURSOR;
yy0:
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if(yych <= '/') goto yy4;
if(yych >= ':') goto yy4;
yy2: yych = *++YYCURSOR;
{
unsigned char yych;
yych = (unsigned char)*p;
if(yych &lt;= '/') goto yy4;
if(yych &gt;= ':') goto yy4;
++p;
yych = (unsigned char)*p;
goto yy7;
yy3:
#line 9
{return YYCURSOR;}
yy4: yych = *++YYCURSOR;
yy5:
#line 10
{return NULL;}
yy6: ++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy7: if(yych <= '/') goto yy3;
if(yych <= '9') goto yy6;
{return p;}
yy4:
++p;
yych = (unsigned char)*p;
{return char*)0;}
yy6:
++p;
yych = (unsigned char)*p;
yy7:
if(yych &lt;= '/') goto yy3;
if(yych &lt;= '9') goto yy6;
goto yy3;
}
#line 11
}
}
.fi
@ -123,7 +113,7 @@ Generate a scanner with support for storable state.
For details see below at \fBSCANNER WITH STORABLE STATES\fP.
.TP
\fB-g\fP
Generate a scanner that utilizes GCC's computed goto feature. That is re2c
Generate a scanner that utilizes GCC's computed goto feature. That is \*(re
generates jump tables whenever a decision is of a certain complexity (e.g. a
lot of if conditions are otherwise necessary). This is only useable with GCC
and produces output that cannot be compiled with any other compiler. Note that
@ -132,8 +122,8 @@ inplace configuration "cgoto:threshold".
.TP
\fB-i\fP
Do not output #line information. This is usefull when you want use a CMS tool
with the re2c output which you might want if you do not require your users to
have re2c themselves when building from your source.
with the \*(re output which you might want if you do not require your users to
have \*(re themselves when building from your source.
\fB-o output\fP
Specify the output file.
.TP
@ -141,6 +131,12 @@ Specify the output file.
Generate nested \fCif\fPs for some \fCswitch\fPes. Many compilers need this
assist to generate better code.
.TP
\fB-u\fP
Generate a parser that supports Unicode chars (UTF-32). This means the
generated code can deal with any valid Unicode character up to 0x10FFFF. When
UTF-8 or UTF-16 needs to be supported you need to convert the incoming stream
to UTF-32 upon input yourself.
.TP
\fB-v\fP
Show version information.
.TP
@ -153,11 +149,16 @@ cannot be used together with \fB-e\fP switch.
.TP
\fB-1\fP
Force single pass generation, this cannot be combined with -f and disables
YYMAXFILL generation prior to last re2c block.
YYMAXFILL generation prior to last \*(re block.
.TP
\fb--no-generation-date\fP
Suppress date output in the generated output so that it only shows the re2c
version.
.SH "INTERFACE CODE"
Unlike other scanner generators, \*(re does not generate complete scanners:
the user must supply some interface code.
In particular, the user must define the following macros:
In particular, the user must define the following macros or use the
corresponding inplace configurations:
.TP
\fCYYCTYPE\fP
Type used to hold an input symbol.
@ -187,26 +188,27 @@ The generated code saves trailing context backtracking information in \fCYYCTXMA
The user only needs to define this macro if a scanner specification uses trailing
context in one or more of its regular expressions.
.TP
\fCYYFILL(\fP\fIn\fP\fC)\fP
\fCYYFILL\fP(\fIn\fP\fC\fP)
The generated code "calls" \fCYYFILL\fP(n) when the buffer needs
(re)filling: at least \fIn\fP additional characters should
be provided. \fCYYFILL\fP(n) should adjust \fCYYCURSOR\fP, \fCYYLIMIT\fP,
\fCYYMARKER\fP and \fCYYCTXMARKER\fP as needed. Note that for typical
programming languages \fIn\fP will be the length of the longest keyword plus one.
The user can place a comment of the form \fC/*!max:re2c */\fP once to insert
a \fCYYMAXFILL\fP definition that is set to the maximum length value. If -1
switch is used then YYMAXFILL can be triggered once after the last \fC/*!re2c */\fP
a \fCYYMAXFILL\fP(n) definition that is set to the maximum length value. If -1
switch is used then \fCYYMAXFILL\fP can be triggered only once after the
last \fC/*!re2c */\fP
block.
.TP
\fCYYGETSTATE()\fP
\fCYYGETSTATE\fP()
The user only needs to define this macro if the \fB-f\fP flag was specified.
In that case, the generated code "calls" \fCYYGETSTATE\fP at the very beginning
of the scanner in order to obtain the saved state. YYGETSTATE must return a signed
In that case, the generated code "calls" \fCYYGETSTATE\fP() at the very beginning
of the scanner in order to obtain the saved state. \fCYYGETSTATE\fP() must return a signed
integer. The value must be either -1, indicating that the scanner is entered for the
first time, or a value previously saved by \fCYYSETSTATE\fP. In the second case, the
first time, or a value previously saved by \fCYYSETSTATE\fP(s). In the second case, the
scanner will resume operations right after where the last \fCYYFILL\fP(n) was called.
.TP
\fCYYSETSTATE(\fP\fIn\fP\fC)\fP
\fCYYSETSTATE(\fP\fIs\fP\fC)\fP
The user only needs to define this macro if the \fB-f\fP flag was specified.
In that case, the generated code "calls" \fCYYSETSTATE\fP just before calling
\fCYYFILL\fP(n). The parameter to \fCYYSETSTATE\fP is a signed integer that uniquely
@ -214,7 +216,9 @@ identifies the specific instance of \fCYYFILL\fP(n) that is about to be called.
Should the user wish to save the state of the scanner and have \fCYYFILL\fP(n) return
to the caller, all he has to do is store that unique identifer in a variable.
Later, when the scannered is called again, it will call \fCYYGETSTATE()\fP and
resume execution right where it left off.
resume execution right where it left off. The generated code will contain
both \fCYYSETSTATE\fP(s) and \fCYYGETSTATE\fP even if \fCYYFILL\fP(n) is being
disabled.
.TP
\fCYYDEBUG(\fP\fIstate\fP,\fIcurrent\fC)\fP
This is only needed if the \fB-d\fP flag was specified. It allows to easily debug
@ -227,11 +231,11 @@ input at the current cursor.
This will be automatically defined by \fC/*!max:re2c */\fP blocks as explained above.
.SH "SCANNER WITH STORABLE STATES"
When the \fB-f\fP flag is specified, re2c generates a scanner that
When the \fB-f\fP flag is specified, \*(re generates a scanner that
can store its current state, return to the caller, and later resume
operations exactly where it left off.
The default operation of re2c is a "pull" model, where the scanner asks
The default operation of \*(re is a "pull" model, where the scanner asks
for extra input whenever it needs it. However, this mode of operation
assumes that the scanner is the "owner" the parsing loop, and that may
not always be convenient.
@ -246,9 +250,9 @@ chunk by chunk. When the scanner runs out of data to consume, it just stores
its state, and return to the caller. When more input data is fed to the scanner,
it resumes operations exactly where it left off.
When using the -f option re2c does not accept stdin because it has to do the
When using the -f option \*(re does not accept stdin because it has to do the
full generation process twice which means it has to read the input twice. That
means re2c would fail in case it cannot open the input twice or reading the
means \*(re would fail in case it cannot open the input twice or reading the
input for the first time influences the second read attempt.
Changes needed compared to the "pull" model.
@ -286,7 +290,7 @@ Please see examples/push.re for push-model scanner. The generated code can be
tweaked using inplace configurations "\fBstate:abort\fP" and "\fBstate:nextlabel\fP".
.SH "SCANNER SPECIFICATIONS"
Each scanner specification consists of a set of \fIrules\fP, \fIname
Each scanner specification consists of a set of \fIrules\fP, \fInamed
definitions\fP and \fIconfigurations\fP.
.LP
\fIRules\fP consist of a regular expression along with a block of C/C++ code that
@ -302,12 +306,15 @@ Named definitions are of the form:
\fIname\fP \fC=\fP \fIregular expression\fP\fC;\fP
.RE
.LP
Configurations look like name definitions whose names start
Configurations look like named definitions whose names start
with "\fBre2c:\fP":
.P
.RS
\fCre2c:\fP\fIname\fP \fC=\fP \fIvalue\fP\fC;\fP
.RE
.RS
\fCre2c:\fP\fIname\fP \fC=\fP \fB"\fP\fIvalue\fP\fB"\fP\fC;\fP
.RE
.SH "SUMMARY OF RE2C REGULAR EXPRESSIONS"
.TP
@ -345,7 +352,7 @@ one or more \fIr\fP's
zero or one \fIr\fP's (that is, "an optional \fIr\fP")
.TP
name
the expansion of the "name" definition (see above)
the expansion of the "named definition" (see above)
.TP
\fC(\fP\fIr\fP\fC)\fP
an \fIr\fP; parentheses are used to override precedence
@ -385,12 +392,10 @@ and a hexadecimal character is defined by backslash, a lower cased '\fBx\fP'
and its two hexadecimal digits or a backslash, an upper cased \fBX\fP and its
four hexadecimal digits.
.LP
re2c
further more supports the c/c++ unicode notation. That is a backslash followed
\*(re further more supports the c/c++ unicode notation. That is a backslash followed
by either a lowercased \fBu\fP and its four hexadecimal digits or an uppercased
\fBU\fP and its eight hexadecimal digits. However using the U notation it is
not possible to support characters greater \fB\\U0000FFFF\fP due to an internal
limitation of re2c.
\fBU\fP and its eight hexadecimal digits. However only in \fB-u\fP mode the
generated code can deal with any valid Unicode character up to 0x10FFFF.
.LP
Since characters greater \fB\\X00FF\fP are not allowed in non unicode mode, the
only portable "\fBany\fP" rules are \fB(.|"\\n")\fP and \fB[^]\fP.
@ -401,7 +406,7 @@ Those grouped together have equal precedence.
.SH "INPLACE CONFIGURATION"
.LP
It is possible to configure code generation inside re2c blocks. The following
It is possible to configure code generation inside \*(re blocks. The following
lists the available configurations:
.TP
\fIre2c:indent:top\fP \fB=\fP 0 \fB;\fP
@ -423,6 +428,12 @@ Set this to zero to suppress generation of YYFILL(n). When using this be sure
to verify that the generated scanner does not read behind input. Allowing
this behavior might introduce sever security issues to you programs.
.TP
\fIre2c:yyfill:parameter\fP \fB=\fP 1 \fB;\fP
Allows to suppress parameter passing to \fBYYFILL\fP calls. If set to zero
then no parameter is passed to \fBYYFILL\fP. If set to a non zero value then
\fBYYFILL\fP usage will be followed by the number of requested characters in
braces.
.TP
\fIre2c:startlabel\fP \fB=\fP 0 \fB;\fP
If set to a non zero integer then the start label of the next scanner blocks
will be generated even if not used by the scanner itself. Otherwise the normal
@ -431,6 +442,10 @@ value then a label with that text will be generated regardless of whether the
normal start label is being used or not. This setting is being reset to \fB0\fP
after a start label has been generated.
.TP
\fIre2c:labelprefix\fP \fB=\fP yy \fB;\fP
Allows to change the prefix of numbered labels. The default is \fByy\fP and
can be set any string that is a valid label.
.TP
\fIre2c:state:abort\fP \fB=\fP 0 \fB;\fP
When not zero and switch -f is active then the \fCYYGETSTATE\fP block will
contain a default case that aborts and a -1 case is used for initialization.
@ -448,11 +463,77 @@ When -g is active this value specifies the complexity threshold that triggers
generation of jump tables rather than using nested if's and decision bitfields.
The threshold is compared against a calculated estimation of if-s needed where
every used bitmap divides the threshold by 2.
.TP
\fIre2c:yych:conversion\fP \fB=\fP 0 \fB;\fP
When the input uses signed characters and \fB-s\fP or \fB-b\fP switches are
in effect re2c allows to automatically convert to the unsigned character type
that is then necessary for its internal single character. When this setting
is zero or an empty string the conversion is disabled. Using a non zero number
the conversion is taken from \fBYYCTYPE\fP. If that is given by an inplace
configuration that value is being used. Otherwise it will be \fB(YYCTYPE)\fP
and changes to that configuration are no longer possible. When this setting is
a string the braces must be specified. Now assuming your input is a \fBchar*\fP
buffer and you are using above mentioned switches you can set \fBYYCTYPE\fP to
\fBunsigned char\fP and this setting to either \fB1\fP or \fB"(unsigned char)"\fP.
.TP
\fIre2c:define:YYCTXMARKER\fP \fB=\fP YYCTXMARKER \fB;\fP
Allows to overwrite the define YYCTXMARKER and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYCTYPE\fP \fB=\fP YYCTYPE \fB;\fP
Allows to overwrite the define YYCTYPE and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYCURSOR\fP \fB=\fP YYCURSOR \fB;\fP
Allows to overwrite the define YYCURSOR and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYDEBUG\fP \fB=\fP YYDEBUG \fB;\fP
Allows to overwrite the define YYDEBUG and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYFILL\fP \fB=\fP YYFILL \fB;\fP
Allows to overwrite the define YYFILL and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYGETSTATE\fP \fB=\fP YYGETSTATE \fB;\fP
Allows to overwrite the define YYGETSTATE and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYLIMIT\fP \fB=\fP YYLIMIT \fB;\fP
Allows to overwrite the define YYLIMIT and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYMARKER\fP \fB=\fP YYMARKER \fB;\fP
Allows to overwrite the define YYMARKER and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:define:YYSETSTATE\fP \fB=\fP YYSETSTATE \fB;\fP
Allows to overwrite the define YYSETSTATE and thus avoiding it by setting the
value to the actual code needed.
.TP
\fIre2c:label:yyFillLabel\fP \fB=\fP yyFillLabel \fB;\fP
Allows to overwrite the name of the label yyFillLabel.
.TP
\fIre2c:label:yyNext\fP \fB=\fP yyNext \fB;\fP
Allows to overwrite the name of the label yyNext.
.TP
\fIre2c:variable:yyaccept\fP \fB=\fP yyaccept \fB;\fP
Allows to overwrite the name of the variable yyaccept.
.TP
\fIre2c:variable:yybm\fP \fB=\fP yybm \fB;\fP
Allows to overwrite the name of the variable yybm.
.TP
\fIre2c:variable:yych\fP \fB=\fP yych \fB;\fP
Allows to overwrite the name of the variable yych.
.TP
\fIre2c:variable:yytarget\fP \fB=\fP yytarget \fB;\fP
Allows to overwrite the name of the variable yytarget.
.SH "UNDERSTANDING RE2C"
.LP
The subdirectory lessons of the re2c distribution contains a few step by step
lessons to get you started with re2c. All examples in the lessons subdirectory
The subdirectory lessons of the \*(re distribution contains a few step by step
lessons to get you started with \*(re. All examples in the lessons subdirectory
can be compiled and actually work.
.SH FEATURES
@ -487,10 +568,10 @@ The \*(re internal algorithms need documentation.
.LP
flex(1), lex(1).
.P
More information on \fBre2c\fP can be found here:
More information on \*(re can be found here:
.PD 0
.P
.B http://sourceforge.net/projects/re2c/
.B http://re2c.org/
.PD 1
.SH AUTHORS
@ -511,6 +592,6 @@ Emmanuel Mogenet <mgix@mgix.com> added storable state
.PD 1
.SH VERSION INFORMATION
This manpage describes \fBre2c\fP, version 0.10.5.
This manpage describes \*(re, version 0.12.3.
.fi

File diff suppressed because it is too large Load diff

View file

@ -1,373 +1,373 @@
/* $Id:$ */
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include "scanner.h"
#include "parser.h"
#include "y.tab.h"
#include "globals.h"
#include "dfa.h"
extern YYSTYPE yylval;
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
#define BSIZE 8192
#define YYCTYPE unsigned char
#define YYCURSOR cursor
#define YYLIMIT lim
#define YYMARKER ptr
#define YYFILL(n) {cursor = fill(cursor);}
#define RETURN(i) {cur = cursor; return i;}
namespace re2c
{
Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o)
: in(i)
, out(o)
, bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
, top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn)
{
;
}
char *Scanner::fill(char *cursor)
{
if(!eof)
{
uint cnt = tok - bot;
if(cnt)
{
memcpy(bot, tok, lim - tok);
tok = bot;
ptr -= cnt;
cursor -= cnt;
pos -= cnt;
lim -= cnt;
}
if((top - lim) < BSIZE)
{
char *buf = new char[(lim - bot) + BSIZE];
memcpy(buf, tok, lim - tok);
tok = buf;
ptr = &buf[ptr - bot];
cursor = &buf[cursor - bot];
pos = &buf[pos - bot];
lim = &buf[lim - bot];
top = &lim[BSIZE];
delete [] bot;
bot = buf;
}
in.read(lim, BSIZE);
if ((cnt = in.gcount()) != BSIZE )
{
eof = &lim[cnt]; *eof++ = '\0';
}
lim += cnt;
}
return cursor;
}
/*!re2c
zero = "\000";
any = [\000-\377];
dot = any \ [\n];
esc = dot \ [\\];
istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ;
cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ;
dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\"";
sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ;
letter = [a-zA-Z];
digit = [0-9];
number = "0" | ("-"? [1-9] digit*);
/* $Id: scanner.re 663 2007-04-01 11:22:15Z helly $ */
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include "scanner.h"
#include "parser.h"
#include "y.tab.h"
#include "globals.h"
#include "dfa.h"
extern YYSTYPE yylval;
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
#define BSIZE 8192
#define YYCTYPE unsigned char
#define YYCURSOR cursor
#define YYLIMIT lim
#define YYMARKER ptr
#define YYFILL(n) {cursor = fill(cursor);}
#define RETURN(i) {cur = cursor; return i;}
namespace re2c
{
Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o)
: in(i)
, out(o)
, bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
, top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn)
{
;
}
char *Scanner::fill(char *cursor)
{
if(!eof)
{
uint cnt = tok - bot;
if(cnt)
{
memcpy(bot, tok, lim - tok);
tok = bot;
ptr -= cnt;
cursor -= cnt;
pos -= cnt;
lim -= cnt;
}
if((top - lim) < BSIZE)
{
char *buf = new char[(lim - bot) + BSIZE];
memcpy(buf, tok, lim - tok);
tok = buf;
ptr = &buf[ptr - bot];
cursor = &buf[cursor - bot];
pos = &buf[pos - bot];
lim = &buf[lim - bot];
top = &lim[BSIZE];
delete [] bot;
bot = buf;
}
in.read(lim, BSIZE);
if ((cnt = in.gcount()) != BSIZE )
{
eof = &lim[cnt]; *eof++ = '\0';
}
lim += cnt;
}
return cursor;
}
/*!re2c
zero = "\000";
any = [\000-\377];
dot = any \ [\n];
esc = dot \ [\\];
istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ;
cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ;
dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\"";
sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ;
letter = [a-zA-Z];
digit = [0-9];
number = "0" | ("-"? [1-9] digit*);
name = (letter|"_") (letter|digit|"_")*;
cname = ":" name;
space = [ \t];
eol = ("\r\n" | "\n");
config = "re2c" cname+;
value = [^\r\n; \t]* | dstring | sstring;
*/
int Scanner::echo()
{
char *cursor = cur;
bool ignore_eoc = false;
int ignore_cnt = 0;
if (eof && cursor == eof) // Catch EOF
{
return 0;
}
tok = cursor;
echo:
/*!re2c
"/*!re2c" {
if (bUsedYYMaxFill && bSinglePass) {
fatal("found scanner block after YYMAXFILL declaration");
}
out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok));
tok = cursor;
RETURN(1);
}
"/*!max:re2c" {
if (bUsedYYMaxFill) {
fatal("cannot generate YYMAXFILL twice");
}
out << "#define YYMAXFILL " << maxFill << std::endl;
tok = pos = cursor;
ignore_eoc = true;
bUsedYYMaxFill = true;
goto echo;
}
"/*!getstate:re2c" {
tok = pos = cursor;
genGetState(out, topIndent, 0);
ignore_eoc = true;
goto echo;
}
"/*!ignore:re2c" {
tok = pos = cursor;
ignore_eoc = true;
goto echo;
}
"*" "/" "\r"? "\n" {
cline++;
if (ignore_eoc) {
if (ignore_cnt) {
out << sourceFileInfo;
}
ignore_eoc = false;
ignore_cnt = 0;
} else {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
}
tok = pos = cursor;
goto echo;
}
"*" "/" {
if (ignore_eoc) {
if (ignore_cnt) {
out << "\n" << sourceFileInfo;
}
ignore_eoc = false;
ignore_cnt = 0;
} else {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
}
tok = pos = cursor;
goto echo;
}
"\n" {
if (ignore_eoc) {
ignore_cnt++;
} else {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
}
tok = pos = cursor; cline++;
goto echo;
}
zero {
if (!ignore_eoc) {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0
}
if(cursor == eof) {
RETURN(0);
}
}
any {
goto echo;
}
*/
}
int Scanner::scan()
{
char *cursor = cur;
uint depth;
scan:
tchar = cursor - pos;
tline = cline;
tok = cursor;
if (iscfg == 1)
{
goto config;
}
else if (iscfg == 2)
{
goto value;
}
/*!re2c
"{" { depth = 1;
goto code;
}
"/*" { depth = 1;
goto comment; }
"*/" { tok = cursor;
RETURN(0); }
dstring { cur = cursor;
yylval.regexp = strToRE(token());
return STRING; }
sstring { cur = cursor;
yylval.regexp = strToCaseInsensitiveRE(token());
return STRING; }
"\"" { fatal("unterminated string constant (missing \")"); }
"'" { fatal("unterminated string constant (missing ')"); }
istring { cur = cursor;
yylval.regexp = invToRE(token());
return RANGE; }
cstring { cur = cursor;
yylval.regexp = ranToRE(token());
return RANGE; }
"[" { fatal("unterminated range (missing ])"); }
[()|=;/\\] { RETURN(*tok); }
[*+?] { yylval.op = *tok;
RETURN(CLOSE); }
"{0,}" { yylval.op = '*';
RETURN(CLOSE); }
"{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = atoi((char *)tok+1);
RETURN(CLOSESIZE); }
"{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
RETURN(CLOSESIZE); }
"{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = -1;
RETURN(CLOSESIZE); }
"{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
config { cur = cursor;
tok+= 5; /* skip "re2c:" */
iscfg = 1;
yylval.str = new Str(token());
return CONFIG;
}
name { cur = cursor;
yylval.symbol = Symbol::find(token());
return ID; }
"." { cur = cursor;
yylval.regexp = mkDot();
return RANGE;
}
space+ { goto scan; }
eol { if(cursor == eof) RETURN(0);
pos = cursor; cline++;
goto scan;
}
any { std::ostringstream msg;
msg << "unexpected character: ";
prtChOrHex(msg, *tok);
fatal(msg.str().c_str());
goto scan;
}
*/
code:
/*!re2c
"}" { if(--depth == 0){
cur = cursor;
yylval.token = new Token(token(), tline);
return CODE;
}
goto code; }
"{" { ++depth;
goto code; }
"\n" { if(cursor == eof) fatal("missing '}'");
pos = cursor; cline++;
goto code;
}
zero { if(cursor == eof) {
if (depth) fatal("missing '}'");
RETURN(0);
}
goto code;
}
dstring | sstring | any { goto code; }
*/
comment:
/*!re2c
"*/" { if(--depth == 0)
goto scan;
else
goto comment; }
"/*" { ++depth;
fatal("ambiguous /* found");
goto comment; }
"\n" { if(cursor == eof) RETURN(0);
tok = pos = cursor; cline++;
goto comment;
}
any { if(cursor == eof) RETURN(0);
goto comment; }
*/
config:
/*!re2c
space+ { goto config; }
"=" space* { iscfg = 2;
cur = cursor;
RETURN('=');
}
any { fatal("missing '='"); }
*/
value:
/*!re2c
number { cur = cursor;
yylval.number = atoi(token().to_string().c_str());
iscfg = 0;
return NUMBER;
}
value { cur = cursor;
yylval.str = new Str(token());
iscfg = 0;
return VALUE;
}
*/
}
void Scanner::fatal(uint ofs, const char *msg) const
{
out.flush();
#ifdef _MSC_VER
std::cerr << filename << "(" << tline << "): error : "
<< "column " << (tchar + ofs + 1) << ": "
<< msg << std::endl;
#else
std::cerr << "re2c: error: "
<< "line " << tline << ", column " << (tchar + ofs + 1) << ": "
<< msg << std::endl;
#endif
exit(1);
}
space = [ \t];
eol = ("\r\n" | "\n");
config = "re2c" cname+;
value = [^\r\n; \t]* | dstring | sstring;
*/
int Scanner::echo()
{
char *cursor = cur;
bool ignore_eoc = false;
int ignore_cnt = 0;
if (eof && cursor == eof) // Catch EOF
{
return 0;
}
tok = cursor;
echo:
/*!re2c
"/*!re2c" {
if (bUsedYYMaxFill && bSinglePass) {
fatal("found scanner block after YYMAXFILL declaration");
}
out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok));
tok = cursor;
RETURN(1);
}
"/*!max:re2c" {
if (bUsedYYMaxFill) {
fatal("cannot generate YYMAXFILL twice");
}
out << "#define YYMAXFILL " << maxFill << std::endl;
tok = pos = cursor;
ignore_eoc = true;
bUsedYYMaxFill = true;
goto echo;
}
"/*!getstate:re2c" {
tok = pos = cursor;
genGetState(out, topIndent, 0);
ignore_eoc = true;
goto echo;
}
"/*!ignore:re2c" {
tok = pos = cursor;
ignore_eoc = true;
goto echo;
}
"*" "/" "\r"? "\n" {
cline++;
if (ignore_eoc) {
if (ignore_cnt) {
out << sourceFileInfo;
}
ignore_eoc = false;
ignore_cnt = 0;
} else {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
}
tok = pos = cursor;
goto echo;
}
"*" "/" {
if (ignore_eoc) {
if (ignore_cnt) {
out << "\n" << sourceFileInfo;
}
ignore_eoc = false;
ignore_cnt = 0;
} else {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
}
tok = pos = cursor;
goto echo;
}
"\n" {
if (ignore_eoc) {
ignore_cnt++;
} else {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
}
tok = pos = cursor; cline++;
goto echo;
}
zero {
if (!ignore_eoc) {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0
}
if(cursor == eof) {
RETURN(0);
}
}
any {
goto echo;
}
*/
}
int Scanner::scan()
{
char *cursor = cur;
uint depth;
scan:
tchar = cursor - pos;
tline = cline;
tok = cursor;
if (iscfg == 1)
{
goto config;
}
else if (iscfg == 2)
{
goto value;
}
/*!re2c
"{" { depth = 1;
goto code;
}
"/*" { depth = 1;
goto comment; }
"*/" { tok = cursor;
RETURN(0); }
dstring { cur = cursor;
yylval.regexp = strToRE(token());
return STRING; }
sstring { cur = cursor;
yylval.regexp = strToCaseInsensitiveRE(token());
return STRING; }
"\"" { fatal("unterminated string constant (missing \")"); }
"'" { fatal("unterminated string constant (missing ')"); }
istring { cur = cursor;
yylval.regexp = invToRE(token());
return RANGE; }
cstring { cur = cursor;
yylval.regexp = ranToRE(token());
return RANGE; }
"[" { fatal("unterminated range (missing ])"); }
[()|=;/\\] { RETURN(*tok); }
[*+?] { yylval.op = *tok;
RETURN(CLOSE); }
"{0,}" { yylval.op = '*';
RETURN(CLOSE); }
"{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = atoi((char *)tok+1);
RETURN(CLOSESIZE); }
"{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
RETURN(CLOSESIZE); }
"{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = -1;
RETURN(CLOSESIZE); }
"{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
config { cur = cursor;
tok+= 5; /* skip "re2c:" */
iscfg = 1;
yylval.str = new Str(token());
return CONFIG;
}
name { cur = cursor;
yylval.symbol = Symbol::find(token());
return ID; }
"." { cur = cursor;
yylval.regexp = mkDot();
return RANGE;
}
space+ { goto scan; }
eol { if(cursor == eof) RETURN(0);
pos = cursor; cline++;
goto scan;
}
any { std::ostringstream msg;
msg << "unexpected character: ";
prtChOrHex(msg, *tok);
fatal(msg.str().c_str());
goto scan;
}
*/
code:
/*!re2c
"}" { if(--depth == 0){
cur = cursor;
yylval.token = new Token(token(), tline);
return CODE;
}
goto code; }
"{" { ++depth;
goto code; }
"\n" { if(cursor == eof) fatal("missing '}'");
pos = cursor; cline++;
goto code;
}
zero { if(cursor == eof) {
if (depth) fatal("missing '}'");
RETURN(0);
}
goto code;
}
dstring | sstring | any { goto code; }
*/
comment:
/*!re2c
"*/" { if(--depth == 0)
goto scan;
else
goto comment; }
"/*" { ++depth;
fatal("ambiguous /* found");
goto comment; }
"\n" { if(cursor == eof) RETURN(0);
tok = pos = cursor; cline++;
goto comment;
}
any { if(cursor == eof) RETURN(0);
goto comment; }
*/
config:
/*!re2c
space+ { goto config; }
"=" space* { iscfg = 2;
cur = cursor;
RETURN('=');
}
any { fatal("missing '='"); }
*/
value:
/*!re2c
number { cur = cursor;
yylval.number = atoi(token().to_string().c_str());
iscfg = 0;
return NUMBER;
}
value { cur = cursor;
yylval.str = new Str(token());
iscfg = 0;
return VALUE;
}
*/
}
void Scanner::fatal(uint ofs, const char *msg) const
{
out.flush();
#ifdef _MSC_VER
std::cerr << filename << "(" << tline << "): error : "
<< "column " << (tchar + ofs + 1) << ": "
<< msg << std::endl;
#else
std::cerr << "re2c: error: "
<< "line " << tline << ", column " << (tchar + ofs + 1) << ": "
<< msg << std::endl;
#endif
exit(1);
}
Scanner::~Scanner()
{
@ -376,6 +376,6 @@ Scanner::~Scanner()
delete [] bot;
}
}
} // end namespace re2c
} // end namespace re2c

View file

@ -2,7 +2,7 @@
Author: Marcus Boerger <helly@users.sourceforge.net>
*/
/* $Id: stream_lc.h,v 1.10 2006/02/26 20:36:09 helly Exp $ */
/* $Id: stream_lc.h 767 2007-06-26 15:21:10Z helly $ */
#ifndef _stream_lc_h
#define _stream_lc_h

View file

@ -1,4 +1,4 @@
/* $Id: substr.cc,v 1.11 2006/02/26 20:30:54 helly Exp $ */
/* $Id: substr.cc 546 2006-05-25 13:40:14Z helly $ */
#include <string.h>
#include <stdlib.h>
#include "substr.h"

View file

@ -1,4 +1,4 @@
/* $Id: substr.h,v 1.10 2006/01/01 13:42:10 helly Exp $ */
/* $Id: substr.h 530 2006-05-25 13:34:33Z helly $ */
#ifndef _substr_h
#define _substr_h

View file

@ -1,4 +1,4 @@
/* $Id: token.h,v 1.4 2004/11/01 04:35:57 nuffer Exp $ */
/* $Id: token.h 547 2006-05-25 13:40:35Z helly $ */
#ifndef _token_h
#define _token_h

View file

@ -1,4 +1,4 @@
/* $Id: translate.cc,v 1.5 2005/12/28 18:33:37 helly Exp $ */
/* $Id: translate.cc 713 2007-04-29 15:33:47Z helly $ */
#include "globals.h"
namespace re2c

View file

@ -250,7 +250,7 @@ int main (int argc, char **argv)
printf ("Usage: %s <source file> <output file>\n", argv[0]);
return -1;
}
#if !defined(NDEBUG) && 1
#if !defined(NDEBUG) && 0
ParseTrace(fopen("trace.txt", "w"), ":");
#endif
IncludeFile (argv[1]);

File diff suppressed because it is too large Load diff

View file

@ -10,27 +10,28 @@
#define SYMNUM 10
#define LPAREN 11
#define RPAREN 12
#define PRINT 13
#define COMMA 14
#define STRING 15
#define ENDL 16
#define DEFINE 17
#define SYM 18
#define INCLUDE 19
#define RBRACE 20
#define ENUM 21
#define LBRACE 22
#define EQUALS 23
#define SPECIAL 24
#define SEMICOLON 25
#define COLON 26
#define LBRACKET 27
#define RBRACKET 28
#define FLAGS 29
#define ARG2 30
#define ARG3 31
#define ARG4 32
#define ARG5 33
#define OR_EQUAL 34
#define TAG 35
#define LINEID 36
#define NOP 13
#define PRINT 14
#define COMMA 15
#define STRING 16
#define ENDL 17
#define DEFINE 18
#define SYM 19
#define INCLUDE 20
#define RBRACE 21
#define ENUM 22
#define LBRACE 23
#define EQUALS 24
#define SPECIAL 25
#define SEMICOLON 26
#define COLON 27
#define LBRACKET 28
#define RBRACKET 29
#define FLAGS 30
#define ARG2 31
#define ARG3 32
#define ARG4 33
#define ARG5 34
#define OR_EQUAL 35
#define TAG 36
#define LINEID 37

View file

@ -243,10 +243,33 @@ void yyparse (void)
void *pParser = ParseAlloc (malloc);
YYSTYPE token;
int tokentype;
int include_state = 0;
while ((tokentype = yylex(&token)) != 0)
{
/* Whenever the sequence INCLUDE STRING is encountered in the token
* stream, feed a dummy NOP token to the parser so that it will
* reduce the include_statement before grabbing any more tokens
* from the current file.
*/
if (tokentype == INCLUDE && include_state == 0)
{
include_state = 1;
}
else if (tokentype == STRING && include_state == 1)
{
include_state = 2;
}
else
{
include_state = 0;
}
Parse (pParser, tokentype, token);
if (include_state == 2)
{
include_state = 0;
Parse (pParser, NOP, token);
}
}
memset (&token, 0, sizeof(token));
Parse (pParser, 0, token);
@ -354,7 +377,7 @@ exp(A) ::= MINUS exp(B). [NEG] { A = -B; }
exp(A) ::= LPAREN exp(B) RPAREN. { A = B; }
translation_unit ::= . /* empty */
translation_unit ::= external_declaration.
translation_unit ::= translation_unit external_declaration.
external_declaration ::= define_statement.
external_declaration ::= include_statement.
@ -363,6 +386,7 @@ external_declaration ::= enum_statement.
external_declaration ::= linetype_declaration.
external_declaration ::= boom_declaration.
external_declaration ::= special_declaration.
external_declaration ::= NOP.
print_statement ::= PRINT LPAREN print_list RPAREN.
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -3696,7 +3696,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating $(InputName).h from src/$(InputFileName)"
CommandLine="tools\re2c\re2c -s -o &quot;src/$(InputName).h&quot; &quot;src/$(InputFileName)&quot;&#x0D;&#x0A;"
CommandLine="tools\re2c\re2c --no-generation-date -s -o &quot;src/$(InputName).h&quot; &quot;src/$(InputFileName)&quot;&#x0D;&#x0A;"
Outputs="&quot;src/$(InputName).h&quot;"
/>
</FileConfiguration>
@ -3716,7 +3716,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Creating $(InputName).h from src/$(InputFileName)"
CommandLine="tools\re2c\re2c -s -o &quot;src/$(InputName).h&quot; &quot;src/$(InputFileName)&quot;&#x0D;&#x0A;"
CommandLine="tools\re2c\re2c --no-generation-date -s -o &quot;src/$(InputName).h&quot; &quot;src/$(InputFileName)&quot;&#x0D;&#x0A;"
Outputs="&quot;src/$(InputName).h&quot;"
/>
</FileConfiguration>