]>
Commit | Line | Data |
---|---|---|
122c0aac | 1 | /* Part of the bison parser generator, |
6986fd9e | 2 | Copyright 1984, 1989, 2000, 2001 Free Software Foundation, Inc. |
122c0aac | 3 | |
3519ec76 | 4 | This file is part of Bison, the GNU Compiler Compiler. |
122c0aac | 5 | |
3519ec76 AD |
6 | Bison is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2, or (at your option) | |
9 | any later version. | |
122c0aac | 10 | |
3519ec76 AD |
11 | Bison is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
122c0aac | 15 | |
3519ec76 AD |
16 | You should have received a copy of the GNU General Public License |
17 | along with Bison; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 | Boston, MA 02111-1307, USA. */ | |
122c0aac RS |
20 | |
21 | ||
3519ec76 AD |
22 | /* Set up NULLABLE, a vector saying which nonterminals can expand into |
23 | the null string. NULLABLE[I - NTOKENS] is nonzero if symbol I can | |
ceed8467 | 24 | do so. */ |
122c0aac | 25 | |
122c0aac | 26 | #include "system.h" |
9bfe901c | 27 | #include "getargs.h" |
6bb1878b | 28 | #include "reader.h" |
122c0aac RS |
29 | #include "types.h" |
30 | #include "gram.h" | |
3519ec76 | 31 | #include "nullable.h" |
122c0aac | 32 | |
3519ec76 | 33 | char *nullable = NULL; |
122c0aac | 34 | |
6bb1878b AD |
35 | static void |
36 | nullable_print (FILE *out) | |
37 | { | |
38 | int i; | |
39 | fputs ("NULLABLE\n", out); | |
40 | for (i = ntokens; i < nsyms; i++) | |
41 | fprintf (out, "\t%s: %s\n", tags[i], nullable[i] ? "yes" : "no"); | |
42 | fputs ("\n\n", out); | |
43 | } | |
44 | ||
122c0aac | 45 | void |
d2729d44 | 46 | set_nullable (void) |
122c0aac | 47 | { |
3519ec76 AD |
48 | short *r; |
49 | short *s1; | |
50 | short *s2; | |
3519ec76 | 51 | shorts *p; |
122c0aac RS |
52 | |
53 | short *squeue; | |
54 | short *rcount; | |
55 | shorts **rsets; | |
56 | shorts *relts; | |
122c0aac | 57 | |
9bfe901c | 58 | if (trace_flag) |
c87d4863 | 59 | fprintf (stderr, "Entering set_nullable\n"); |
122c0aac | 60 | |
d7913476 | 61 | nullable = XCALLOC (char, nvars) - ntokens; |
122c0aac | 62 | |
d7913476 | 63 | squeue = XCALLOC (short, nvars); |
122c0aac RS |
64 | s1 = s2 = squeue; |
65 | ||
d7913476 AD |
66 | rcount = XCALLOC (short, nrules + 1); |
67 | rsets = XCALLOC (shorts *, nvars) - ntokens; | |
122c0aac RS |
68 | /* This is said to be more elements than we actually use. |
69 | Supposedly nitems - nrules is enough. | |
70 | But why take the risk? */ | |
d7913476 | 71 | relts = XCALLOC (shorts, nitems + nvars + 1); |
122c0aac RS |
72 | p = relts; |
73 | ||
74 | r = ritem; | |
75 | while (*r) | |
76 | { | |
77 | if (*r < 0) | |
78 | { | |
6bb1878b | 79 | int symbol = rule_table[-(*r++)].lhs; |
122c0aac RS |
80 | if (symbol >= 0 && !nullable[symbol]) |
81 | { | |
82 | nullable[symbol] = 1; | |
83 | *s2++ = symbol; | |
84 | } | |
85 | } | |
86 | else | |
87 | { | |
6bb1878b AD |
88 | int any_tokens = 0; |
89 | int symbol; | |
90 | short *r1 = r; | |
122c0aac | 91 | for (symbol = *r++; symbol > 0; symbol = *r++) |
6bb1878b AD |
92 | if (ISTOKEN (symbol)) |
93 | any_tokens = 1; | |
122c0aac RS |
94 | |
95 | if (!any_tokens) | |
96 | { | |
6bb1878b | 97 | int ruleno = -symbol; |
122c0aac RS |
98 | r = r1; |
99 | for (symbol = *r++; symbol > 0; symbol = *r++) | |
100 | { | |
101 | rcount[ruleno]++; | |
102 | p->next = rsets[symbol]; | |
103 | p->value = ruleno; | |
104 | rsets[symbol] = p; | |
105 | p++; | |
106 | } | |
107 | } | |
108 | } | |
109 | } | |
110 | ||
111 | while (s1 < s2) | |
112 | { | |
113 | p = rsets[*s1++]; | |
114 | while (p) | |
115 | { | |
6bb1878b | 116 | int ruleno = p->value; |
122c0aac RS |
117 | p = p->next; |
118 | if (--rcount[ruleno] == 0) | |
119 | { | |
6bb1878b | 120 | int symbol = rule_table[ruleno].lhs; |
122c0aac RS |
121 | if (symbol >= 0 && !nullable[symbol]) |
122 | { | |
123 | nullable[symbol] = 1; | |
124 | *s2++ = symbol; | |
125 | } | |
126 | } | |
127 | } | |
128 | } | |
129 | ||
d7913476 AD |
130 | XFREE (squeue); |
131 | XFREE (rcount); | |
132 | XFREE (rsets + ntokens); | |
133 | XFREE (relts); | |
6bb1878b AD |
134 | |
135 | if (trace_flag) | |
136 | nullable_print (stderr); | |
122c0aac RS |
137 | } |
138 | ||
139 | ||
140 | void | |
d2729d44 | 141 | free_nullable (void) |
122c0aac | 142 | { |
d7913476 | 143 | XFREE (nullable + ntokens); |
122c0aac | 144 | } |