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 acount; /* count #of global actions */
static p_order order,
maxorder;
static int order;
static p_term t_list;
static int t_cnt;
static p_gram alt_table;
@ -49,29 +48,36 @@ static int max_rules;
#define RULEINCR 32
/* Here are defined : */
STATIC p_order neworder();
STATIC newnorder();
STATIC newtorder();
STATIC copyact();
STATIC mkalt();
STATIC mkterm();
STATIC p_gram copyrule();
/* and of course LLparse() */
STATIC p_order
neworder(index) {
register p_order po;
STATIC
newnorder(index) {
static int porder;
if ((po = order) == maxorder) {
po = (p_order) alloc(20 * sizeof(*order));
maxorder = po + 20;
if (norder != -1) {
nonterms[porder].n_next = index;
}
order = po + 1;
po->o_next = 0;
po->o_index = index;
if (porder) {
porder->o_next = po;
else norder = index;
porder = index;
nonterms[porder].n_next = -1;
}
STATIC
newtorder(index) {
static int porder;
if (torder != -1) {
tokens[porder].t_next = index;
}
else sorder = po;
return po;
else torder = index;
porder = index;
tokens[porder].t_next = -1;
}
p_init()
@ -128,6 +134,12 @@ def { register string p; }
ff->ff_name = p;
ff->ff_next = start;
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
/*
@ -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;
@ -194,7 +209,7 @@ rule { register p_nont p;
* order to keep track with the actions on the
* temporary file
*/
porder = neworder(p - nonterms);
newnorder(p - nonterms);
p->n_count = acount;
acount = 0;
p->n_lineno = linecount;

View file

@ -55,7 +55,7 @@ conflchecks() {
* must be disjunct.
*/
register p_nont p;
register p_order s;
register int s;
p_file x = files;
f_input = x->f_name;
@ -71,15 +71,15 @@ conflchecks() {
*/
for (; x < maxfiles; x++) {
f_input = x->f_name;
for (s = x->f_list; s; s = s->o_next) {
p = &nonterms[s->o_index];
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
p = &nonterms[s];
if (check(p->n_rule)) p->n_flags |= VERBOSE;
}
}
for (x = files; x < maxfiles; x++) {
f_input = x->f_name;
for (s = x->f_list; s; s = s->o_next) {
p = &nonterms[s->o_index];
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
p = &nonterms[s];
if (p->n_flags & RECURSIVE) {
error(p->n_lineno,
"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; }
case ALTERNATION : {
register p_link l;
register int i, f;
register int i;
f = 1;
retval = -1;
while (g_gettype(p) == ALTERNATION) {
l = g_getlink(p);
if (safe > SAFE && (l->l_flag & DEF)) {
i = do_safes(l->l_rule,SAFESCANDONE,ch);
}
else i = do_safes(l->l_rule,SAFE,ch);
if (f) retval = i;
if (retval == -1) retval = i;
else if (i != retval) {
if (i == 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;
}
p++;
f = 0;
}
return retval; }
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_token tokens; /* the token array */
extern p_token maxt; /* is filled up until here */
extern struct order *sorder, *porder;
extern int norder, torder;
/* order of nonterminals in the grammar,
* important because actions are copied to
* 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
*/
register p_order s;
register int s;
register p_nont p;
int i;
register p_first ff;
@ -249,8 +249,8 @@ generate(f) p_file f; {
}
/* For every nonterminal generate a function */
for (s = f->f_list; s; s = s->o_next) {
p = &nonterms[s->o_index];
for (s = f->f_nonterminals; s != -1; s = p->n_next) {
p = &nonterms[s];
/* Generate functions in the order in which the nonterminals
* were defined in the grammar. This is important, because
* of synchronisation with the action file
@ -260,7 +260,7 @@ generate(f) p_file f; {
getntparams(p) == 0) {
continue;
}
genextname(s->o_index, p->n_name, fpars);
genextname(s, p->n_name, fpars);
if (p->n_flags & PARAMS) {
fputs("(\n", fpars);
controlline();
@ -297,7 +297,7 @@ prset(p) p_set p; {
for (;;) {
i = (unsigned) *p++;
for (k = 0; k < sizeof(int); k++) {
fprintf(fpars,"0%o,",(i & 0377));
fprintf(fpars,"0%o,",(int)(i & 0377));
i >>= 8;
if (--j == 0) {
fputs("\n",fpars);
@ -574,6 +574,7 @@ alternation(pp, safety, mustscan, mustpop, lb)
p = pp;
}
while (g_gettype(p) != EORULE) {
set = 0;
l = g_getlink(p);
if (l->l_flag & COND) {
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;
p_set p1;
p_set setalloc();
int hulp1, hulp2;
int hulp1 = 0, hulp2;
int safeterm;
int termissafe = 0;
int casecnt = 0;

View file

@ -33,7 +33,7 @@ p_token tokens;
p_token maxt;
int ntokens;
int nterms, nalts;
p_order porder, sorder;
int norder, torder;
p_start start;
int linecount;
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 term structures: %d\n", nterms);
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);
}
@ -222,10 +222,11 @@ doparse(p) register p_file p; {
p->f_name = f_input;
p->f_firsts = 0;
pfile = p;
sorder = 0;
porder = 0;
torder = -1;
norder = -1;
LLparse();
p->f_list = sorder;
p->f_nonterminals = norder;
p->f_terminals = torder;
}
/* VARARGS1 */

View file

@ -114,7 +114,7 @@ search(type,str,option) register string str; {
* It has type UNKNOWN, LITERAL, TERMINAL or NONTERM.
* option can be ENTERING or BOTH (also looking).
*/
register int val;
register int val = 0;
register p_entry p;
register int i;
int type1;

View file

@ -37,9 +37,10 @@ co_reach() {
* Check for undefined or unreachable nonterminals.
*/
register p_nont p;
register p_token t;
register p_start st;
register p_file x;
register p_order s;
register int s;
/* Check for undefined nonterminals */
for (p = nonterms; p < maxnt; p++) {
@ -63,13 +64,20 @@ co_reach() {
*/
for (x = files; x < maxfiles; x++) {
f_input = x->f_name;
for (s = x->f_list; s; s = s->o_next) {
p = &nonterms[s->o_index];
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
p = &nonterms[s];
if (! (p->n_flags & REACHABLE)) {
warning(p->n_lineno,"nonterminal %s unreachable",
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;
}
case TERMINAL:
tokens[g_getcont(p)].t_flags |= REACHABLE;
break;
case EORULE :
return;
}

View file

@ -44,7 +44,7 @@ p_set *setptr, *maxptr;
static t_info set_info;
p_mem alloc();
setinit(ntneeded) {
setinit(nt_needed) {
/*
* Initialises some variables needed for setcomputations
*/
@ -53,7 +53,7 @@ setinit(ntneeded) {
nbytes = NBYTES(ntokens);
bitset = ALIGN(nbytes);
tsetsize = NINTS(bitset);
if (ntneeded) {
if (nt_needed) {
/* nonterminals must be included in the sets */
bitset += NBYTES(nnonterms);
}

View file

@ -32,6 +32,9 @@ typedef struct token {
} t_x;
# define t_string t_x.t_s
# define t_num t_x.t_v
int t_flags;
int t_next;
int t_lineno;
} t_token, *p_token;
/*
@ -131,6 +134,7 @@ typedef struct {
p_set n_follow; /* pointer to the "follow" set */
p_set n_contains; /* pointer to symbols that can be produced */
string n_name; /* name of nonterminal */
int n_next; /* index of next nonterminal */
} t_nont, *p_nont;
/*
@ -212,11 +216,6 @@ typedef struct ff_firsts {
typedef t_first t_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
*/
@ -226,7 +225,8 @@ typedef struct f_file {
* generated in the target file for this
* 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;
typedef struct info_alloc {