* src/closure.h: New file.

* src/closure.c: Formatting changes, topological sort over the
functions, use of closure.h.
(initialize_closure, finalize_closure):  Rename as...
(new_closure, free_closure): these.  Adjust dependencies.
* src/LR0.c: Formatting changes, topological sort, use of
cloture.h.
(initialize_states): Rename as...
(new_states): this.
* src/Makefile.am (noinst_HEADERS): Adjust.
This commit is contained in:
Akim Demaille
2000-09-20 15:43:39 +00:00
parent 499daa504f
commit 2fa6973e6f
11 changed files with 478 additions and 502 deletions

View File

@@ -1,3 +1,16 @@
2000-09-20 Akim Demaille <akim@epita.fr>
* src/closure.h: New file.
* src/closure.c: Formatting changes, topological sort over the
functions, use of closure.h.
(initialize_closure, finalize_closure): Rename as...
(new_closure, free_closure): these. Adjust dependencies.
* src/LR0.c: Formatting changes, topological sort, use of
cloture.h.
(initialize_states): Rename as...
(new_states): this.
* src/Makefile.am (noinst_HEADERS): Adjust.
2000-09-20 Akim Demaille <akim@epita.fr> 2000-09-20 Akim Demaille <akim@epita.fr>
* src/acconfig.h: Don't protect config.h against multiple * src/acconfig.h: Don't protect config.h against multiple

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: bison 1.25\n" "Project-Id-Version: bison 1.25\n"
"POT-Creation-Date: 2000-09-20 14:50+0200\n" "POT-Creation-Date: 2000-09-20 17:44+0200\n"
"PO-Revision-Date: 1996-10-10 17:54 MET DST\n" "PO-Revision-Date: 1996-10-10 17:54 MET DST\n"
"Last-Translator: Ulrich Drepper <drepper@gnu.ai.mit.edu>\n" "Last-Translator: Ulrich Drepper <drepper@gnu.ai.mit.edu>\n"
"Language-Team: German <de@li.org>\n" "Language-Team: German <de@li.org>\n"
@@ -13,7 +13,7 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8-bit\n" "Content-Transfer-Encoding: 8-bit\n"
#: src/LR0.c:375 #: src/LR0.c:212
#, c-format #, c-format
msgid "too many states (max %d)" msgid "too many states (max %d)"
msgstr "" msgstr ""

View File

@@ -30,7 +30,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: GNU bison 1.25\n" "Project-Id-Version: GNU bison 1.25\n"
"POT-Creation-Date: 2000-09-20 14:50+0200\n" "POT-Creation-Date: 2000-09-20 17:44+0200\n"
"PO-Revision-Date: 1998-09-21 10:19+0200\n" "PO-Revision-Date: 1998-09-21 10:19+0200\n"
"Last-Translator: Nicolás García-Pedrajas <ngarcia-pedrajas@acm.org>\n" "Last-Translator: Nicolás García-Pedrajas <ngarcia-pedrajas@acm.org>\n"
"Language-Team: Spanish <es@li.org>\n" "Language-Team: Spanish <es@li.org>\n"
@@ -38,7 +38,7 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8-bit\n" "Content-Transfer-Encoding: 8-bit\n"
#: src/LR0.c:375 #: src/LR0.c:212
#, c-format #, c-format
msgid "too many states (max %d)" msgid "too many states (max %d)"
msgstr "" msgstr ""

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: bison 1.25\n" "Project-Id-Version: bison 1.25\n"
"POT-Creation-Date: 2000-09-20 14:50+0200\n" "POT-Creation-Date: 2000-09-20 17:44+0200\n"
"PO-Revision-Date: 2000-04-11 22:19+02:00\n" "PO-Revision-Date: 2000-04-11 22:19+02:00\n"
"Last-Translator: Toomas Soome <tsoome@ut.ee>\n" "Last-Translator: Toomas Soome <tsoome@ut.ee>\n"
"Language-Team: Estonian <et@li.org>\n" "Language-Team: Estonian <et@li.org>\n"
@@ -13,7 +13,7 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8-bit\n" "Content-Transfer-Encoding: 8-bit\n"
#: src/LR0.c:375 #: src/LR0.c:212
#, c-format #, c-format
msgid "too many states (max %d)" msgid "too many states (max %d)"
msgstr "liiga palju olekuid (maks %d)" msgstr "liiga palju olekuid (maks %d)"

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: bison 1.25\n" "Project-Id-Version: bison 1.25\n"
"POT-Creation-Date: 2000-09-20 14:50+0200\n" "POT-Creation-Date: 2000-09-20 17:44+0200\n"
"PO-Revision-Date: 1996-03-19 20:05 EST\n" "PO-Revision-Date: 1996-03-19 20:05 EST\n"
"Last-Translator: Dominique Boucher <boucherd@IRO.UMontreal.CA>\n" "Last-Translator: Dominique Boucher <boucherd@IRO.UMontreal.CA>\n"
"Language-Team: French <fr@li.org>\n" "Language-Team: French <fr@li.org>\n"
@@ -13,7 +13,7 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8-bit\n" "Content-Transfer-Encoding: 8-bit\n"
#: src/LR0.c:375 #: src/LR0.c:212
#, c-format #, c-format
msgid "too many states (max %d)" msgid "too many states (max %d)"
msgstr "" msgstr ""

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: GNU bison 1.28\n" "Project-Id-Version: GNU bison 1.28\n"
"POT-Creation-Date: 2000-09-20 14:50+0200\n" "POT-Creation-Date: 2000-09-20 17:44+0200\n"
"PO-Revision-Date: 1999-09-28 21:10+0900\n" "PO-Revision-Date: 1999-09-28 21:10+0900\n"
"Last-Translator: Daisuke Yamashita <yamad@mb.infoweb.ne.jp>\n" "Last-Translator: Daisuke Yamashita <yamad@mb.infoweb.ne.jp>\n"
"Language-Team: Japanese <ja@li.org>\n" "Language-Team: Japanese <ja@li.org>\n"
@@ -13,7 +13,7 @@ msgstr ""
"Content-Type: text/plain; charset=EUC-JP\n" "Content-Type: text/plain; charset=EUC-JP\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: src/LR0.c:375 #: src/LR0.c:212
#, fuzzy, c-format #, fuzzy, c-format
msgid "too many states (max %d)" msgid "too many states (max %d)"
msgstr "%s の数が多すぎます (最大 %d)" msgstr "%s の数が多すぎます (最大 %d)"

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: bison 1.25\n" "Project-Id-Version: bison 1.25\n"
"POT-Creation-Date: 2000-09-20 14:50+0200\n" "POT-Creation-Date: 2000-09-20 17:44+0200\n"
"PO-Revision-Date: 1996-08-27 15:34 MET DST\n" "PO-Revision-Date: 1996-08-27 15:34 MET DST\n"
"Last-Translator: Erick Branderhorst <branderh@debian.org>\n" "Last-Translator: Erick Branderhorst <branderh@debian.org>\n"
"Language-Team: Dutch <nl@li.org>\n" "Language-Team: Dutch <nl@li.org>\n"
@@ -13,7 +13,7 @@ msgstr ""
"Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8-bit\n" "Content-Transfer-Encoding: 8-bit\n"
#: src/LR0.c:375 #: src/LR0.c:212
#, c-format #, c-format
msgid "too many states (max %d)" msgid "too many states (max %d)"
msgstr "" msgstr ""

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: bison 1.28a\n" "Project-Id-Version: bison 1.28a\n"
"POT-Creation-Date: 2000-09-20 14:50+0200\n" "POT-Creation-Date: 2000-09-20 17:44+0200\n"
"PO-Revision-Date: 2000-04-12 13:16+04:00\n" "PO-Revision-Date: 2000-04-12 13:16+04:00\n"
"Last-Translator: Dmitry S. Sivachenko <dima@Chg.RU>\n" "Last-Translator: Dmitry S. Sivachenko <dima@Chg.RU>\n"
"Language-Team: Russian <ru@li.org>\n" "Language-Team: Russian <ru@li.org>\n"
@@ -13,7 +13,7 @@ msgstr ""
"Content-Type: text/plain; charset=koi8-r\n" "Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8-bit\n" "Content-Transfer-Encoding: 8-bit\n"
#: src/LR0.c:375 #: src/LR0.c:212
#, c-format #, c-format
msgid "too many states (max %d)" msgid "too many states (max %d)"
msgstr "ÓÌÉÛËÏÍ ÍÎÏÇÏ ÓÏÓÔÏÑÎÉÊ (ÍÁËÓÉÍÁÌØÎÏ %d)" msgstr "ÓÌÉÛËÏÍ ÍÎÏÇÏ ÓÏÓÔÏÑÎÉÊ (ÍÁËÓÉÍÁÌØÎÏ %d)"

600
src/LR0.c
View File

@@ -1,22 +1,22 @@
/* Generate the nondeterministic finite state machine for bison, /* Generate the nondeterministic finite state machine for bison,
Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc. Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler. This file is part of Bison, the GNU Compiler Compiler.
Bison is free software; you can redistribute it and/or modify Bison is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
Bison is distributed in the hope that it will be useful, Bison is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to along with Bison; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
/* See comments in state.h for the data structures that represent it. /* See comments in state.h for the data structures that represent it.
@@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
#include "gram.h" #include "gram.h"
#include "state.h" #include "state.h"
#include "complain.h" #include "complain.h"
#include "closure.h"
extern char *nullable; extern char *nullable;
extern short *itemset; extern short *itemset;
@@ -40,23 +40,7 @@ core *first_state;
shifts *first_shift; shifts *first_shift;
reductions *first_reduction; reductions *first_reduction;
extern void generate_states PARAMS((void)); extern void generate_states PARAMS ((void));
static int get_state PARAMS((int));
static core *new_state PARAMS((int));
static void allocate_itemsets PARAMS((void));
static void allocate_storage PARAMS((void));
static void free_storage PARAMS((void));
static void new_itemsets PARAMS((void));
static void append_states PARAMS((void));
static void initialize_states PARAMS((void));
static void save_shifts PARAMS((void));
static void save_reductions PARAMS((void));
static void augment_automaton PARAMS((void));
static void insert_start_shift PARAMS((void));
extern void initialize_closure PARAMS((int));
extern void closure PARAMS((short *, int));
extern void finalize_closure PARAMS((void));
static core *this_state; static core *this_state;
static core *last_state; static core *last_state;
@@ -78,19 +62,18 @@ static short *kernel_items;
#define STATE_TABLE_SIZE 1009 #define STATE_TABLE_SIZE 1009
static core **state_table; static core **state_table;
static void static void
allocate_itemsets (void) allocate_itemsets (void)
{ {
register short *itemp; short *itemp;
register int symbol; int symbol;
register int i; int i;
register int count; int count;
register short *symbol_count; short *symbol_count;
count = 0; count = 0;
symbol_count = NEW2(nsyms, short); symbol_count = NEW2 (nsyms, short);
itemp = ritem; itemp = ritem;
symbol = *itemp++; symbol = *itemp++;
@@ -104,14 +87,14 @@ allocate_itemsets (void)
symbol = *itemp++; symbol = *itemp++;
} }
/* see comments before new_itemsets. All the vectors of items /* See comments before new_itemsets. All the vectors of items
live inside kernel_items. The number of active items after live inside KERNEL_ITEMS. The number of active items after
some symbol cannot be more than the number of times that symbol some symbol cannot be more than the number of times that symbol
appears as an item, which is symbol_count[symbol]. appears as an item, which is symbol_count[symbol].
We allocate that much space for each symbol. */ We allocate that much space for each symbol. */
kernel_base = NEW2(nsyms, short *); kernel_base = NEW2 (nsyms, short *);
kernel_items = NEW2(count, short); kernel_items = NEW2 (count, short);
count = 0; count = 0;
for (i = 0; i < nsyms; i++) for (i = 0; i < nsyms; i++)
@@ -121,94 +104,59 @@ allocate_itemsets (void)
} }
shift_symbol = symbol_count; shift_symbol = symbol_count;
kernel_end = NEW2(nsyms, short *); kernel_end = NEW2 (nsyms, short *);
} }
static void static void
allocate_storage (void) allocate_storage (void)
{ {
allocate_itemsets(); allocate_itemsets ();
shiftset = NEW2(nsyms, short); shiftset = NEW2 (nsyms, short);
redset = NEW2(nrules + 1, short); redset = NEW2 (nrules + 1, short);
state_table = NEW2(STATE_TABLE_SIZE, core *); state_table = NEW2 (STATE_TABLE_SIZE, core *);
} }
static void static void
free_storage (void) free_storage (void)
{ {
FREE(shift_symbol); FREE (shift_symbol);
FREE(redset); FREE (redset);
FREE(shiftset); FREE (shiftset);
FREE(kernel_base); FREE (kernel_base);
FREE(kernel_end); FREE (kernel_end);
FREE(kernel_items); FREE (kernel_items);
FREE(state_table); FREE (state_table);
} }
/* compute the nondeterministic finite state machine (see state.h for details)
from the grammar. */
void
generate_states (void)
{
allocate_storage();
initialize_closure(nitems);
initialize_states();
while (this_state) /*----------------------------------------------------------------.
{ | Find which symbols can be shifted in the current state, and for |
/* Set up ruleset and itemset for the transitions out of this state. | each one record which items would be active after that shift. |
ruleset gets a 1 bit for each rule that could reduce now. | Uses the contents of itemset. |
itemset gets a vector of all the items that could be accepted next. */ | |
closure(this_state->items, this_state->nitems); | shift_symbol is set to a vector of the symbols that can be |
/* record the reductions allowed out of this state */ | shifted. For each symbol in the grammar, kernel_base[symbol] |
save_reductions(); | points to a vector of item numbers activated if that symbol is |
/* find the itemsets of the states that shifts can reach */ | shifted, and kernel_end[symbol] points after the end of that |
new_itemsets(); | vector. |
/* find or create the core structures for those states */ `----------------------------------------------------------------*/
append_states();
/* create the shifts structures for the shifts to those states,
now that the state numbers transitioning to are known */
if (nshifts > 0)
save_shifts();
/* states are queued when they are created; process them all */
this_state = this_state->next;
}
/* discard various storage */
finalize_closure();
free_storage();
/* set up initial and final states as parser wants them */
augment_automaton();
}
/* Find which symbols can be shifted in the current state,
and for each one record which items would be active after that shift.
Uses the contents of itemset.
shift_symbol is set to a vector of the symbols that can be shifted.
For each symbol in the grammar, kernel_base[symbol] points to
a vector of item numbers activated if that symbol is shifted,
and kernel_end[symbol] points after the end of that vector. */
static void static void
new_itemsets (void) new_itemsets (void)
{ {
register int i; int i;
register int shiftcount; int shiftcount;
register short *isp; short *isp;
register short *ksp; short *ksp;
register int symbol; int symbol;
#ifdef TRACE #if TRACE
fprintf(stderr, "Entering new_itemsets\n"); fprintf (stderr, "Entering new_itemsets\n");
#endif #endif
for (i = 0; i < nsyms; i++) for (i = 0; i < nsyms; i++)
@@ -224,16 +172,16 @@ new_itemsets (void)
symbol = ritem[i]; symbol = ritem[i];
if (symbol > 0) if (symbol > 0)
{ {
ksp = kernel_end[symbol]; ksp = kernel_end[symbol];
if (!ksp) if (!ksp)
{ {
shift_symbol[shiftcount++] = symbol; shift_symbol[shiftcount++] = symbol;
ksp = kernel_base[symbol]; ksp = kernel_base[symbol];
} }
*ksp++ = i + 1; *ksp++ = i + 1;
kernel_end[symbol] = ksp; kernel_end[symbol] = ksp;
} }
} }
@@ -242,63 +190,70 @@ new_itemsets (void)
/* Use the information computed by new_itemsets to find the state numbers /*-----------------------------------------------------------------.
reached by each shift transition from the current state. | Subroutine of get_state. Create a new state for those items, if |
| necessary. |
`-----------------------------------------------------------------*/
shiftset is set up as a vector of state numbers of those states. */ static core *
static void new_state (int symbol)
append_states (void)
{ {
register int i; int n;
register int j; core *p;
register int symbol; short *isp1;
short *isp2;
short *iend;
#ifdef TRACE #if TRACE
fprintf(stderr, "Entering append_states\n"); fprintf (stderr, "Entering new_state, symbol = %d\n", symbol);
#endif #endif
/* first sort shift_symbol into increasing order */ if (nstates >= MAXSHORT)
fatal (_("too many states (max %d)"), MAXSHORT);
for (i = 1; i < nshifts; i++) isp1 = kernel_base[symbol];
{ iend = kernel_end[symbol];
symbol = shift_symbol[i]; n = iend - isp1;
j = i;
while (j > 0 && shift_symbol[j - 1] > symbol)
{
shift_symbol[j] = shift_symbol[j - 1];
j--;
}
shift_symbol[j] = symbol;
}
for (i = 0; i < nshifts; i++) p =
{ (core *) xmalloc ((unsigned) (sizeof (core) + (n - 1) * sizeof (short)));
symbol = shift_symbol[i]; p->accessing_symbol = symbol;
shiftset[i] = get_state(symbol); p->number = nstates;
} p->nitems = n;
isp2 = p->items;
while (isp1 < iend)
*isp2++ = *isp1++;
last_state->next = p;
last_state = p;
nstates++;
return p;
} }
/*--------------------------------------------------------------.
/* find the state number for the state we would get to | Find the state number for the state we would get to (from the |
(from the current state) by shifting symbol. | current state) by shifting symbol. Create a new state if no |
Create a new state if no equivalent one exists already. | equivalent one exists already. Used by append_states. |
Used by append_states */ `--------------------------------------------------------------*/
static int static int
get_state (int symbol) get_state (int symbol)
{ {
register int key; int key;
register short *isp1; short *isp1;
register short *isp2; short *isp2;
register short *iend; short *iend;
register core *sp; core *sp;
register int found; int found;
int n; int n;
#ifdef TRACE #if TRACE
fprintf(stderr, "Entering get_state, symbol = %d\n", symbol); fprintf (stderr, "Entering get_state, symbol = %d\n", symbol);
#endif #endif
isp1 = kernel_base[symbol]; isp1 = kernel_base[symbol];
@@ -338,73 +293,68 @@ get_state (int symbol)
{ {
sp = sp->link; sp = sp->link;
} }
else /* bucket exhausted and no match */ else /* bucket exhausted and no match */
{ {
sp = sp->link = new_state(symbol); sp = sp->link = new_state (symbol);
found = 1; found = 1;
} }
} }
} }
} }
else /* bucket is empty */ else /* bucket is empty */
{ {
state_table[key] = sp = new_state(symbol); state_table[key] = sp = new_state (symbol);
} }
return sp->number; return sp->number;
} }
/*------------------------------------------------------------------.
| Use the information computed by new_itemsets to find the state |
| numbers reached by each shift transition from the current state. |
| |
| shiftset is set up as a vector of state numbers of those states. |
`------------------------------------------------------------------*/
static void
/* subroutine of get_state. create a new state for those items, if necessary. */ append_states (void)
static core *
new_state (int symbol)
{ {
register int n; int i;
register core *p; int j;
register short *isp1; int symbol;
register short *isp2;
register short *iend;
#ifdef TRACE #if TRACE
fprintf(stderr, "Entering new_state, symbol = %d\n", symbol); fprintf (stderr, "Entering append_states\n");
#endif #endif
if (nstates >= MAXSHORT) /* first sort shift_symbol into increasing order */
fatal (_("too many states (max %d)"), MAXSHORT);
isp1 = kernel_base[symbol]; for (i = 1; i < nshifts; i++)
iend = kernel_end[symbol]; {
n = iend - isp1; symbol = shift_symbol[i];
j = i;
while (j > 0 && shift_symbol[j - 1] > symbol)
{
shift_symbol[j] = shift_symbol[j - 1];
j--;
}
shift_symbol[j] = symbol;
}
p = (core *) xmalloc((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); for (i = 0; i < nshifts; i++)
p->accessing_symbol = symbol; {
p->number = nstates; symbol = shift_symbol[i];
p->nitems = n; shiftset[i] = get_state (symbol);
}
isp2 = p->items;
while (isp1 < iend)
*isp2++ = *isp1++;
last_state->next = p;
last_state = p;
nstates++;
return p;
} }
static void static void
initialize_states (void) new_states (void)
{ {
register core *p; core *p;
/* register unsigned *rp1; JF unused */
/* register unsigned *rp2; JF unused */
/* register unsigned *rend; JF unused */
p = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); p = (core *) xmalloc ((unsigned) (sizeof (core) - sizeof (short)));
first_state = last_state = this_state = p; first_state = last_state = this_state = p;
nstates = 1; nstates = 1;
} }
@@ -413,13 +363,13 @@ initialize_states (void)
static void static void
save_shifts (void) save_shifts (void)
{ {
register shifts *p; shifts *p;
register short *sp1; short *sp1;
register short *sp2; short *sp2;
register short *send; short *send;
p = (shifts *) xmalloc((unsigned) (sizeof(shifts) + p = (shifts *) xmalloc ((unsigned) (sizeof (shifts) +
(nshifts - 1) * sizeof(short))); (nshifts - 1) * sizeof (short)));
p->number = this_state->number; p->number = this_state->number;
p->nshifts = nshifts; p->nshifts = nshifts;
@@ -444,80 +394,52 @@ save_shifts (void)
} }
/*------------------------------------------------------------------.
| Subroutine of augment_automaton. Create the next-to-final state, |
| to which a shift has already been made in the initial state. |
`------------------------------------------------------------------*/
/* find which rules can be used for reduction transitions from the current state
and make a reductions structure for the state to record their rule numbers. */
static void static void
save_reductions (void) insert_start_shift (void)
{ {
register short *isp; core *statep;
register short *rp1; shifts *sp;
register short *rp2;
register int item;
register int count;
register reductions *p;
short *rend; statep = (core *) xmalloc ((unsigned) (sizeof (core) - sizeof (short)));
statep->number = nstates;
statep->accessing_symbol = start_symbol;
/* find and count the active items that represent ends of rules */ last_state->next = statep;
last_state = statep;
count = 0; /* Make a shift from this state to (what will be) the final state. */
for (isp = itemset; isp < itemsetend; isp++) sp = NEW (shifts);
{ sp->number = nstates++;
item = ritem[*isp]; sp->nshifts = 1;
if (item < 0) sp->shifts[0] = nstates;
{
redset[count++] = -item;
}
}
/* make a reductions structure and copy the data into it. */ last_shift->next = sp;
last_shift = sp;
if (count)
{
p = (reductions *) xmalloc((unsigned) (sizeof(reductions) +
(count - 1) * sizeof(short)));
p->number = this_state->number;
p->nreds = count;
rp1 = redset;
rp2 = p->rules;
rend = rp1 + count;
while (rp1 < rend)
*rp2++ = *rp1++;
if (last_reduction)
{
last_reduction->next = p;
last_reduction = p;
}
else
{
first_reduction = p;
last_reduction = p;
}
}
} }
/*------------------------------------------------------------------.
| Make sure that the initial state has a shift that accepts the |
| grammar's start symbol and goes to the next-to-final state, which |
| has a shift going to the final state, which has a shift to the |
| termination state. Create such states and shifts if they don't |
| happen to exist already. |
`------------------------------------------------------------------*/
/* Make sure that the initial state has a shift that accepts the
grammar's start symbol and goes to the next-to-final state,
which has a shift going to the final state, which has a shift
to the termination state.
Create such states and shifts if they don't happen to exist already. */
static void static void
augment_automaton (void) augment_automaton (void)
{ {
register int i; int i;
register int k; int k;
/* register int found; JF unused */ core *statep;
register core *statep; shifts *sp;
register shifts *sp; shifts *sp2;
register shifts *sp2; shifts *sp1 = NULL;
register shifts *sp1 = NULL;
sp = first_shift; sp = first_shift;
@@ -531,13 +453,13 @@ augment_automaton (void)
/* The states reached by shifts from first_state are numbered 1...K. /* The states reached by shifts from first_state are numbered 1...K.
Look for one reached by start_symbol. */ Look for one reached by start_symbol. */
while (statep->accessing_symbol < start_symbol while (statep->accessing_symbol < start_symbol
&& statep->number < k) && statep->number < k)
statep = statep->next; statep = statep->next;
if (statep->accessing_symbol == start_symbol) if (statep->accessing_symbol == start_symbol)
{ {
/* We already have a next-to-final state. /* We already have a next-to-final state.
Make sure it has a shift to what will be the final state. */ Make sure it has a shift to what will be the final state. */
k = statep->number; k = statep->number;
while (sp && sp->number < k) while (sp && sp->number < k)
@@ -548,8 +470,10 @@ augment_automaton (void)
if (sp && sp->number == k) if (sp && sp->number == k)
{ {
sp2 = (shifts *) xmalloc((unsigned) (sizeof(shifts) sp2 = (shifts *) xmalloc ((unsigned) (sizeof (shifts)
+ sp->nshifts * sizeof(short))); +
sp->nshifts *
sizeof (short)));
sp2->number = k; sp2->number = k;
sp2->nshifts = sp->nshifts + 1; sp2->nshifts = sp->nshifts + 1;
sp2->shifts[0] = nstates; sp2->shifts[0] = nstates;
@@ -562,11 +486,11 @@ augment_automaton (void)
sp1->next = sp2; sp1->next = sp2;
if (sp == last_shift) if (sp == last_shift)
last_shift = sp2; last_shift = sp2;
FREE(sp); FREE (sp);
} }
else else
{ {
sp2 = NEW(shifts); sp2 = NEW (shifts);
sp2->number = k; sp2->number = k;
sp2->nshifts = 1; sp2->nshifts = 1;
sp2->shifts[0] = nstates; sp2->shifts[0] = nstates;
@@ -582,11 +506,11 @@ augment_automaton (void)
{ {
/* There is no next-to-final state as yet. */ /* There is no next-to-final state as yet. */
/* Add one more shift in first_shift, /* Add one more shift in first_shift,
going to the next-to-final state (yet to be made). */ going to the next-to-final state (yet to be made). */
sp = first_shift; sp = first_shift;
sp2 = (shifts *) xmalloc(sizeof(shifts) sp2 = (shifts *) xmalloc (sizeof (shifts)
+ sp->nshifts * sizeof(short)); + sp->nshifts * sizeof (short));
sp2->nshifts = sp->nshifts + 1; sp2->nshifts = sp->nshifts + 1;
/* Stick this shift into the vector at the proper place. */ /* Stick this shift into the vector at the proper place. */
@@ -602,24 +526,24 @@ augment_automaton (void)
sp2->shifts[k++] = nstates; sp2->shifts[k++] = nstates;
/* Patch sp2 into the chain of shifts /* Patch sp2 into the chain of shifts
in place of sp, at the beginning. */ in place of sp, at the beginning. */
sp2->next = sp->next; sp2->next = sp->next;
first_shift = sp2; first_shift = sp2;
if (last_shift == sp) if (last_shift == sp)
last_shift = sp2; last_shift = sp2;
FREE(sp); FREE (sp);
/* Create the next-to-final state, with shift to /* Create the next-to-final state, with shift to
what will be the final state. */ what will be the final state. */
insert_start_shift(); insert_start_shift ();
} }
} }
else else
{ {
/* The initial state didn't even have any shifts. /* The initial state didn't even have any shifts.
Give it one shift, to the next-to-final state. */ Give it one shift, to the next-to-final state. */
sp = NEW(shifts); sp = NEW (shifts);
sp->nshifts = 1; sp->nshifts = 1;
sp->shifts[0] = nstates; sp->shifts[0] = nstates;
@@ -629,15 +553,15 @@ augment_automaton (void)
/* Create the next-to-final state, with shift to /* Create the next-to-final state, with shift to
what will be the final state. */ what will be the final state. */
insert_start_shift(); insert_start_shift ();
} }
} }
else else
{ {
/* There are no shifts for any state. /* There are no shifts for any state.
Make one shift, from the initial state to the next-to-final state. */ Make one shift, from the initial state to the next-to-final state. */
sp = NEW(shifts); sp = NEW (shifts);
sp->nshifts = 1; sp->nshifts = 1;
sp->shifts[0] = nstates; sp->shifts[0] = nstates;
@@ -646,20 +570,20 @@ augment_automaton (void)
last_shift = sp; last_shift = sp;
/* Create the next-to-final state, with shift to /* Create the next-to-final state, with shift to
what will be the final state. */ what will be the final state. */
insert_start_shift(); insert_start_shift ();
} }
/* Make the final state--the one that follows a shift from the /* Make the final state--the one that follows a shift from the
next-to-final state. next-to-final state.
The symbol for that shift is 0 (end-of-file). */ The symbol for that shift is 0 (end-of-file). */
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep = (core *) xmalloc ((unsigned) (sizeof (core) - sizeof (short)));
statep->number = nstates; statep->number = nstates;
last_state->next = statep; last_state->next = statep;
last_state = statep; last_state = statep;
/* Make the shift from the final state to the termination state. */ /* Make the shift from the final state to the termination state. */
sp = NEW(shifts); sp = NEW (shifts);
sp->number = nstates++; sp->number = nstates++;
sp->nshifts = 1; sp->nshifts = 1;
sp->shifts[0] = nstates; sp->shifts[0] = nstates;
@@ -671,35 +595,111 @@ augment_automaton (void)
final_state = nstates; final_state = nstates;
/* Make the termination state. */ /* Make the termination state. */
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); statep = (core *) xmalloc ((unsigned) (sizeof (core) - sizeof (short)));
statep->number = nstates++; statep->number = nstates++;
last_state->next = statep; last_state->next = statep;
last_state = statep; last_state = statep;
} }
/* subroutine of augment_automaton. /*----------------------------------------------------------------.
Create the next-to-final state, to which a shift has already been made in | Find which rules can be used for reduction transitions from the |
the initial state. */ | current state and make a reductions structure for the state to |
| record their rule numbers. |
`----------------------------------------------------------------*/
static void static void
insert_start_shift (void) save_reductions (void)
{ {
register core *statep; short *isp;
register shifts *sp; short *rp1;
short *rp2;
int item;
int count;
reductions *p;
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short))); short *rend;
statep->number = nstates;
statep->accessing_symbol = start_symbol;
last_state->next = statep; /* Find and count the active items that represent ends of rules. */
last_state = statep;
/* Make a shift from this state to (what will be) the final state. */ count = 0;
sp = NEW(shifts); for (isp = itemset; isp < itemsetend; isp++)
sp->number = nstates++; {
sp->nshifts = 1; item = ritem[*isp];
sp->shifts[0] = nstates; if (item < 0)
redset[count++] = -item;
}
last_shift->next = sp; /* Make a reductions structure and copy the data into it. */
last_shift = sp;
if (count)
{
p = (reductions *) xmalloc ((unsigned) (sizeof (reductions) +
(count - 1) * sizeof (short)));
p->number = this_state->number;
p->nreds = count;
rp1 = redset;
rp2 = p->rules;
rend = rp1 + count;
for (/* nothing */; rp1 < rend; ++rp1, ++rp2)
*rp2 = *rp1;
if (last_reduction)
{
last_reduction->next = p;
last_reduction = p;
}
else
{
first_reduction = p;
last_reduction = p;
}
}
}
/*-------------------------------------------------------------------.
| Compute the nondeterministic finite state machine (see state.h for |
| details) from the grammar. |
`-------------------------------------------------------------------*/
void
generate_states (void)
{
allocate_storage ();
new_closure (nitems);
new_states ();
while (this_state)
{
/* Set up ruleset and itemset for the transitions out of this
state. ruleset gets a 1 bit for each rule that could reduce
now. itemset gets a vector of all the items that could be
accepted next. */
closure (this_state->items, this_state->nitems);
/* record the reductions allowed out of this state */
save_reductions ();
/* find the itemsets of the states that shifts can reach */
new_itemsets ();
/* find or create the core structures for those states */
append_states ();
/* create the shifts structures for the shifts to those states,
now that the state numbers transitioning to are known */
if (nshifts > 0)
save_shifts ();
/* states are queued when they are created; process them all */
this_state = this_state->next;
}
/* discard various storage */
free_closure ();
free_storage ();
/* set up initial and final states as parser wants them */
augment_automaton ();
} }

View File

@@ -18,8 +18,10 @@ bison_SOURCES = LR0.c allocate.c closure.c complain.c conflicts.c \
EXTRA_bison_SOURCES = vmsgetargs.c EXTRA_bison_SOURCES = vmsgetargs.c
noinst_HEADERS = alloc.h complain.h files.h getargs.h gram.h lex.h \ noinst_HEADERS = alloc.h closure.h complain.h \
derives.h state.h \ derives.h \
files.h getargs.h gram.h lex.h \
state.h \
symtab.h system.h types.h symtab.h system.h types.h
data_DATA = bison.simple bison.hairy data_DATA = bison.simple bison.hairy

View File

@@ -19,52 +19,15 @@
02111-1307, USA. */ 02111-1307, USA. */
/* Subroutines of file LR0.c.
Entry points:
closure (items, n)
Given a vector of item numbers items, of length n, set up ruleset and
itemset to indicate what rules could be run and which items could be
accepted when those items are the active ones.
ruleset contains a bit for each rule. closure sets the bits for all
rules which could potentially describe the next input to be read.
itemset is a vector of item numbers; itemsetend points to just beyond
the end of the part of it that is significant. closure places there
the indices of all items which represent units of input that could
arrive next.
initialize_closure (n)
Allocates the itemset and ruleset vectors, and precomputes useful data
so that closure can be called. n is the number of elements to
allocate for itemset.
finalize_closure ()
Frees itemset, ruleset and internal data.
*/
#include "system.h" #include "system.h"
#include "alloc.h" #include "alloc.h"
#include "gram.h" #include "gram.h"
#include "closure.h"
extern short **derives; extern short **derives;
extern char **tags; extern char **tags;
extern void initialize_closure PARAMS((int)); extern void RTC PARAMS ((unsigned *, int));
extern void closure PARAMS((short *, int));
extern void finalize_closure PARAMS((void));
static void set_fderives PARAMS((void));
static void set_firsts PARAMS((void));
extern void RTC PARAMS((unsigned *, int));
short *itemset; short *itemset;
short *itemsetend; short *itemsetend;
@@ -79,47 +42,143 @@ static int rulesetsize;
/* number of words required to hold a bit for each variable */ /* number of words required to hold a bit for each variable */
static int varsetsize; static int varsetsize;
#if DEBUG
#ifdef DEBUG /*-----------------.
static void print_closure PARAMS((int)); | Debugging code. |
static void print_fderives PARAMS((void)); `-----------------*/
static void print_firsts PARAMS((void));
#endif
void static void
initialize_closure (int n) print_closure (int n)
{ {
itemset = NEW2(n, short); short *isp;
rulesetsize = WORDSIZE(nrules + 1); printf ("\n\nn = %d\n\n", n);
ruleset = NEW2(rulesetsize, unsigned); for (isp = itemset; isp < itemsetend; isp++)
printf (" %d\n", *isp);
set_fderives();
} }
static void
print_firsts (void)
{
int i;
int j;
unsigned *rowp;
printf ("\n\n\nFIRSTS\n\n");
for (i = ntokens; i < nsyms; i++)
{
printf ("\n\n%s firsts\n\n", tags[i]);
rowp = firsts + ((i - ntokens) * varsetsize);
for (j = 0; j < nvars; j++)
if (BITISSET (rowp, j))
printf (" %s\n", tags[j + ntokens]);
}
}
static void
print_fderives (void)
{
int i;
int j;
unsigned *rp;
printf ("\n\n\nFDERIVES\n");
for (i = ntokens; i < nsyms; i++)
{
printf ("\n\n%s derives\n\n", tags[i]);
rp = fderives + i * rulesetsize;
for (j = 0; j <= nrules; j++)
if (BITISSET (rp, j))
printf (" %d\n", j);
}
fflush (stdout);
}
#endif
/*-------------------------------------------------------------------.
| Set FIRSTS to be an NVARS by NVARS bit matrix indicating which |
| items can represent the beginning of the input corresponding to |
| which other items. |
| |
| For example, if some rule expands symbol 5 into the sequence of |
| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
| symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is set. |
`-------------------------------------------------------------------*/
static void
set_firsts (void)
{
unsigned *row;
int symbol;
short *sp;
int rowsize;
int i;
varsetsize = rowsize = WORDSIZE (nvars);
firsts = NEW2 (nvars * rowsize, unsigned);
row = firsts;
for (i = ntokens; i < nsyms; i++)
{
sp = derives[i];
while (*sp >= 0)
{
symbol = ritem[rrhs[*sp++]];
if (ISVAR (symbol))
{
symbol -= ntokens;
SETBIT (row, symbol);
}
}
row += rowsize;
}
RTC (firsts, nvars);
#ifdef DEBUG
print_firsts ();
#endif
}
/*-------------------------------------------------------------------.
| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
| rules can help derive the beginning of the data for each |
| nonterminal. |
| |
| For example, if symbol 5 can be derived as the sequence of symbols |
| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
`-------------------------------------------------------------------*/
/* set fderives to an nvars by nrules matrix of bits
indicating which rules can help derive the beginning of the data
for each nonterminal. For example, if symbol 5 can be derived as
the sequence of symbols 8 3 20, and one of the rules for deriving
symbol 8 is rule 4, then the [5 - ntokens, 4] bit in fderives is set. */
static void static void
set_fderives (void) set_fderives (void)
{ {
register unsigned *rrow; unsigned *rrow;
register unsigned *vrow; unsigned *vrow;
register int j; int j;
register unsigned cword; unsigned cword;
register short *rp; short *rp;
register int b; int b;
int ruleno; int ruleno;
int i; int i;
fderives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize; fderives = NEW2 (nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
set_firsts(); set_firsts ();
rrow = fderives + ntokens * rulesetsize; rrow = fderives + ntokens * rulesetsize;
@@ -135,7 +194,7 @@ set_fderives (void)
rp = derives[j]; rp = derives[j];
while ((ruleno = *rp++) > 0) while ((ruleno = *rp++) > 0)
{ {
SETBIT(rrow, ruleno); SETBIT (rrow, ruleno);
} }
} }
@@ -151,71 +210,34 @@ set_fderives (void)
} }
#ifdef DEBUG #ifdef DEBUG
print_fderives(); print_fderives ();
#endif #endif
FREE(firsts); FREE (firsts);
} }
void
new_closure (int n)
/* set firsts to be an nvars by nvars bit matrix indicating which
items can represent the beginning of the input corresponding to
which other items.
For example, if some rule expands symbol 5 into the sequence of
symbols 8 3 20, the symbol 8 can be the beginning of the data for
symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is
set. */
static void
set_firsts (void)
{ {
register unsigned *row; itemset = NEW2 (n, short);
/* register int done; JF unused */
register int symbol;
register short *sp;
register int rowsize;
int i; rulesetsize = WORDSIZE (nrules + 1);
ruleset = NEW2 (rulesetsize, unsigned);
varsetsize = rowsize = WORDSIZE(nvars); set_fderives ();
firsts = NEW2(nvars * rowsize, unsigned);
row = firsts;
for (i = ntokens; i < nsyms; i++)
{
sp = derives[i];
while (*sp >= 0)
{
symbol = ritem[rrhs[*sp++]];
if (ISVAR(symbol))
{
symbol -= ntokens;
SETBIT(row, symbol);
}
}
row += rowsize;
}
RTC(firsts, nvars);
#ifdef DEBUG
print_firsts ();
#endif
} }
void void
closure (short *core, int n) closure (short *core, int n)
{ {
register int ruleno; int ruleno;
register unsigned word; unsigned word;
register short *csp; short *csp;
register unsigned *dsp; unsigned *dsp;
register unsigned *rsp; unsigned *rsp;
short *csend; short *csend;
unsigned *rsend; unsigned *rsend;
@@ -241,7 +263,7 @@ closure (short *core, int n)
while (csp < csend) while (csp < csend)
{ {
symbol = ritem[*csp++]; symbol = ritem[*csp++];
if (ISVAR(symbol)) if (ISVAR (symbol))
{ {
dsp = fderives + symbol * rulesetsize; dsp = fderives + symbol * rulesetsize;
rsp = ruleset; rsp = ruleset;
@@ -264,7 +286,7 @@ closure (short *core, int n)
} }
else else
{ {
register int b; int b;
for (b = 0; b < BITS_PER_WORD; b++) for (b = 0; b < BITS_PER_WORD; b++)
{ {
@@ -284,77 +306,16 @@ closure (short *core, int n)
while (csp < csend) while (csp < csend)
*itemsetend++ = *csp++; *itemsetend++ = *csp++;
#ifdef DEBUG #if DEBUG
print_closure(n); print_closure (n);
#endif #endif
} }
void void
finalize_closure (void) free_closure (void)
{ {
FREE(itemset); FREE (itemset);
FREE(ruleset); FREE (ruleset);
FREE(fderives + ntokens * rulesetsize); FREE (fderives + ntokens * rulesetsize);
} }
#ifdef DEBUG
static void
print_closure(int n)
{
register short *isp;
printf ("\n\nn = %d\n\n", n);
for (isp = itemset; isp < itemsetend; isp++)
printf (" %d\n", *isp);
}
static void
print_firsts (void)
{
register int i;
register int j;
register unsigned *rowp;
printf ("\n\n\nFIRSTS\n\n");
for (i = ntokens; i < nsyms; i++)
{
printf ("\n\n%s firsts\n\n", tags[i]);
rowp = firsts + ((i - ntokens) * varsetsize);
for (j = 0; j < nvars; j++)
if (BITISSET (rowp, j))
printf (" %s\n", tags[j + ntokens]);
}
}
static void
print_fderives (void)
{
register int i;
register int j;
register unsigned *rp;
printf ("\n\n\nFDERIVES\n");
for (i = ntokens; i < nsyms; i++)
{
printf ("\n\n%s derives\n\n", tags[i]);
rp = fderives + i * rulesetsize;
for (j = 0; j <= nrules; j++)
if (BITISSET (rp, j))
printf (" %d\n", j);
}
fflush(stdout);
}
#endif