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