1 /* Copyright (c) 1991 by the Vrije Universiteit, Amsterdam, the Netherlands.
2 * For full copyright and restrictions on use see the file COPYING in the top
3 * level of the LLgen tree.
9 * An Extended LL(1) Parser Generator
11 * Author : Ceriel J.H. Jacobs
16 * Determine which nonterminals are reachable, and also check that they
26 static string rcsid8 = "$Id: reach.c,v 2.12 1995/07/31 09:17:00 ceriel Exp $";
29 /* In this file the following routines are defined: */
36 * Check for undefined or unreachable nonterminals.
44 /* Check for undefined nonterminals */
45 for (p = nonterms; p < maxnt; p++) {
46 if (! p->n_rule) { /* undefined */
47 f_input = p->n_string;
48 error(p->n_lineno,"Nonterminal %s not defined",
54 * Walk the grammar rules, starting with the startsymbols
55 * Mark the nonterminals that are encountered with the flag
56 * REACHABLE, and walk their rules, if not done before
58 for (st = start; st; st = st->ff_next) {
59 reachable(&nonterms[st->ff_nont]);
62 * Now check for unreachable nonterminals
64 for (x = files; x < maxfiles; x++) {
66 for (s = x->f_nonterminals; s != -1; s = p->n_next) {
68 if (! (p->n_flags & REACHABLE)) {
69 warning(p->n_lineno,"nonterminal %s unreachable",
73 for (s = x->f_terminals; s != -1; s = t->t_next) {
75 if (! (t->t_flags & REACHABLE)) {
76 warning(t->t_lineno,"terminal %s not used",
84 reachable(p) register p_nont p; {
86 * Enter the fact that p is reachable, and look for implications
88 if (! (p->n_flags & REACHABLE)) {
89 p->n_flags |= REACHABLE;
91 * Now walk its grammar rule
93 if (p->n_rule) reachwalk(p->n_rule);
98 reachwalk(p) register p_gram p; {
100 * Walk through rule p, looking for nonterminals.
101 * The nonterminals found are entered as reachable
105 switch(g_gettype(p)) {
107 reachwalk(g_getlink(p)->l_rule);
110 reachwalk(g_getterm(p)->t_rule);
113 register p_nont n = &nonterms[g_getcont(p)];
116 if (n->n_rule && g_gettype(n->n_rule) == EORULE &&
117 ! g_getnpar(p) && (getntparams(n) == 0)) {
118 register p_gram np = p;
122 } while (g_gettype(np) != EORULE);
128 tokens[g_getcont(p)].t_flags |= REACHABLE;