* 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)"

476
src/LR0.c
View File

@@ -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;
@@ -42,22 +42,6 @@ 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;
static shifts *last_shift; static shifts *last_shift;
@@ -78,16 +62,15 @@ 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);
@@ -104,8 +87,8 @@ 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. */
@@ -150,64 +133,29 @@ free_storage (void)
/* 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
@@ -242,62 +190,69 @@ 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
@@ -354,55 +309,50 @@ get_state (int 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;
@@ -413,10 +363,10 @@ 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)));
@@ -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;
@@ -549,7 +471,9 @@ 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;
@@ -678,28 +602,104 @@ augment_automaton (void)
} }
/* 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; }
last_shift = sp;
/* Make a reductions structure and copy the data into it. */
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,51 +19,14 @@
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 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)); extern void RTC PARAMS ((unsigned *, int));
short *itemset; short *itemset;
@@ -79,40 +42,136 @@ 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;
@@ -156,66 +215,29 @@ set_fderives (void)
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;
@@ -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