Added some tests and changed ordering mechanism

This commit is contained in:
ceriel 1991-11-01 10:37:26 +00:00
parent 7c479cf325
commit 03e1bea097
11 changed files with 78 additions and 51 deletions

View file

@ -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;

View file

@ -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",

View file

@ -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 : {

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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;
} }

View file

@ -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);
} }

View file

@ -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 {