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;
#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()
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
/*
*/
;
-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;
* 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;
* must be disjunct.
*/
register p_nont p;
- register p_order s;
+ register int s;
p_file x = files;
f_input = x->f_name;
*/
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",
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) {
else if (i > retval) retval = i;
}
p++;
- f = 0;
}
return retval; }
case NONTERM : {
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
/*
* Generates a parsing routine for every nonterminal
*/
- register p_order s;
+ register int s;
register p_nont p;
int i;
register p_first ff;
}
/* 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
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();
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);
p = pp;
}
while (g_gettype(p) != EORULE) {
+ set = 0;
l = g_getlink(p);
if (l->l_flag & COND) {
if (!(l->l_flag & NOCONF)) {
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;
p_token maxt;
int ntokens;
int nterms, nalts;
-p_order porder, sorder;
+int norder, torder;
p_start start;
int linecount;
int assval;
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);
}
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 */
* 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;
* 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++) {
*/
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);
+ }
+ }
}
}
}
break;
}
+ case TERMINAL:
+ tokens[g_getcont(p)].t_flags |= REACHABLE;
+ break;
case EORULE :
return;
}
static t_info set_info;
p_mem alloc();
-setinit(ntneeded) {
+setinit(nt_needed) {
/*
* Initialises some variables needed for setcomputations
*/
nbytes = NBYTES(ntokens);
bitset = ALIGN(nbytes);
tsetsize = NINTS(bitset);
- if (ntneeded) {
+ if (nt_needed) {
/* nonterminals must be included in the sets */
bitset += NBYTES(nnonterms);
}
} 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;
/*
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;
/*
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
*/
* 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 {