mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 21:41:03 +00:00
- 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:
parent
e5572a1c4e
commit
ec17f5a5b9
46 changed files with 9134 additions and 8988 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -424,7 +424,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating scanner.c from scanner.re"
|
||||
CommandLine="..\re2c\re2c -s -o "scanner.c" "$(InputFileName)"
"
|
||||
CommandLine="..\re2c\re2c -s --no-generation-date -o "scanner.c" "$(InputFileName)"
"
|
||||
Outputs="$(InputDir)scanner.c"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
@ -444,7 +444,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating scanner.c from scanner.re"
|
||||
CommandLine="..\re2c\re2c -s -o "scanner.c" "$(InputFileName)"
"
|
||||
CommandLine="..\re2c\re2c -s --no-generation-date -o "scanner.c" "$(InputFileName)"
"
|
||||
Outputs="$(InputDir)scanner.c"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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); }
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
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++;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -350,9 +350,7 @@ static int yy_find_shift_action(
|
|||
if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
|
||||
return yy_default[stateno];
|
||||
}
|
||||
if( iLookAhead==YYNOCODE ){
|
||||
return YY_NO_ACTION;
|
||||
}
|
||||
assert( iLookAhead!=YYNOCODE );
|
||||
i += iLookAhead;
|
||||
if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
|
||||
if( iLookAhead>0 ){
|
||||
|
@ -403,13 +401,18 @@ static int yy_find_reduce_action(
|
|||
YYCODETYPE iLookAhead /* The look-ahead token */
|
||||
){
|
||||
int i;
|
||||
assert( stateno<=YY_REDUCE_MAX );
|
||||
i = yy_reduce_ofst[stateno];
|
||||
if( stateno>YY_REDUCE_MAX ||
|
||||
(i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){
|
||||
return yy_default[stateno];
|
||||
}
|
||||
assert( i!=YY_REDUCE_USE_DFLT );
|
||||
assert( iLookAhead!=YYNOCODE );
|
||||
i += iLookAhead;
|
||||
assert( i>=0 && i<YY_SZ_ACTTAB );
|
||||
assert( yy_lookahead[i]==iLookAhead );
|
||||
if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
|
||||
return yy_default[stateno];
|
||||
}else{
|
||||
return yy_action[i];
|
||||
}
|
||||
return yy_action[i];
|
||||
}
|
||||
|
||||
|
@ -466,7 +469,7 @@ static void yy_shift(
|
|||
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
|
||||
fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
|
||||
for(i=1; i<=yypParser->yyidx; i++)
|
||||
fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
|
||||
fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]);
|
||||
fprintf(yyTraceFILE,"\n");
|
||||
}
|
||||
#endif
|
||||
|
@ -679,14 +682,6 @@ void Parse(
|
|||
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
|
||||
yypParser->yyerrcnt--;
|
||||
yymajor = YYNOCODE;
|
||||
/* [RH] If we can reduce the stack now, do it. Otherwise, constructs */
|
||||
/* like "include <somefile>" won't work because the next token after */
|
||||
/* the include will be shifted before the include is reduced. Then the */
|
||||
/* parser will act as if that token had been the first one in the */
|
||||
/* included file. */
|
||||
while( yypParser->yyidx>= 0 && (yyact = yy_find_shift_action(yypParser,YYNOCODE)) < YYNSTATE + YYNRULE ){
|
||||
yy_reduce(yypParser,yyact-YYNSTATE);
|
||||
}
|
||||
}else if( yyact < YYNSTATE + YYNRULE ){
|
||||
yy_reduce(yypParser,yyact-YYNSTATE);
|
||||
}else{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: actions.cc,v 1.35 2006/02/25 12:57:50 helly Exp $ */
|
||||
/* $Id: actions.cc 608 2006-11-05 00:48:30Z helly $ */
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: code.cc,v 1.74 2006/05/14 13:38:26 helly Exp $ */
|
||||
/* $Id: code.cc 717 2007-04-29 22:29:59Z helly $ */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
@ -331,7 +331,7 @@ static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMark
|
|||
}
|
||||
else
|
||||
{
|
||||
o << indent(ind) << "if((YYLIMIT - YYCURSOR) < " << n << ") YYFILL(" << n << ");\n";
|
||||
o << indent(ind) << "if((" << mapCodeName["YYLIMIT"] << " - " << mapCodeName["YYCURSOR"] << ") < " << n << ") " << mapCodeName["YYFILL"];
|
||||
}
|
||||
if (bUseYYFillParam)
|
||||
{
|
||||
|
@ -1763,7 +1763,7 @@ void Scanner::config(const Str& cfg, const Str& val)
|
|||
}
|
||||
else if (cfg.to_string() == "startlabel")
|
||||
{
|
||||
startLabelName = val.to_string();
|
||||
startLabelName = strVal;
|
||||
bUseStartLabel = !startLabelName.empty();
|
||||
}
|
||||
else if (cfg.to_string() == "labelprefix")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: re.h,v 1.17 2006/04/09 00:06:33 helly Exp $ */
|
||||
/* $Id: re.h 775 2007-07-10 19:33:17Z helly $ */
|
||||
#ifndef _re_h
|
||||
#define _re_h
|
||||
|
||||
|
@ -105,6 +105,11 @@ public:
|
|||
vFreeList.insert(this);
|
||||
}
|
||||
|
||||
~Range()
|
||||
{
|
||||
vFreeList.erase(this);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream&, const Range&);
|
||||
friend std::ostream& operator<<(std::ostream&, const Range*);
|
||||
};
|
||||
|
@ -125,6 +130,7 @@ public:
|
|||
public:
|
||||
RegExp() : size(0)
|
||||
{
|
||||
vFreeList.insert(this);
|
||||
}
|
||||
|
||||
virtual ~RegExp()
|
||||
|
|
|
@ -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 <= '/') goto yy4;
|
||||
if(yych >= ':') 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 <= '/') goto yy3;
|
||||
if(yych <= '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
|
@ -1,4 +1,4 @@
|
|||
/* $Id:$ */
|
||||
/* $Id: scanner.re 663 2007-04-01 11:22:15Z helly $ */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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.
BIN
wadsrc/doomx.lmp
BIN
wadsrc/doomx.lmp
Binary file not shown.
BIN
wadsrc/foo
BIN
wadsrc/foo
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3696,7 +3696,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating $(InputName).h from src/$(InputFileName)"
|
||||
CommandLine="tools\re2c\re2c -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
||||
CommandLine="tools\re2c\re2c --no-generation-date -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
||||
Outputs=""src/$(InputName).h""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
@ -3716,7 +3716,7 @@
|
|||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating $(InputName).h from src/$(InputFileName)"
|
||||
CommandLine="tools\re2c\re2c -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
||||
CommandLine="tools\re2c\re2c --no-generation-date -s -o "src/$(InputName).h" "src/$(InputFileName)"
"
|
||||
Outputs=""src/$(InputName).h""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
|
Loading…
Reference in a new issue