X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/d854cc9e5a89c4eef71fdbf44a980765e30d6c68..b59b91bb6e46b51bfc7960bacd654ca7b710f3c7:/src/nullable.c?ds=sidebyside diff --git a/src/nullable.c b/src/nullable.c index 74164937..8e8809e2 100644 --- a/src/nullable.c +++ b/src/nullable.c @@ -28,6 +28,7 @@ #include "reader.h" #include "types.h" #include "gram.h" +#include "reduce.h" #include "nullable.h" char *nullable = NULL; @@ -64,11 +65,14 @@ set_nullable (void) s1 = s2 = squeue; rcount = XCALLOC (short, nrules + 1); - rsets = XCALLOC (shorts *, nvars) - ntokens; + + /* RITEM contains all the rules, including useless productions. + Hence we must allocate room for useless nonterminals too. */ + rsets = XCALLOC (shorts *, nvars + nuseless_nonterminals) - ntokens; /* This is said to be more elements than we actually use. Supposedly nitems - nrules is enough. But why take the risk? */ - relts = XCALLOC (shorts, nitems + nvars + 1); + relts = XCALLOC (shorts, nitems + nvars + nuseless_nonterminals + 1); p = relts; for (r = ritem; *r; ++r) @@ -103,23 +107,16 @@ set_nullable (void) } while (s1 < s2) - { - p = rsets[*s1++]; - while (p) - { - int ruleno = p->value; - p = p->next; - if (--rcount[ruleno] == 0) + for (p = rsets[*s1++]; p; p = p->next) + { + int ruleno = p->value; + if (--rcount[ruleno] == 0) + if (rule_table[ruleno].useful && !nullable[rule_table[ruleno].lhs]) { - int symbol = rule_table[ruleno].lhs; - if (symbol >= 0 && !nullable[symbol]) - { - nullable[symbol] = 1; - *s2++ = symbol; - } + nullable[rule_table[ruleno].lhs] = 1; + *s2++ = rule_table[ruleno].lhs; } - } - } + } XFREE (squeue); XFREE (rcount);