diff --git a/c/dsls/Makefile.am b/c/dsls/Makefile.am index 1f142d9b4..ebf12974c 100644 --- a/c/dsls/Makefile.am +++ b/c/dsls/Makefile.am @@ -3,6 +3,8 @@ AM_CFLAGS= -std=gnu99 noinst_PROGRAMS= lemon lemon_SOURCES= lemon.c \ + lemon_action.c \ + lemon_action.h \ lemon_assert.c \ lemon_assert.h \ lemon_error.c \ diff --git a/c/dsls/Makefile.no-autoconfig b/c/dsls/Makefile.no-autoconfig index b2f971f5b..f5280622d 100644 --- a/c/dsls/Makefile.no-autoconfig +++ b/c/dsls/Makefile.no-autoconfig @@ -105,8 +105,19 @@ ex2_lexer.c ex2_lexer.h: ex2_lexer.l ./ex_ast.h flex --prefix=ex2_lexer_ --outfile=ex2_lexer.c --header-file=ex2_lexer.h ex2_lexer.l # ---------------------------------------------------------------- -lemon: lemon.c lemon_assert.c lemon_error.c lemon_memory.c lemon_option.c lemon_structs.h - $(DSLCC) -o lemon lemon.c lemon_assert.c lemon_error.c lemon_memory.c lemon_option.c +lemon: lemon.c \ + lemon_assert.h \ + lemon_assert.c \ + lemon_error.h \ + lemon_error.c \ + lemon_memory.h \ + lemon_memory.c \ + lemon_option.h \ + lemon_option.c \ + lemon_structs.h \ + lemon_action.h \ + lemon_action.c + $(DSLCC) -o lemon lemon.c lemon_assert.c lemon_error.c lemon_memory.c lemon_option.c lemon_action.c # ---------------------------------------------------------------- clean: diff --git a/c/dsls/lemon.c b/c/dsls/lemon.c index 34d282c91..fa5a52ed7 100644 --- a/c/dsls/lemon.c +++ b/c/dsls/lemon.c @@ -18,6 +18,7 @@ #include "lemon_memory.h" #include "lemon_option.h" #include "lemon_structs.h" +#include "lemon_action.h" /* #define PRIVATE static */ #define PRIVATE @@ -31,10 +32,6 @@ char *msort(); extern void *malloc(); -/******** From the file "action.h" *************************************/ -struct action *Action_new(); -struct action *Action_sort(); - /********** From the file "build.h" ************************************/ void FindRulePrecedences(); void FindFirstSets(); @@ -134,234 +131,6 @@ int Configtable_insert(/* struct config * */); struct config *Configtable_find(/* struct config * */); void Configtable_clear(/* int(*)(struct config *) */); -/****************** From the file "action.c" *******************************/ -/* -** Routines processing parser actions in the LEMON parser generator. -*/ - -/* Allocate a new parser action */ -struct action *Action_new() { - static struct action *freelist = 0; - struct action *new; - - if (freelist==0) { - int i; - int amt = 100; - freelist = (struct action *)malloc (sizeof(struct action)*amt) ; - if (freelist==0) { - fprintf(stderr,"Unable to allocate memory for a new parser action."); - exit(1); - } - for(i=0; inext; - return new; -} - -/* Compare two actions */ -static int actioncmp(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) { - assert (ap1->type==REDUCE || ap1->type==RD_RESOLVED || ap1->type==CONFLICT); - assert (ap2->type==REDUCE || ap2->type==RD_RESOLVED || ap2->type==CONFLICT); - rc = ap1->x.rp->index - ap2->x.rp->index; - } - return rc; -} - -/* Sort parser actions */ -struct action *Action_sort(struct action *ap) -{ - ap = (struct action *)msort((char *)ap,(char **)&ap->next,actioncmp); - return ap; -} - -void Action_add( - struct action **app, - enum e_action type, - struct symbol *sp, - char *arg) -{ - struct action *new; - new = Action_new(); - new->next = *app; - *app = new; - new->type = type; - new->sp = sp; - if (type==SHIFT) { - new->x.stp = (struct state *)arg; - } else { - new->x.rp = (struct rule *)arg; - } -} - -/********************** New code to implement the "acttab" module ***********/ -/* -** This module implements routines use to construct the yy_action[] table. -*/ - -/* -** The state of the yy_action table under construction is an instance of -** the following structure -*/ -typedef struct acttab acttab; -struct acttab { - int nAction; /* Number of used slots in aAction[] */ - int nActionAlloc; /* Slots allocated for aAction[] */ - struct { - int lookahead; /* Value of the lookahead token */ - int action; /* Action to take on the given lookahead */ - } *aAction, /* The yy_action[] table under construction */ - *aLookahead; /* A single new transaction set */ - int mnLookahead; /* Minimum aLookahead[].lookahead */ - int mnAction; /* Action associated with mnLookahead */ - int mxLookahead; /* Maximum aLookahead[].lookahead */ - int nLookahead; /* Used slots in aLookahead[] */ - int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ -}; - -/* Return the number of entries in the yy_action table */ -#define acttab_size(X) ((X)->nAction) - -/* The value for the N-th entry in yy_action */ -#define acttab_yyaction(X,N) ((X)->aAction[N].action) - -/* The value for the N-th entry in yy_lookahead */ -#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) - -/* Free all memory associated with the given acttab */ -void acttab_free(acttab *p) { - free (p->aAction); - free (p->aLookahead); - free (p); -} - -/* Allocate a new acttab structure */ -acttab *acttab_alloc(void) { - acttab *p = malloc (sizeof(*p)) ; - if (p==0) { - fprintf(stderr,"Unable to allocate memory for a new acttab."); - exit(1); - } - memset(p, 0, sizeof(*p)); - return p; -} - -/* Add a new action to the current transaction set -*/ -void acttab_action(acttab *p, int lookahead, int action) { - if (p->nLookahead>=p->nLookaheadAlloc) { - p->nLookaheadAlloc += 25; - p->aLookahead = realloc (p->aLookahead, sizeof(p->aLookahead[0])*p->nLookaheadAlloc) ; - if (p->aLookahead==0) { - fprintf(stderr,"malloc failed\n"); - exit(1); - } - } - if (p->nLookahead==0) { - p->mxLookahead = lookahead; - p->mnLookahead = lookahead; - p->mnAction = action; - } else { - if (p->mxLookaheadmxLookahead = lookahead; - if (p->mnLookahead>lookahead) { - p->mnLookahead = lookahead; - p->mnAction = action; - } - } - p->aLookahead[p->nLookahead].lookahead = lookahead; - p->aLookahead[p->nLookahead].action = action; - p->nLookahead++; -} - -/* -** Add the transaction set built up with prior calls to acttab_action() -** into the current action table. Then reset the transaction set back -** to an empty set in preparation for a new round of acttab_action() calls. -** -** Return the offset into the action table of the new transaction. -*/ -int acttab_insert(acttab *p) { - int i, j, k, n; - assert (p->nLookahead>0) ; - - /* Make sure we have enough space to hold the expanded action table - ** in the worst case. The worst case occurs if the transaction set - ** must be appended to the current action table - */ - n = p->mxLookahead + 1; - if (p->nAction + n >= p->nActionAlloc) { - int oldAlloc = p->nActionAlloc; - p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; - p->aAction = realloc (p->aAction, sizeof(p->aAction[0])*p->nActionAlloc); - if (p->aAction==0) { - fprintf(stderr,"malloc failed\n"); - exit(1); - } - for(i=oldAlloc; inActionAlloc; i++){ - p->aAction[i].lookahead = -1; - p->aAction[i].action = -1; - } - } - - /* Scan the existing action table looking for an offset where we can - ** insert the current transaction set. Fall out of the loop when that - ** offset is found. In the worst case, we fall out of the loop when - ** i reaches p->nAction, which means we append the new transaction set. - ** - ** i is the index in p->aAction[] where p->mnLookahead is inserted. - */ - for(i=0; inAction+p->mnLookahead; i++){ - if (p->aAction[i].lookahead<0) { - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if (k<0) break; - if (p->aAction[k].lookahead>=0) break; - } - if (jnLookahead) continue; - for(j=0; jnAction; j++){ - if (p->aAction[j].lookahead==j+p->mnLookahead-i) break; - } - if (j==p->nAction) { - break; /* Fits in empty slots */ - } - } else if (p->aAction[i].lookahead==p->mnLookahead) { - if (p->aAction[i].action!=p->mnAction) continue; - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - if (k<0 || k>=p->nAction) break; - if (p->aLookahead[j].lookahead!=p->aAction[k].lookahead) break; - if (p->aLookahead[j].action!=p->aAction[k].action) break; - } - if (jnLookahead) continue; - n = 0; - for(j=0; jnAction; j++){ - if (p->aAction[j].lookahead<0) continue; - if (p->aAction[j].lookahead==j+p->mnLookahead-i) n++; - } - if (n==p->nLookahead) { - break; /* Same as a prior transaction set */ - } - } - } - /* Insert transaction set at index i. */ - for(j=0; jnLookahead; j++){ - k = p->aLookahead[j].lookahead - p->mnLookahead + i; - p->aAction[k] = p->aLookahead[j]; - if (k>=p->nAction) p->nAction = k+1; - } - p->nLookahead = 0; - - /* Return the offset that is added to the lookahead in order to get the - ** index into yy_action of the action */ - return i - p->mnLookahead; -} - /********************** From the file "build.c" *****************************/ /* ** Routines to construction the finite state machine for the LEMON diff --git a/c/dsls/lemon_action.c b/c/dsls/lemon_action.c new file mode 100644 index 000000000..ba02f5ca0 --- /dev/null +++ b/c/dsls/lemon_action.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include "lemon_assert.h" +#include "lemon_action.h" + +// xxx move: +char *msort(char *list, char **next, int (*cmp)()); + + +/* +** Routines processing parser actions in the LEMON parser generator. +*/ + +/* Allocate a new parser action */ +struct action *Action_new() { + static struct action *freelist = 0; + struct action *new; + + if (freelist==0) { + int i; + int amt = 100; + freelist = (struct action *)malloc (sizeof(struct action)*amt) ; + if (freelist==0) { + fprintf(stderr,"Unable to allocate memory for a new parser action."); + exit(1); + } + for(i=0; inext; + return new; +} + +/* Compare two actions */ +static int actioncmp(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) { + assert (ap1->type==REDUCE || ap1->type==RD_RESOLVED || ap1->type==CONFLICT); + assert (ap2->type==REDUCE || ap2->type==RD_RESOLVED || ap2->type==CONFLICT); + rc = ap1->x.rp->index - ap2->x.rp->index; + } + return rc; +} + +/* Sort parser actions */ +struct action *Action_sort(struct action *ap) +{ + ap = (struct action *)msort((char *)ap,(char **)&ap->next,actioncmp); + return ap; +} + +void Action_add( + struct action **app, + enum e_action type, + struct symbol *sp, + char *arg) +{ + struct action *new; + new = Action_new(); + new->next = *app; + *app = new; + new->type = type; + new->sp = sp; + if (type==SHIFT) { + new->x.stp = (struct state *)arg; + } else { + new->x.rp = (struct rule *)arg; + } +} + +/* Free all memory associated with the given acttab */ +void acttab_free(acttab *p) { + free (p->aAction); + free (p->aLookahead); + free (p); +} + +/* Allocate a new acttab structure */ +acttab *acttab_alloc(void) { + acttab *p = malloc (sizeof(*p)) ; + if (p==0) { + fprintf(stderr,"Unable to allocate memory for a new acttab."); + exit(1); + } + memset(p, 0, sizeof(*p)); + return p; +} + +/* Add a new action to the current transaction set +*/ +void acttab_action(acttab *p, int lookahead, int action) { + if (p->nLookahead>=p->nLookaheadAlloc) { + p->nLookaheadAlloc += 25; + p->aLookahead = realloc (p->aLookahead, sizeof(p->aLookahead[0])*p->nLookaheadAlloc) ; + if (p->aLookahead==0) { + fprintf(stderr,"malloc failed\n"); + exit(1); + } + } + if (p->nLookahead==0) { + p->mxLookahead = lookahead; + p->mnLookahead = lookahead; + p->mnAction = action; + } else { + if (p->mxLookaheadmxLookahead = lookahead; + if (p->mnLookahead>lookahead) { + p->mnLookahead = lookahead; + p->mnAction = action; + } + } + p->aLookahead[p->nLookahead].lookahead = lookahead; + p->aLookahead[p->nLookahead].action = action; + p->nLookahead++; +} + +/* +** Add the transaction set built up with prior calls to acttab_action() +** into the current action table. Then reset the transaction set back +** to an empty set in preparation for a new round of acttab_action() calls. +** +** Return the offset into the action table of the new transaction. +*/ +int acttab_insert(acttab *p) { + int i, j, k, n; + assert (p->nLookahead>0) ; + + /* Make sure we have enough space to hold the expanded action table + ** in the worst case. The worst case occurs if the transaction set + ** must be appended to the current action table + */ + n = p->mxLookahead + 1; + if (p->nAction + n >= p->nActionAlloc) { + int oldAlloc = p->nActionAlloc; + p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20; + p->aAction = realloc (p->aAction, sizeof(p->aAction[0])*p->nActionAlloc); + if (p->aAction==0) { + fprintf(stderr,"malloc failed\n"); + exit(1); + } + for(i=oldAlloc; inActionAlloc; i++){ + p->aAction[i].lookahead = -1; + p->aAction[i].action = -1; + } + } + + /* Scan the existing action table looking for an offset where we can + ** insert the current transaction set. Fall out of the loop when that + ** offset is found. In the worst case, we fall out of the loop when + ** i reaches p->nAction, which means we append the new transaction set. + ** + ** i is the index in p->aAction[] where p->mnLookahead is inserted. + */ + for(i=0; inAction+p->mnLookahead; i++){ + if (p->aAction[i].lookahead<0) { + for(j=0; jnLookahead; j++){ + k = p->aLookahead[j].lookahead - p->mnLookahead + i; + if (k<0) break; + if (p->aAction[k].lookahead>=0) break; + } + if (jnLookahead) continue; + for(j=0; jnAction; j++){ + if (p->aAction[j].lookahead==j+p->mnLookahead-i) break; + } + if (j==p->nAction) { + break; /* Fits in empty slots */ + } + } else if (p->aAction[i].lookahead==p->mnLookahead) { + if (p->aAction[i].action!=p->mnAction) continue; + for(j=0; jnLookahead; j++){ + k = p->aLookahead[j].lookahead - p->mnLookahead + i; + if (k<0 || k>=p->nAction) break; + if (p->aLookahead[j].lookahead!=p->aAction[k].lookahead) break; + if (p->aLookahead[j].action!=p->aAction[k].action) break; + } + if (jnLookahead) continue; + n = 0; + for(j=0; jnAction; j++){ + if (p->aAction[j].lookahead<0) continue; + if (p->aAction[j].lookahead==j+p->mnLookahead-i) n++; + } + if (n==p->nLookahead) { + break; /* Same as a prior transaction set */ + } + } + } + /* Insert transaction set at index i. */ + for(j=0; jnLookahead; j++){ + k = p->aLookahead[j].lookahead - p->mnLookahead + i; + p->aAction[k] = p->aLookahead[j]; + if (k>=p->nAction) p->nAction = k+1; + } + p->nLookahead = 0; + + /* Return the offset that is added to the lookahead in order to get the + ** index into yy_action of the action */ + return i - p->mnLookahead; +} diff --git a/c/dsls/lemon_action.h b/c/dsls/lemon_action.h new file mode 100644 index 000000000..c796ad94a --- /dev/null +++ b/c/dsls/lemon_action.h @@ -0,0 +1,53 @@ +#ifndef LEMON_ACTION_H +#define LEMON_ACTION_H + +#include "lemon_structs.h" + +struct action *Action_new(); +struct action *Action_sort(); +void Action_add( + struct action **app, + enum e_action type, + struct symbol *sp, + char *arg); + +/* +** This module implements routines use to construct the yy_action[] table. +*/ + +/* +** The state of the yy_action table under construction is an instance of +** the following structure +*/ +typedef struct acttab acttab; +struct acttab { + int nAction; /* Number of used slots in aAction[] */ + int nActionAlloc; /* Slots allocated for aAction[] */ + struct { + int lookahead; /* Value of the lookahead token */ + int action; /* Action to take on the given lookahead */ + } *aAction, /* The yy_action[] table under construction */ + *aLookahead; /* A single new transaction set */ + int mnLookahead; /* Minimum aLookahead[].lookahead */ + int mnAction; /* Action associated with mnLookahead */ + int mxLookahead; /* Maximum aLookahead[].lookahead */ + int nLookahead; /* Used slots in aLookahead[] */ + int nLookaheadAlloc; /* Slots allocated in aLookahead[] */ +}; + +/* Return the number of entries in the yy_action table */ +#define acttab_size(X) ((X)->nAction) + +/* The value for the N-th entry in yy_action */ +#define acttab_yyaction(X,N) ((X)->aAction[N].action) + +/* The value for the N-th entry in yy_lookahead */ +#define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) + +struct acttab *acttab_alloc(void); +void acttab_free(acttab *p); +acttab *acttab_alloc(void); +void acttab_action(acttab *p, int lookahead, int action); +int acttab_insert(acttab *p); + +#endif // LEMON_ACTION_H