mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
* 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:
13
ChangeLog
13
ChangeLog
@@ -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>
|
||||
|
||||
* src/acconfig.h: Don't protect config.h against multiple
|
||||
|
||||
4
po/de.po
4
po/de.po
@@ -5,7 +5,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Ulrich Drepper <drepper@gnu.ai.mit.edu>\n"
|
||||
"Language-Team: German <de@li.org>\n"
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
#: src/LR0.c:375
|
||||
#: src/LR0.c:212
|
||||
#, c-format
|
||||
msgid "too many states (max %d)"
|
||||
msgstr ""
|
||||
|
||||
4
po/es.po
4
po/es.po
@@ -30,7 +30,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Nicolás García-Pedrajas <ngarcia-pedrajas@acm.org>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
@@ -38,7 +38,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
#: src/LR0.c:375
|
||||
#: src/LR0.c:212
|
||||
#, c-format
|
||||
msgid "too many states (max %d)"
|
||||
msgstr ""
|
||||
|
||||
4
po/et.po
4
po/et.po
@@ -5,7 +5,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Toomas Soome <tsoome@ut.ee>\n"
|
||||
"Language-Team: Estonian <et@li.org>\n"
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=ISO-8859-15\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
#: src/LR0.c:375
|
||||
#: src/LR0.c:212
|
||||
#, c-format
|
||||
msgid "too many states (max %d)"
|
||||
msgstr "liiga palju olekuid (maks %d)"
|
||||
|
||||
4
po/fr.po
4
po/fr.po
@@ -5,7 +5,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Dominique Boucher <boucherd@IRO.UMontreal.CA>\n"
|
||||
"Language-Team: French <fr@li.org>\n"
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
#: src/LR0.c:375
|
||||
#: src/LR0.c:212
|
||||
#, c-format
|
||||
msgid "too many states (max %d)"
|
||||
msgstr ""
|
||||
|
||||
4
po/ja.po
4
po/ja.po
@@ -5,7 +5,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Daisuke Yamashita <yamad@mb.infoweb.ne.jp>\n"
|
||||
"Language-Team: Japanese <ja@li.org>\n"
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=EUC-JP\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/LR0.c:375
|
||||
#: src/LR0.c:212
|
||||
#, fuzzy, c-format
|
||||
msgid "too many states (max %d)"
|
||||
msgstr "%s の数が多すぎます (最大 %d)"
|
||||
|
||||
4
po/nl.po
4
po/nl.po
@@ -5,7 +5,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Erick Branderhorst <branderh@debian.org>\n"
|
||||
"Language-Team: Dutch <nl@li.org>\n"
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=ISO-8859-1\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
#: src/LR0.c:375
|
||||
#: src/LR0.c:212
|
||||
#, c-format
|
||||
msgid "too many states (max %d)"
|
||||
msgstr ""
|
||||
|
||||
4
po/ru.po
4
po/ru.po
@@ -5,7 +5,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Dmitry S. Sivachenko <dima@Chg.RU>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
@@ -13,7 +13,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=koi8-r\n"
|
||||
"Content-Transfer-Encoding: 8-bit\n"
|
||||
|
||||
#: src/LR0.c:375
|
||||
#: src/LR0.c:212
|
||||
#, c-format
|
||||
msgid "too many states (max %d)"
|
||||
msgstr "ÓÌÉÛËÏÍ ÍÎÏÇÏ ÓÏÓÔÏÑÎÉÊ (ÍÁËÓÉÍÁÌØÎÏ %d)"
|
||||
|
||||
600
src/LR0.c
600
src/LR0.c
@@ -1,22 +1,22 @@
|
||||
/* Generate the nondeterministic finite state machine for bison,
|
||||
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
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
Bison is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
Bison is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
Bison is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bison; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bison; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
/* 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 "state.h"
|
||||
#include "complain.h"
|
||||
|
||||
#include "closure.h"
|
||||
|
||||
extern char *nullable;
|
||||
extern short *itemset;
|
||||
@@ -40,23 +40,7 @@ core *first_state;
|
||||
shifts *first_shift;
|
||||
reductions *first_reduction;
|
||||
|
||||
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));
|
||||
extern void generate_states PARAMS ((void));
|
||||
|
||||
static core *this_state;
|
||||
static core *last_state;
|
||||
@@ -78,19 +62,18 @@ static short *kernel_items;
|
||||
#define STATE_TABLE_SIZE 1009
|
||||
static core **state_table;
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
allocate_itemsets (void)
|
||||
{
|
||||
register short *itemp;
|
||||
register int symbol;
|
||||
register int i;
|
||||
register int count;
|
||||
register short *symbol_count;
|
||||
short *itemp;
|
||||
int symbol;
|
||||
int i;
|
||||
int count;
|
||||
short *symbol_count;
|
||||
|
||||
count = 0;
|
||||
symbol_count = NEW2(nsyms, short);
|
||||
symbol_count = NEW2 (nsyms, short);
|
||||
|
||||
itemp = ritem;
|
||||
symbol = *itemp++;
|
||||
@@ -104,14 +87,14 @@ allocate_itemsets (void)
|
||||
symbol = *itemp++;
|
||||
}
|
||||
|
||||
/* see comments before new_itemsets. All the vectors of items
|
||||
live inside kernel_items. The number of active items after
|
||||
/* See comments before new_itemsets. All the vectors of items
|
||||
live inside KERNEL_ITEMS. The number of active items after
|
||||
some symbol cannot be more than the number of times that symbol
|
||||
appears as an item, which is symbol_count[symbol].
|
||||
We allocate that much space for each symbol. */
|
||||
|
||||
kernel_base = NEW2(nsyms, short *);
|
||||
kernel_items = NEW2(count, short);
|
||||
kernel_base = NEW2 (nsyms, short *);
|
||||
kernel_items = NEW2 (count, short);
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < nsyms; i++)
|
||||
@@ -121,94 +104,59 @@ allocate_itemsets (void)
|
||||
}
|
||||
|
||||
shift_symbol = symbol_count;
|
||||
kernel_end = NEW2(nsyms, short *);
|
||||
kernel_end = NEW2 (nsyms, short *);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
allocate_storage (void)
|
||||
{
|
||||
allocate_itemsets();
|
||||
allocate_itemsets ();
|
||||
|
||||
shiftset = NEW2(nsyms, short);
|
||||
redset = NEW2(nrules + 1, short);
|
||||
state_table = NEW2(STATE_TABLE_SIZE, core *);
|
||||
shiftset = NEW2 (nsyms, short);
|
||||
redset = NEW2 (nrules + 1, short);
|
||||
state_table = NEW2 (STATE_TABLE_SIZE, core *);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_storage (void)
|
||||
{
|
||||
FREE(shift_symbol);
|
||||
FREE(redset);
|
||||
FREE(shiftset);
|
||||
FREE(kernel_base);
|
||||
FREE(kernel_end);
|
||||
FREE(kernel_items);
|
||||
FREE(state_table);
|
||||
FREE (shift_symbol);
|
||||
FREE (redset);
|
||||
FREE (shiftset);
|
||||
FREE (kernel_base);
|
||||
FREE (kernel_end);
|
||||
FREE (kernel_items);
|
||||
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)
|
||||
{
|
||||
/* 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();
|
||||
/*----------------------------------------------------------------.
|
||||
| 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. |
|
||||
`----------------------------------------------------------------*/
|
||||
|
||||
/* 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
|
||||
new_itemsets (void)
|
||||
{
|
||||
register int i;
|
||||
register int shiftcount;
|
||||
register short *isp;
|
||||
register short *ksp;
|
||||
register int symbol;
|
||||
int i;
|
||||
int shiftcount;
|
||||
short *isp;
|
||||
short *ksp;
|
||||
int symbol;
|
||||
|
||||
#ifdef TRACE
|
||||
fprintf(stderr, "Entering new_itemsets\n");
|
||||
#if TRACE
|
||||
fprintf (stderr, "Entering new_itemsets\n");
|
||||
#endif
|
||||
|
||||
for (i = 0; i < nsyms; i++)
|
||||
@@ -224,16 +172,16 @@ new_itemsets (void)
|
||||
symbol = ritem[i];
|
||||
if (symbol > 0)
|
||||
{
|
||||
ksp = kernel_end[symbol];
|
||||
ksp = kernel_end[symbol];
|
||||
|
||||
if (!ksp)
|
||||
if (!ksp)
|
||||
{
|
||||
shift_symbol[shiftcount++] = symbol;
|
||||
ksp = kernel_base[symbol];
|
||||
}
|
||||
|
||||
*ksp++ = i + 1;
|
||||
kernel_end[symbol] = ksp;
|
||||
*ksp++ = i + 1;
|
||||
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 void
|
||||
append_states (void)
|
||||
static core *
|
||||
new_state (int symbol)
|
||||
{
|
||||
register int i;
|
||||
register int j;
|
||||
register int symbol;
|
||||
int n;
|
||||
core *p;
|
||||
short *isp1;
|
||||
short *isp2;
|
||||
short *iend;
|
||||
|
||||
#ifdef TRACE
|
||||
fprintf(stderr, "Entering append_states\n");
|
||||
#if TRACE
|
||||
fprintf (stderr, "Entering new_state, symbol = %d\n", symbol);
|
||||
#endif
|
||||
|
||||
/* first sort shift_symbol into increasing order */
|
||||
if (nstates >= MAXSHORT)
|
||||
fatal (_("too many states (max %d)"), MAXSHORT);
|
||||
|
||||
for (i = 1; i < nshifts; i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
isp1 = kernel_base[symbol];
|
||||
iend = kernel_end[symbol];
|
||||
n = iend - isp1;
|
||||
|
||||
for (i = 0; i < nshifts; i++)
|
||||
{
|
||||
symbol = shift_symbol[i];
|
||||
shiftset[i] = get_state(symbol);
|
||||
}
|
||||
p =
|
||||
(core *) xmalloc ((unsigned) (sizeof (core) + (n - 1) * sizeof (short)));
|
||||
p->accessing_symbol = 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
|
||||
(from the current state) by shifting symbol.
|
||||
Create a new state if no equivalent one exists already.
|
||||
Used by append_states */
|
||||
/*--------------------------------------------------------------.
|
||||
| Find the state number for the state we would get to (from the |
|
||||
| current state) by shifting symbol. Create a new state if no |
|
||||
| equivalent one exists already. Used by append_states. |
|
||||
`--------------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
get_state (int symbol)
|
||||
{
|
||||
register int key;
|
||||
register short *isp1;
|
||||
register short *isp2;
|
||||
register short *iend;
|
||||
register core *sp;
|
||||
register int found;
|
||||
int key;
|
||||
short *isp1;
|
||||
short *isp2;
|
||||
short *iend;
|
||||
core *sp;
|
||||
int found;
|
||||
|
||||
int n;
|
||||
|
||||
#ifdef TRACE
|
||||
fprintf(stderr, "Entering get_state, symbol = %d\n", symbol);
|
||||
#if TRACE
|
||||
fprintf (stderr, "Entering get_state, symbol = %d\n", symbol);
|
||||
#endif
|
||||
|
||||
isp1 = kernel_base[symbol];
|
||||
@@ -338,73 +293,68 @@ get_state (int symbol)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| 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. |
|
||||
`------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* subroutine of get_state. create a new state for those items, if necessary. */
|
||||
|
||||
static core *
|
||||
new_state (int symbol)
|
||||
static void
|
||||
append_states (void)
|
||||
{
|
||||
register int n;
|
||||
register core *p;
|
||||
register short *isp1;
|
||||
register short *isp2;
|
||||
register short *iend;
|
||||
int i;
|
||||
int j;
|
||||
int symbol;
|
||||
|
||||
#ifdef TRACE
|
||||
fprintf(stderr, "Entering new_state, symbol = %d\n", symbol);
|
||||
#if TRACE
|
||||
fprintf (stderr, "Entering append_states\n");
|
||||
#endif
|
||||
|
||||
if (nstates >= MAXSHORT)
|
||||
fatal (_("too many states (max %d)"), MAXSHORT);
|
||||
/* first sort shift_symbol into increasing order */
|
||||
|
||||
isp1 = kernel_base[symbol];
|
||||
iend = kernel_end[symbol];
|
||||
n = iend - isp1;
|
||||
for (i = 1; i < nshifts; i++)
|
||||
{
|
||||
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)));
|
||||
p->accessing_symbol = 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;
|
||||
for (i = 0; i < nshifts; i++)
|
||||
{
|
||||
symbol = shift_symbol[i];
|
||||
shiftset[i] = get_state (symbol);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
initialize_states (void)
|
||||
new_states (void)
|
||||
{
|
||||
register core *p;
|
||||
/* register unsigned *rp1; JF unused */
|
||||
/* register unsigned *rp2; JF unused */
|
||||
/* register unsigned *rend; JF unused */
|
||||
core *p;
|
||||
|
||||
p = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
|
||||
p = (core *) xmalloc ((unsigned) (sizeof (core) - sizeof (short)));
|
||||
first_state = last_state = this_state = p;
|
||||
nstates = 1;
|
||||
}
|
||||
@@ -413,13 +363,13 @@ initialize_states (void)
|
||||
static void
|
||||
save_shifts (void)
|
||||
{
|
||||
register shifts *p;
|
||||
register short *sp1;
|
||||
register short *sp2;
|
||||
register short *send;
|
||||
shifts *p;
|
||||
short *sp1;
|
||||
short *sp2;
|
||||
short *send;
|
||||
|
||||
p = (shifts *) xmalloc((unsigned) (sizeof(shifts) +
|
||||
(nshifts - 1) * sizeof(short)));
|
||||
p = (shifts *) xmalloc ((unsigned) (sizeof (shifts) +
|
||||
(nshifts - 1) * sizeof (short)));
|
||||
|
||||
p->number = this_state->number;
|
||||
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
|
||||
save_reductions (void)
|
||||
insert_start_shift (void)
|
||||
{
|
||||
register short *isp;
|
||||
register short *rp1;
|
||||
register short *rp2;
|
||||
register int item;
|
||||
register int count;
|
||||
register reductions *p;
|
||||
core *statep;
|
||||
shifts *sp;
|
||||
|
||||
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;
|
||||
for (isp = itemset; isp < itemsetend; isp++)
|
||||
{
|
||||
item = ritem[*isp];
|
||||
if (item < 0)
|
||||
{
|
||||
redset[count++] = -item;
|
||||
}
|
||||
}
|
||||
/* Make a shift from this state to (what will be) the final state. */
|
||||
sp = NEW (shifts);
|
||||
sp->number = nstates++;
|
||||
sp->nshifts = 1;
|
||||
sp->shifts[0] = nstates;
|
||||
|
||||
/* 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;
|
||||
|
||||
while (rp1 < rend)
|
||||
*rp2++ = *rp1++;
|
||||
|
||||
if (last_reduction)
|
||||
{
|
||||
last_reduction->next = p;
|
||||
last_reduction = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_reduction = p;
|
||||
last_reduction = p;
|
||||
}
|
||||
}
|
||||
last_shift->next = sp;
|
||||
last_shift = sp;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| 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
|
||||
augment_automaton (void)
|
||||
{
|
||||
register int i;
|
||||
register int k;
|
||||
/* register int found; JF unused */
|
||||
register core *statep;
|
||||
register shifts *sp;
|
||||
register shifts *sp2;
|
||||
register shifts *sp1 = NULL;
|
||||
int i;
|
||||
int k;
|
||||
core *statep;
|
||||
shifts *sp;
|
||||
shifts *sp2;
|
||||
shifts *sp1 = NULL;
|
||||
|
||||
sp = first_shift;
|
||||
|
||||
@@ -531,13 +453,13 @@ augment_automaton (void)
|
||||
/* The states reached by shifts from first_state are numbered 1...K.
|
||||
Look for one reached by start_symbol. */
|
||||
while (statep->accessing_symbol < start_symbol
|
||||
&& statep->number < k)
|
||||
&& statep->number < k)
|
||||
statep = statep->next;
|
||||
|
||||
if (statep->accessing_symbol == start_symbol)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
while (sp && sp->number < k)
|
||||
@@ -548,8 +470,10 @@ augment_automaton (void)
|
||||
|
||||
if (sp && sp->number == k)
|
||||
{
|
||||
sp2 = (shifts *) xmalloc((unsigned) (sizeof(shifts)
|
||||
+ sp->nshifts * sizeof(short)));
|
||||
sp2 = (shifts *) xmalloc ((unsigned) (sizeof (shifts)
|
||||
+
|
||||
sp->nshifts *
|
||||
sizeof (short)));
|
||||
sp2->number = k;
|
||||
sp2->nshifts = sp->nshifts + 1;
|
||||
sp2->shifts[0] = nstates;
|
||||
@@ -562,11 +486,11 @@ augment_automaton (void)
|
||||
sp1->next = sp2;
|
||||
if (sp == last_shift)
|
||||
last_shift = sp2;
|
||||
FREE(sp);
|
||||
FREE (sp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sp2 = NEW(shifts);
|
||||
sp2 = NEW (shifts);
|
||||
sp2->number = k;
|
||||
sp2->nshifts = 1;
|
||||
sp2->shifts[0] = nstates;
|
||||
@@ -582,11 +506,11 @@ augment_automaton (void)
|
||||
{
|
||||
/* There is no next-to-final state as yet. */
|
||||
/* 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;
|
||||
|
||||
sp2 = (shifts *) xmalloc(sizeof(shifts)
|
||||
+ sp->nshifts * sizeof(short));
|
||||
sp2 = (shifts *) xmalloc (sizeof (shifts)
|
||||
+ sp->nshifts * sizeof (short));
|
||||
sp2->nshifts = sp->nshifts + 1;
|
||||
|
||||
/* Stick this shift into the vector at the proper place. */
|
||||
@@ -602,24 +526,24 @@ augment_automaton (void)
|
||||
sp2->shifts[k++] = nstates;
|
||||
|
||||
/* 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;
|
||||
first_shift = sp2;
|
||||
if (last_shift == sp)
|
||||
last_shift = sp2;
|
||||
|
||||
FREE(sp);
|
||||
FREE (sp);
|
||||
|
||||
/* Create the next-to-final state, with shift to
|
||||
what will be the final state. */
|
||||
insert_start_shift();
|
||||
what will be the final state. */
|
||||
insert_start_shift ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The initial state didn't even have any shifts.
|
||||
Give it one shift, to the next-to-final state. */
|
||||
sp = NEW(shifts);
|
||||
sp = NEW (shifts);
|
||||
sp->nshifts = 1;
|
||||
sp->shifts[0] = nstates;
|
||||
|
||||
@@ -629,15 +553,15 @@ augment_automaton (void)
|
||||
|
||||
/* Create the next-to-final state, with shift to
|
||||
what will be the final state. */
|
||||
insert_start_shift();
|
||||
insert_start_shift ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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->shifts[0] = nstates;
|
||||
|
||||
@@ -646,20 +570,20 @@ augment_automaton (void)
|
||||
last_shift = sp;
|
||||
|
||||
/* Create the next-to-final state, with shift to
|
||||
what will be the final state. */
|
||||
insert_start_shift();
|
||||
what will be the final state. */
|
||||
insert_start_shift ();
|
||||
}
|
||||
|
||||
/* Make the final state--the one that follows a shift from the
|
||||
next-to-final state.
|
||||
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;
|
||||
last_state->next = statep;
|
||||
last_state = statep;
|
||||
|
||||
/* Make the shift from the final state to the termination state. */
|
||||
sp = NEW(shifts);
|
||||
sp = NEW (shifts);
|
||||
sp->number = nstates++;
|
||||
sp->nshifts = 1;
|
||||
sp->shifts[0] = nstates;
|
||||
@@ -671,35 +595,111 @@ augment_automaton (void)
|
||||
final_state = nstates;
|
||||
|
||||
/* Make the termination state. */
|
||||
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
|
||||
statep = (core *) xmalloc ((unsigned) (sizeof (core) - sizeof (short)));
|
||||
statep->number = nstates++;
|
||||
last_state->next = statep;
|
||||
last_state = statep;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
insert_start_shift (void)
|
||||
save_reductions (void)
|
||||
{
|
||||
register core *statep;
|
||||
register shifts *sp;
|
||||
short *isp;
|
||||
short *rp1;
|
||||
short *rp2;
|
||||
int item;
|
||||
int count;
|
||||
reductions *p;
|
||||
|
||||
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
|
||||
statep->number = nstates;
|
||||
statep->accessing_symbol = start_symbol;
|
||||
short *rend;
|
||||
|
||||
last_state->next = statep;
|
||||
last_state = statep;
|
||||
/* Find and count the active items that represent ends of rules. */
|
||||
|
||||
/* Make a shift from this state to (what will be) the final state. */
|
||||
sp = NEW(shifts);
|
||||
sp->number = nstates++;
|
||||
sp->nshifts = 1;
|
||||
sp->shifts[0] = nstates;
|
||||
count = 0;
|
||||
for (isp = itemset; isp < itemsetend; isp++)
|
||||
{
|
||||
item = ritem[*isp];
|
||||
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 ();
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ bison_SOURCES = LR0.c allocate.c closure.c complain.c conflicts.c \
|
||||
|
||||
EXTRA_bison_SOURCES = vmsgetargs.c
|
||||
|
||||
noinst_HEADERS = alloc.h complain.h files.h getargs.h gram.h lex.h \
|
||||
derives.h state.h \
|
||||
noinst_HEADERS = alloc.h closure.h complain.h \
|
||||
derives.h \
|
||||
files.h getargs.h gram.h lex.h \
|
||||
state.h \
|
||||
symtab.h system.h types.h
|
||||
|
||||
data_DATA = bison.simple bison.hairy
|
||||
|
||||
333
src/closure.c
333
src/closure.c
@@ -19,52 +19,15 @@
|
||||
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 "alloc.h"
|
||||
#include "gram.h"
|
||||
|
||||
#include "closure.h"
|
||||
|
||||
extern short **derives;
|
||||
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 *itemsetend;
|
||||
@@ -79,47 +42,143 @@ static int rulesetsize;
|
||||
|
||||
/* number of words required to hold a bit for each variable */
|
||||
static int varsetsize;
|
||||
|
||||
#if DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
static void print_closure PARAMS((int));
|
||||
static void print_fderives PARAMS((void));
|
||||
static void print_firsts PARAMS((void));
|
||||
#endif
|
||||
/*-----------------.
|
||||
| Debugging code. |
|
||||
`-----------------*/
|
||||
|
||||
void
|
||||
initialize_closure (int n)
|
||||
static void
|
||||
print_closure (int n)
|
||||
{
|
||||
itemset = NEW2(n, short);
|
||||
short *isp;
|
||||
|
||||
rulesetsize = WORDSIZE(nrules + 1);
|
||||
ruleset = NEW2(rulesetsize, unsigned);
|
||||
|
||||
set_fderives();
|
||||
printf ("\n\nn = %d\n\n", n);
|
||||
for (isp = itemset; isp < itemsetend; isp++)
|
||||
printf (" %d\n", *isp);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
set_fderives (void)
|
||||
{
|
||||
register unsigned *rrow;
|
||||
register unsigned *vrow;
|
||||
register int j;
|
||||
register unsigned cword;
|
||||
register short *rp;
|
||||
register int b;
|
||||
unsigned *rrow;
|
||||
unsigned *vrow;
|
||||
int j;
|
||||
unsigned cword;
|
||||
short *rp;
|
||||
int b;
|
||||
|
||||
int ruleno;
|
||||
int i;
|
||||
|
||||
fderives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
|
||||
fderives = NEW2 (nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
|
||||
|
||||
set_firsts();
|
||||
set_firsts ();
|
||||
|
||||
rrow = fderives + ntokens * rulesetsize;
|
||||
|
||||
@@ -135,7 +194,7 @@ set_fderives (void)
|
||||
rp = derives[j];
|
||||
while ((ruleno = *rp++) > 0)
|
||||
{
|
||||
SETBIT(rrow, ruleno);
|
||||
SETBIT (rrow, ruleno);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,71 +210,34 @@ set_fderives (void)
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
print_fderives();
|
||||
print_fderives ();
|
||||
#endif
|
||||
|
||||
FREE(firsts);
|
||||
FREE (firsts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* 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)
|
||||
void
|
||||
new_closure (int n)
|
||||
{
|
||||
register unsigned *row;
|
||||
/* register int done; JF unused */
|
||||
register int symbol;
|
||||
register short *sp;
|
||||
register int rowsize;
|
||||
itemset = NEW2 (n, short);
|
||||
|
||||
int i;
|
||||
rulesetsize = WORDSIZE (nrules + 1);
|
||||
ruleset = NEW2 (rulesetsize, unsigned);
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
closure (short *core, int n)
|
||||
{
|
||||
register int ruleno;
|
||||
register unsigned word;
|
||||
register short *csp;
|
||||
register unsigned *dsp;
|
||||
register unsigned *rsp;
|
||||
int ruleno;
|
||||
unsigned word;
|
||||
short *csp;
|
||||
unsigned *dsp;
|
||||
unsigned *rsp;
|
||||
|
||||
short *csend;
|
||||
unsigned *rsend;
|
||||
@@ -241,7 +263,7 @@ closure (short *core, int n)
|
||||
while (csp < csend)
|
||||
{
|
||||
symbol = ritem[*csp++];
|
||||
if (ISVAR(symbol))
|
||||
if (ISVAR (symbol))
|
||||
{
|
||||
dsp = fderives + symbol * rulesetsize;
|
||||
rsp = ruleset;
|
||||
@@ -264,7 +286,7 @@ closure (short *core, int n)
|
||||
}
|
||||
else
|
||||
{
|
||||
register int b;
|
||||
int b;
|
||||
|
||||
for (b = 0; b < BITS_PER_WORD; b++)
|
||||
{
|
||||
@@ -284,77 +306,16 @@ closure (short *core, int n)
|
||||
while (csp < csend)
|
||||
*itemsetend++ = *csp++;
|
||||
|
||||
#ifdef DEBUG
|
||||
print_closure(n);
|
||||
#if DEBUG
|
||||
print_closure (n);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
finalize_closure (void)
|
||||
free_closure (void)
|
||||
{
|
||||
FREE(itemset);
|
||||
FREE(ruleset);
|
||||
FREE(fderives + ntokens * rulesetsize);
|
||||
FREE (itemset);
|
||||
FREE (ruleset);
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user