]> git.saurik.com Git - bison.git/blame - src/nullable.c
* data/lalr1.cc (parser::token_number_type, parser::rhs_number_type)
[bison.git] / src / nullable.c
CommitLineData
09939714
PE
1/* Calculate which nonterminals can expand into the null string for Bison.
2
779e7ceb
PE
3 Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2004 Free
4 Software Foundation, Inc.
122c0aac 5
3519ec76 6 This file is part of Bison, the GNU Compiler Compiler.
122c0aac 7
3519ec76
AD
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.
122c0aac 12
3519ec76
AD
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.
122c0aac 17
3519ec76
AD
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. */
122c0aac
RS
22
23
3519ec76
AD
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
ceed8467 26 do so. */
122c0aac 27
122c0aac 28#include "system.h"
a0b76449 29
9bfe901c 30#include "getargs.h"
122c0aac 31#include "gram.h"
3519ec76 32#include "nullable.h"
a0b76449
PE
33#include "reduce.h"
34#include "symtab.h"
122c0aac 35
bb0027a9 36/* Linked list of rules. */
a0b76449 37typedef struct rule_list
e68e0410 38{
a0b76449
PE
39 struct rule_list *next;
40 rule *value;
41} rule_list;
e68e0410 42
bb0027a9 43bool *nullable = NULL;
122c0aac 44
6bb1878b
AD
45static void
46nullable_print (FILE *out)
47{
48 int i;
49 fputs ("NULLABLE\n", out);
50 for (i = ntokens; i < nsyms; i++)
09939714
PE
51 fprintf (out, "\t%s: %s\n", symbols[i]->tag,
52 nullable[i - ntokens] ? "yes" : "no");
6bb1878b
AD
53 fputs ("\n\n", out);
54}
55
122c0aac 56void
bb0027a9 57nullable_compute (void)
122c0aac 58{
a0b76449
PE
59 rule_number ruleno;
60 symbol_number *s1;
61 symbol_number *s2;
62 rule_list *p;
122c0aac 63
da2a7671 64 symbol_number *squeue = xnmalloc (nvars, sizeof *squeue);
f6fbd3da 65 size_t *rcount = xcalloc (nrules, sizeof *rcount);
ed8e1f68
AD
66 /* RITEM contains all the rules, including useless productions.
67 Hence we must allocate room for useless nonterminals too. */
da2a7671 68 rule_list **rsets = xcalloc (nvars, sizeof *rsets);
ed8e1f68 69 /* This is said to be more elements than we actually use.
9e7f6bbd 70 Supposedly NRITEMS - NRULES is enough. But why take the risk? */
da2a7671 71 rule_list *relts = xnmalloc (nritems + nvars + 1, sizeof *relts);
122c0aac 72
da2a7671 73 nullable = xcalloc (nvars, sizeof *nullable);
122c0aac 74
122c0aac 75 s1 = s2 = squeue;
122c0aac
RS
76 p = relts;
77
4b3d3a8e 78 for (ruleno = 0; ruleno < nrules; ++ruleno)
1a2b5d37 79 if (rules[ruleno].useful)
ed8e1f68 80 {
a0b76449
PE
81 rule *rules_ruleno = &rules[ruleno];
82 if (rules_ruleno->rhs[0] >= 0)
9c2c67e6
AD
83 {
84 /* This rule has a non empty RHS. */
a737b216 85 item_number *rp = NULL;
d0829076 86 bool any_tokens = false;
a737b216
PE
87 for (rp = rules_ruleno->rhs; *rp >= 0; ++rp)
88 if (ISTOKEN (*rp))
d0829076 89 any_tokens = true;
9c2c67e6
AD
90
91 /* This rule has only nonterminals: schedule it for the second
92 pass. */
93 if (!any_tokens)
a737b216 94 for (rp = rules_ruleno->rhs; *rp >= 0; ++rp)
9c2c67e6
AD
95 {
96 rcount[ruleno]++;
a737b216 97 p->next = rsets[*rp - ntokens];
a0b76449 98 p->value = rules_ruleno;
a737b216 99 rsets[*rp - ntokens] = p;
9c2c67e6
AD
100 p++;
101 }
102 }
103 else
81b51460 104 {
9c2c67e6 105 /* This rule has an empty RHS. */
a0b76449 106 if (item_number_as_rule_number (rules_ruleno->rhs[0]) != ruleno)
b475e0cc 107 abort ();
09939714
PE
108 if (rules_ruleno->useful
109 && ! nullable[rules_ruleno->lhs->number - ntokens])
9c2c67e6 110 {
d0829076 111 nullable[rules_ruleno->lhs->number - ntokens] = true;
a0b76449 112 *s2++ = rules_ruleno->lhs->number;
9c2c67e6 113 }
81b51460 114 }
ed8e1f68 115 }
122c0aac
RS
116
117 while (s1 < s2)
09939714 118 for (p = rsets[*s1++ - ntokens]; p; p = p->next)
e3e4e814 119 {
a0b76449
PE
120 rule *r = p->value;
121 if (--rcount[r->number] == 0)
09939714 122 if (r->useful && ! nullable[r->lhs->number - ntokens])
122c0aac 123 {
d0829076 124 nullable[r->lhs->number - ntokens] = true;
a0b76449 125 *s2++ = r->lhs->number;
122c0aac 126 }
e3e4e814 127 }
122c0aac 128
afbb696d
PE
129 free (squeue);
130 free (rcount);
131 free (rsets);
132 free (relts);
6bb1878b 133
273a74fa 134 if (trace_flag & trace_sets)
6bb1878b 135 nullable_print (stderr);
122c0aac
RS
136}
137
138
139void
bb0027a9 140nullable_free (void)
122c0aac 141{
afbb696d 142 free (nullable);
122c0aac 143}