]> git.saurik.com Git - bison.git/blob - src/nullable.c
(version): Happy new year; update overall
[bison.git] / src / nullable.c
1 /* Calculate which nonterminals can expand into the null string for Bison.
2
3 Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2004 Free
4 Software Foundation, Inc.
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
8 Bison is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 Bison is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23
24 /* Set up NULLABLE, a vector saying which nonterminals can expand into
25 the null string. NULLABLE[I - NTOKENS] is nonzero if symbol I can
26 do so. */
27
28 #include "system.h"
29
30 #include "getargs.h"
31 #include "gram.h"
32 #include "nullable.h"
33 #include "reduce.h"
34 #include "symtab.h"
35
36 /* Linked list of rules. */
37 typedef struct rule_list
38 {
39 struct rule_list *next;
40 rule *value;
41 } rule_list;
42
43 bool *nullable = NULL;
44
45 static void
46 nullable_print (FILE *out)
47 {
48 int i;
49 fputs ("NULLABLE\n", out);
50 for (i = ntokens; i < nsyms; i++)
51 fprintf (out, "\t%s: %s\n", symbols[i]->tag,
52 nullable[i - ntokens] ? "yes" : "no");
53 fputs ("\n\n", out);
54 }
55
56 void
57 nullable_compute (void)
58 {
59 rule_number ruleno;
60 symbol_number *s1;
61 symbol_number *s2;
62 rule_list *p;
63
64 symbol_number *squeue = xnmalloc (nvars, sizeof *squeue);
65 size_t *rcount = xcalloc (nrules, sizeof *rcount);
66 /* RITEM contains all the rules, including useless productions.
67 Hence we must allocate room for useless nonterminals too. */
68 rule_list **rsets = xcalloc (nvars, sizeof *rsets);
69 /* This is said to be more elements than we actually use.
70 Supposedly NRITEMS - NRULES is enough. But why take the risk? */
71 rule_list *relts = xnmalloc (nritems + nvars + 1, sizeof *relts);
72
73 nullable = xcalloc (nvars, sizeof *nullable);
74
75 s1 = s2 = squeue;
76 p = relts;
77
78 for (ruleno = 0; ruleno < nrules; ++ruleno)
79 if (rules[ruleno].useful)
80 {
81 rule *rules_ruleno = &rules[ruleno];
82 if (rules_ruleno->rhs[0] >= 0)
83 {
84 /* This rule has a non empty RHS. */
85 item_number *rp = NULL;
86 bool any_tokens = false;
87 for (rp = rules_ruleno->rhs; *rp >= 0; ++rp)
88 if (ISTOKEN (*rp))
89 any_tokens = true;
90
91 /* This rule has only nonterminals: schedule it for the second
92 pass. */
93 if (!any_tokens)
94 for (rp = rules_ruleno->rhs; *rp >= 0; ++rp)
95 {
96 rcount[ruleno]++;
97 p->next = rsets[*rp - ntokens];
98 p->value = rules_ruleno;
99 rsets[*rp - ntokens] = p;
100 p++;
101 }
102 }
103 else
104 {
105 /* This rule has an empty RHS. */
106 if (item_number_as_rule_number (rules_ruleno->rhs[0]) != ruleno)
107 abort ();
108 if (rules_ruleno->useful
109 && ! nullable[rules_ruleno->lhs->number - ntokens])
110 {
111 nullable[rules_ruleno->lhs->number - ntokens] = true;
112 *s2++ = rules_ruleno->lhs->number;
113 }
114 }
115 }
116
117 while (s1 < s2)
118 for (p = rsets[*s1++ - ntokens]; p; p = p->next)
119 {
120 rule *r = p->value;
121 if (--rcount[r->number] == 0)
122 if (r->useful && ! nullable[r->lhs->number - ntokens])
123 {
124 nullable[r->lhs->number - ntokens] = true;
125 *s2++ = r->lhs->number;
126 }
127 }
128
129 free (squeue);
130 free (rcount);
131 free (rsets);
132 free (relts);
133
134 if (trace_flag & trace_sets)
135 nullable_print (stderr);
136 }
137
138
139 void
140 nullable_free (void)
141 {
142 free (nullable);
143 }