Added some tests and changed ordering mechanism
This commit is contained in:
parent
7c479cf325
commit
03e1bea097
11 changed files with 78 additions and 51 deletions
|
@ -34,8 +34,7 @@ p_gram search();
|
||||||
|
|
||||||
static int nparams; /* parameter count for nonterminals */
|
static int nparams; /* parameter count for nonterminals */
|
||||||
static int acount; /* count #of global actions */
|
static int acount; /* count #of global actions */
|
||||||
static p_order order,
|
static int order;
|
||||||
maxorder;
|
|
||||||
static p_term t_list;
|
static p_term t_list;
|
||||||
static int t_cnt;
|
static int t_cnt;
|
||||||
static p_gram alt_table;
|
static p_gram alt_table;
|
||||||
|
@ -49,29 +48,36 @@ static int max_rules;
|
||||||
#define RULEINCR 32
|
#define RULEINCR 32
|
||||||
|
|
||||||
/* Here are defined : */
|
/* Here are defined : */
|
||||||
STATIC p_order neworder();
|
STATIC newnorder();
|
||||||
|
STATIC newtorder();
|
||||||
STATIC copyact();
|
STATIC copyact();
|
||||||
STATIC mkalt();
|
STATIC mkalt();
|
||||||
STATIC mkterm();
|
STATIC mkterm();
|
||||||
STATIC p_gram copyrule();
|
STATIC p_gram copyrule();
|
||||||
/* and of course LLparse() */
|
/* and of course LLparse() */
|
||||||
|
|
||||||
STATIC p_order
|
STATIC
|
||||||
neworder(index) {
|
newnorder(index) {
|
||||||
register p_order po;
|
static int porder;
|
||||||
|
|
||||||
if ((po = order) == maxorder) {
|
if (norder != -1) {
|
||||||
po = (p_order) alloc(20 * sizeof(*order));
|
nonterms[porder].n_next = index;
|
||||||
maxorder = po + 20;
|
|
||||||
}
|
}
|
||||||
order = po + 1;
|
else norder = index;
|
||||||
po->o_next = 0;
|
porder = index;
|
||||||
po->o_index = index;
|
nonterms[porder].n_next = -1;
|
||||||
if (porder) {
|
}
|
||||||
porder->o_next = po;
|
|
||||||
|
STATIC
|
||||||
|
newtorder(index) {
|
||||||
|
static int porder;
|
||||||
|
|
||||||
|
if (torder != -1) {
|
||||||
|
tokens[porder].t_next = index;
|
||||||
}
|
}
|
||||||
else sorder = po;
|
else torder = index;
|
||||||
return po;
|
porder = index;
|
||||||
|
tokens[porder].t_next = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_init()
|
p_init()
|
||||||
|
@ -128,6 +134,12 @@ def { register string p; }
|
||||||
ff->ff_name = p;
|
ff->ff_name = p;
|
||||||
ff->ff_next = start;
|
ff->ff_next = start;
|
||||||
start = ff;
|
start = ff;
|
||||||
|
while (ff = ff->ff_next) {
|
||||||
|
if (! strcmp(p, ff->ff_name)) {
|
||||||
|
error(linecount, "\"%s\" already used in a %%start", p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| C_LEXICAL C_IDENT
|
| C_LEXICAL C_IDENT
|
||||||
/*
|
/*
|
||||||
|
@ -172,7 +184,10 @@ def { register string p; }
|
||||||
*/
|
*/
|
||||||
;
|
;
|
||||||
|
|
||||||
listel : C_IDENT { search(TERMINAL,lextoken.t_string,ENTERING); }
|
listel : C_IDENT { p_gram temp = search(TERMINAL,lextoken.t_string,ENTERING);
|
||||||
|
newtorder(g_getcont(temp));
|
||||||
|
tokens[g_getcont(temp)].t_lineno = linecount;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
rule { register p_nont p;
|
rule { register p_nont p;
|
||||||
|
@ -194,7 +209,7 @@ rule { register p_nont p;
|
||||||
* order to keep track with the actions on the
|
* order to keep track with the actions on the
|
||||||
* temporary file
|
* temporary file
|
||||||
*/
|
*/
|
||||||
porder = neworder(p - nonterms);
|
newnorder(p - nonterms);
|
||||||
p->n_count = acount;
|
p->n_count = acount;
|
||||||
acount = 0;
|
acount = 0;
|
||||||
p->n_lineno = linecount;
|
p->n_lineno = linecount;
|
||||||
|
|
|
@ -55,7 +55,7 @@ conflchecks() {
|
||||||
* must be disjunct.
|
* must be disjunct.
|
||||||
*/
|
*/
|
||||||
register p_nont p;
|
register p_nont p;
|
||||||
register p_order s;
|
register int s;
|
||||||
p_file x = files;
|
p_file x = files;
|
||||||
|
|
||||||
f_input = x->f_name;
|
f_input = x->f_name;
|
||||||
|
@ -71,15 +71,15 @@ conflchecks() {
|
||||||
*/
|
*/
|
||||||
for (; x < maxfiles; x++) {
|
for (; x < maxfiles; x++) {
|
||||||
f_input = x->f_name;
|
f_input = x->f_name;
|
||||||
for (s = x->f_list; s; s = s->o_next) {
|
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
|
||||||
p = &nonterms[s->o_index];
|
p = &nonterms[s];
|
||||||
if (check(p->n_rule)) p->n_flags |= VERBOSE;
|
if (check(p->n_rule)) p->n_flags |= VERBOSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (x = files; x < maxfiles; x++) {
|
for (x = files; x < maxfiles; x++) {
|
||||||
f_input = x->f_name;
|
f_input = x->f_name;
|
||||||
for (s = x->f_list; s; s = s->o_next) {
|
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
|
||||||
p = &nonterms[s->o_index];
|
p = &nonterms[s];
|
||||||
if (p->n_flags & RECURSIVE) {
|
if (p->n_flags & RECURSIVE) {
|
||||||
error(p->n_lineno,
|
error(p->n_lineno,
|
||||||
"Recursion in default for nonterminal %s",
|
"Recursion in default for nonterminal %s",
|
||||||
|
|
|
@ -798,16 +798,16 @@ do_safes(p,safe,ch) register p_gram p; register int *ch; {
|
||||||
break; }
|
break; }
|
||||||
case ALTERNATION : {
|
case ALTERNATION : {
|
||||||
register p_link l;
|
register p_link l;
|
||||||
register int i, f;
|
register int i;
|
||||||
|
|
||||||
f = 1;
|
retval = -1;
|
||||||
while (g_gettype(p) == ALTERNATION) {
|
while (g_gettype(p) == ALTERNATION) {
|
||||||
l = g_getlink(p);
|
l = g_getlink(p);
|
||||||
if (safe > SAFE && (l->l_flag & DEF)) {
|
if (safe > SAFE && (l->l_flag & DEF)) {
|
||||||
i = do_safes(l->l_rule,SAFESCANDONE,ch);
|
i = do_safes(l->l_rule,SAFESCANDONE,ch);
|
||||||
}
|
}
|
||||||
else i = do_safes(l->l_rule,SAFE,ch);
|
else i = do_safes(l->l_rule,SAFE,ch);
|
||||||
if (f) retval = i;
|
if (retval == -1) retval = i;
|
||||||
else if (i != retval) {
|
else if (i != retval) {
|
||||||
if (i == NOSCANDONE ||
|
if (i == NOSCANDONE ||
|
||||||
retval == NOSCANDONE) {
|
retval == NOSCANDONE) {
|
||||||
|
@ -816,7 +816,6 @@ do_safes(p,safe,ch) register p_gram p; register int *ch; {
|
||||||
else if (i > retval) retval = i;
|
else if (i > retval) retval = i;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
f = 0;
|
|
||||||
}
|
}
|
||||||
return retval; }
|
return retval; }
|
||||||
case NONTERM : {
|
case NONTERM : {
|
||||||
|
|
|
@ -45,7 +45,7 @@ extern p_nont nonterms; /* the nonterminal array */
|
||||||
extern p_nont maxnt; /* is filled up until here */
|
extern p_nont maxnt; /* is filled up until here */
|
||||||
extern p_token tokens; /* the token array */
|
extern p_token tokens; /* the token array */
|
||||||
extern p_token maxt; /* is filled up until here */
|
extern p_token maxt; /* is filled up until here */
|
||||||
extern struct order *sorder, *porder;
|
extern int norder, torder;
|
||||||
/* order of nonterminals in the grammar,
|
/* order of nonterminals in the grammar,
|
||||||
* important because actions are copied to
|
* important because actions are copied to
|
||||||
* a temporary file in the order in which they
|
* a temporary file in the order in which they
|
||||||
|
|
|
@ -235,7 +235,7 @@ generate(f) p_file f; {
|
||||||
/*
|
/*
|
||||||
* Generates a parsing routine for every nonterminal
|
* Generates a parsing routine for every nonterminal
|
||||||
*/
|
*/
|
||||||
register p_order s;
|
register int s;
|
||||||
register p_nont p;
|
register p_nont p;
|
||||||
int i;
|
int i;
|
||||||
register p_first ff;
|
register p_first ff;
|
||||||
|
@ -249,8 +249,8 @@ generate(f) p_file f; {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For every nonterminal generate a function */
|
/* For every nonterminal generate a function */
|
||||||
for (s = f->f_list; s; s = s->o_next) {
|
for (s = f->f_nonterminals; s != -1; s = p->n_next) {
|
||||||
p = &nonterms[s->o_index];
|
p = &nonterms[s];
|
||||||
/* Generate functions in the order in which the nonterminals
|
/* Generate functions in the order in which the nonterminals
|
||||||
* were defined in the grammar. This is important, because
|
* were defined in the grammar. This is important, because
|
||||||
* of synchronisation with the action file
|
* of synchronisation with the action file
|
||||||
|
@ -260,7 +260,7 @@ generate(f) p_file f; {
|
||||||
getntparams(p) == 0) {
|
getntparams(p) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
genextname(s->o_index, p->n_name, fpars);
|
genextname(s, p->n_name, fpars);
|
||||||
if (p->n_flags & PARAMS) {
|
if (p->n_flags & PARAMS) {
|
||||||
fputs("(\n", fpars);
|
fputs("(\n", fpars);
|
||||||
controlline();
|
controlline();
|
||||||
|
@ -297,7 +297,7 @@ prset(p) p_set p; {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
i = (unsigned) *p++;
|
i = (unsigned) *p++;
|
||||||
for (k = 0; k < sizeof(int); k++) {
|
for (k = 0; k < sizeof(int); k++) {
|
||||||
fprintf(fpars,"0%o,",(i & 0377));
|
fprintf(fpars,"0%o,",(int)(i & 0377));
|
||||||
i >>= 8;
|
i >>= 8;
|
||||||
if (--j == 0) {
|
if (--j == 0) {
|
||||||
fputs("\n",fpars);
|
fputs("\n",fpars);
|
||||||
|
@ -574,6 +574,7 @@ alternation(pp, safety, mustscan, mustpop, lb)
|
||||||
p = pp;
|
p = pp;
|
||||||
}
|
}
|
||||||
while (g_gettype(p) != EORULE) {
|
while (g_gettype(p) != EORULE) {
|
||||||
|
set = 0;
|
||||||
l = g_getlink(p);
|
l = g_getlink(p);
|
||||||
if (l->l_flag & COND) {
|
if (l->l_flag & COND) {
|
||||||
if (!(l->l_flag & NOCONF)) {
|
if (!(l->l_flag & NOCONF)) {
|
||||||
|
@ -884,7 +885,7 @@ genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; {
|
||||||
register FILE *f = fpars;
|
register FILE *f = fpars;
|
||||||
p_set p1;
|
p_set p1;
|
||||||
p_set setalloc();
|
p_set setalloc();
|
||||||
int hulp1, hulp2;
|
int hulp1 = 0, hulp2;
|
||||||
int safeterm;
|
int safeterm;
|
||||||
int termissafe = 0;
|
int termissafe = 0;
|
||||||
int casecnt = 0;
|
int casecnt = 0;
|
||||||
|
|
|
@ -33,7 +33,7 @@ p_token tokens;
|
||||||
p_token maxt;
|
p_token maxt;
|
||||||
int ntokens;
|
int ntokens;
|
||||||
int nterms, nalts;
|
int nterms, nalts;
|
||||||
p_order porder, sorder;
|
int norder, torder;
|
||||||
p_start start;
|
p_start start;
|
||||||
int linecount;
|
int linecount;
|
||||||
int assval;
|
int assval;
|
||||||
|
|
|
@ -171,7 +171,7 @@ main(argc,argv) register string argv[]; {
|
||||||
fprintf(stderr, "number of tokens: %d\n", ntokens);
|
fprintf(stderr, "number of tokens: %d\n", ntokens);
|
||||||
fprintf(stderr, "number of term structures: %d\n", nterms);
|
fprintf(stderr, "number of term structures: %d\n", nterms);
|
||||||
fprintf(stderr, "number of alternation structures: %d\n", nalts);
|
fprintf(stderr, "number of alternation structures: %d\n", nalts);
|
||||||
fprintf(stderr, "total memory used: %u\n", sbrk(0) - (char *) &end);
|
fprintf(stderr, "total memory used: %ld\n", (long)(sbrk(0) - (char *) &end));
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -222,10 +222,11 @@ doparse(p) register p_file p; {
|
||||||
p->f_name = f_input;
|
p->f_name = f_input;
|
||||||
p->f_firsts = 0;
|
p->f_firsts = 0;
|
||||||
pfile = p;
|
pfile = p;
|
||||||
sorder = 0;
|
torder = -1;
|
||||||
porder = 0;
|
norder = -1;
|
||||||
LLparse();
|
LLparse();
|
||||||
p->f_list = sorder;
|
p->f_nonterminals = norder;
|
||||||
|
p->f_terminals = torder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VARARGS1 */
|
/* VARARGS1 */
|
||||||
|
|
|
@ -114,7 +114,7 @@ search(type,str,option) register string str; {
|
||||||
* It has type UNKNOWN, LITERAL, TERMINAL or NONTERM.
|
* It has type UNKNOWN, LITERAL, TERMINAL or NONTERM.
|
||||||
* option can be ENTERING or BOTH (also looking).
|
* option can be ENTERING or BOTH (also looking).
|
||||||
*/
|
*/
|
||||||
register int val;
|
register int val = 0;
|
||||||
register p_entry p;
|
register p_entry p;
|
||||||
register int i;
|
register int i;
|
||||||
int type1;
|
int type1;
|
||||||
|
|
|
@ -37,9 +37,10 @@ co_reach() {
|
||||||
* Check for undefined or unreachable nonterminals.
|
* Check for undefined or unreachable nonterminals.
|
||||||
*/
|
*/
|
||||||
register p_nont p;
|
register p_nont p;
|
||||||
|
register p_token t;
|
||||||
register p_start st;
|
register p_start st;
|
||||||
register p_file x;
|
register p_file x;
|
||||||
register p_order s;
|
register int s;
|
||||||
|
|
||||||
/* Check for undefined nonterminals */
|
/* Check for undefined nonterminals */
|
||||||
for (p = nonterms; p < maxnt; p++) {
|
for (p = nonterms; p < maxnt; p++) {
|
||||||
|
@ -63,13 +64,20 @@ co_reach() {
|
||||||
*/
|
*/
|
||||||
for (x = files; x < maxfiles; x++) {
|
for (x = files; x < maxfiles; x++) {
|
||||||
f_input = x->f_name;
|
f_input = x->f_name;
|
||||||
for (s = x->f_list; s; s = s->o_next) {
|
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
|
||||||
p = &nonterms[s->o_index];
|
p = &nonterms[s];
|
||||||
if (! (p->n_flags & REACHABLE)) {
|
if (! (p->n_flags & REACHABLE)) {
|
||||||
warning(p->n_lineno,"nonterminal %s unreachable",
|
warning(p->n_lineno,"nonterminal %s unreachable",
|
||||||
p->n_name);
|
p->n_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (s = x->f_terminals; s != -1; s = t->t_next) {
|
||||||
|
t = &tokens[s];
|
||||||
|
if (! (t->t_flags & REACHABLE)) {
|
||||||
|
warning(t->t_lineno,"terminal %s not used",
|
||||||
|
t->t_string);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +125,9 @@ reachwalk(p) register p_gram p; {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TERMINAL:
|
||||||
|
tokens[g_getcont(p)].t_flags |= REACHABLE;
|
||||||
|
break;
|
||||||
case EORULE :
|
case EORULE :
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ p_set *setptr, *maxptr;
|
||||||
static t_info set_info;
|
static t_info set_info;
|
||||||
p_mem alloc();
|
p_mem alloc();
|
||||||
|
|
||||||
setinit(ntneeded) {
|
setinit(nt_needed) {
|
||||||
/*
|
/*
|
||||||
* Initialises some variables needed for setcomputations
|
* Initialises some variables needed for setcomputations
|
||||||
*/
|
*/
|
||||||
|
@ -53,7 +53,7 @@ setinit(ntneeded) {
|
||||||
nbytes = NBYTES(ntokens);
|
nbytes = NBYTES(ntokens);
|
||||||
bitset = ALIGN(nbytes);
|
bitset = ALIGN(nbytes);
|
||||||
tsetsize = NINTS(bitset);
|
tsetsize = NINTS(bitset);
|
||||||
if (ntneeded) {
|
if (nt_needed) {
|
||||||
/* nonterminals must be included in the sets */
|
/* nonterminals must be included in the sets */
|
||||||
bitset += NBYTES(nnonterms);
|
bitset += NBYTES(nnonterms);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ typedef struct token {
|
||||||
} t_x;
|
} t_x;
|
||||||
# define t_string t_x.t_s
|
# define t_string t_x.t_s
|
||||||
# define t_num t_x.t_v
|
# define t_num t_x.t_v
|
||||||
|
int t_flags;
|
||||||
|
int t_next;
|
||||||
|
int t_lineno;
|
||||||
} t_token, *p_token;
|
} t_token, *p_token;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -131,6 +134,7 @@ typedef struct {
|
||||||
p_set n_follow; /* pointer to the "follow" set */
|
p_set n_follow; /* pointer to the "follow" set */
|
||||||
p_set n_contains; /* pointer to symbols that can be produced */
|
p_set n_contains; /* pointer to symbols that can be produced */
|
||||||
string n_name; /* name of nonterminal */
|
string n_name; /* name of nonterminal */
|
||||||
|
int n_next; /* index of next nonterminal */
|
||||||
} t_nont, *p_nont;
|
} t_nont, *p_nont;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -212,11 +216,6 @@ typedef struct ff_firsts {
|
||||||
typedef t_first t_start;
|
typedef t_first t_start;
|
||||||
typedef p_first p_start;
|
typedef p_first p_start;
|
||||||
|
|
||||||
typedef struct order {
|
|
||||||
int o_index; /* index in nonterminal array */
|
|
||||||
struct order *o_next;
|
|
||||||
} t_order, *p_order;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* structure for file names and info
|
* structure for file names and info
|
||||||
*/
|
*/
|
||||||
|
@ -226,7 +225,8 @@ typedef struct f_file {
|
||||||
* generated in the target file for this
|
* generated in the target file for this
|
||||||
* grammar file
|
* grammar file
|
||||||
*/
|
*/
|
||||||
struct order *f_list; /* list of nonterminals in this file */
|
int f_nonterminals; /* list of nonterminals in this file */
|
||||||
|
int f_terminals; /* list of terminals in this file */
|
||||||
} t_file, *p_file;
|
} t_file, *p_file;
|
||||||
|
|
||||||
typedef struct info_alloc {
|
typedef struct info_alloc {
|
||||||
|
|
Loading…
Add table
Reference in a new issue