* src/lalr.h: New file.

Propagate its inclusion instead of prototypes and `extern'.
* src/lalr.c: Formatting changes, topological sorting etc.
This commit is contained in:
Akim Demaille
2000-10-02 07:56:58 +00:00
parent f2acea59d9
commit 720d742f8e
7 changed files with 708 additions and 682 deletions

View File

@@ -1,3 +1,10 @@
2000-10-02 Akim Demaille <akim@epita.fr>
* src/lalr.h: New file.
Propagate its inclusion instead of prototypes and `extern'.
* src/lalr.c: Formatting changes, topological sorting etc.
2000-10-02 Akim Demaille <akim@epita.fr> 2000-10-02 Akim Demaille <akim@epita.fr>
* src/output.c (token_actions): Introduce a temporary array, * src/output.c (token_actions): Introduce a temporary array,

View File

@@ -20,7 +20,7 @@ EXTRA_bison_SOURCES = vmsgetargs.c
noinst_HEADERS = alloc.h closure.h complain.h \ noinst_HEADERS = alloc.h closure.h complain.h \
derives.h \ derives.h \
files.h getargs.h gram.h lex.h \ files.h getargs.h gram.h lalr.h lex.h \
output.h state.h \ output.h state.h \
symtab.h system.h types.h symtab.h system.h types.h

View File

@@ -24,16 +24,9 @@
#include "files.h" #include "files.h"
#include "gram.h" #include "gram.h"
#include "state.h" #include "state.h"
#include "lalr.h"
extern char **tags; extern char **tags;
extern int tokensetsize;
extern char *consistent;
extern short *accessing_symbol;
extern shifts **shift_table;
extern unsigned *LA;
extern short *LAruleno;
extern short *lookaheads;
extern int fixed_outfiles; extern int fixed_outfiles;
extern void initialize_conflicts PARAMS ((void)); extern void initialize_conflicts PARAMS ((void));

View File

@@ -19,34 +19,9 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
/* Compute how to make the finite state machine deterministic; /* Compute how to make the finite state machine deterministic; find
find which rules need lookahead in each state, and which lookahead tokens they accept. which rules need lookahead in each state, and which lookahead
tokens they accept. */
lalr(), the entry point, builds these data structures:
goto_map, from_state and to_state
record each shift transition which accepts a variable (a nonterminal).
ngotos is the number of such transitions.
from_state[t] is the state number which a transition leads from
and to_state[t] is the state number it leads to.
All the transitions that accept a particular variable are grouped together and
goto_map[i - ntokens] is the index in from_state and to_state of the first of them.
consistent[s] is nonzero if no lookahead is needed to decide what to do in state s.
LAruleno is a vector which records the rules that need lookahead in various states.
The elements of LAruleno that apply to state s are those from
lookaheads[s] through lookaheads[s+1]-1.
Each element of LAruleno is a rule number.
If lr is the length of LAruleno, then a number from 0 to lr-1
can specify both a rule and a state where the rule might be applied.
LA is a lr by ntokens matrix of bits.
LA[l, i] is 1 if the rule LAruleno[l] is applicable in the appropriate state
when the next token is symbol i.
If LA[l, i] and LA[l, j] are both 1 for i != j, it is a conflict.
*/
#include "system.h" #include "system.h"
#include "types.h" #include "types.h"
@@ -54,6 +29,7 @@ If LA[l, i] and LA[l, j] are both 1 for i != j, it is a conflict.
#include "alloc.h" #include "alloc.h"
#include "gram.h" #include "gram.h"
#include "complain.h" #include "complain.h"
#include "lalr.h"
extern short **derives; extern short **derives;
extern char *nullable; extern char *nullable;
@@ -72,25 +48,6 @@ short *goto_map;
short *from_state; short *from_state;
short *to_state; short *to_state;
extern void lalr PARAMS((void));
static short **transpose PARAMS((short **, int));
static void set_state_table PARAMS((void));
static void set_accessing_symbol PARAMS((void));
static void set_shift_table PARAMS((void));
static void set_reduction_table PARAMS((void));
static void set_maxrhs PARAMS((void));
static void initialize_LA PARAMS((void));
static void set_goto_map PARAMS((void));
static int map_goto PARAMS((int, int));
static void initialize_F PARAMS((void));
static void build_relations PARAMS((void));
static void add_lookback_edge PARAMS((int, int, int));
static void compute_FOLLOWS PARAMS((void));
static void compute_lookaheads PARAMS((void));
static void digraph PARAMS((short **));
static void traverse PARAMS((register int));
extern void berror PARAMS ((const char *)); extern void berror PARAMS ((const char *));
static int infinity; static int infinity;
@@ -105,29 +62,92 @@ static short *VERTICES;
static int top; static int top;
void static void
lalr (void) traverse (int i)
{ {
tokensetsize = WORDSIZE(ntokens); unsigned *fp1;
unsigned *fp2;
unsigned *fp3;
int j;
short *rp;
set_state_table(); int height;
set_accessing_symbol(); unsigned *base;
set_shift_table();
set_reduction_table(); VERTICES[++top] = i;
set_maxrhs(); INDEX[i] = height = top;
initialize_LA();
set_goto_map(); base = F + i * tokensetsize;
initialize_F(); fp3 = base + tokensetsize;
build_relations();
compute_FOLLOWS(); rp = R[i];
compute_lookaheads(); if (rp)
{
while ((j = *rp++) >= 0)
{
if (INDEX[j] == 0)
traverse (j);
if (INDEX[i] > INDEX[j])
INDEX[i] = INDEX[j];
fp1 = base;
fp2 = F + j * tokensetsize;
while (fp1 < fp3)
*fp1++ |= *fp2++;
}
}
if (INDEX[i] == height)
{
for (;;)
{
j = VERTICES[top--];
INDEX[j] = infinity;
if (i == j)
break;
fp1 = base;
fp2 = F + j * tokensetsize;
while (fp1 < fp3)
*fp2++ = *fp1++;
}
}
} }
static void
digraph (short **relation)
{
int i;
infinity = ngotos + 2;
INDEX = NEW2 (ngotos + 1, short);
VERTICES = NEW2 (ngotos + 1, short);
top = 0;
R = relation;
for (i = 0; i < ngotos; i++)
INDEX[i] = 0;
for (i = 0; i < ngotos; i++)
{
if (INDEX[i] == 0 && R[i])
traverse (i);
}
FREE (INDEX);
FREE (VERTICES);
}
static void static void
set_state_table (void) set_state_table (void)
{ {
register core *sp; core *sp;
state_table = NEW2 (nstates, core *); state_table = NEW2 (nstates, core *);
@@ -139,7 +159,7 @@ set_state_table (void)
static void static void
set_accessing_symbol (void) set_accessing_symbol (void)
{ {
register core *sp; core *sp;
accessing_symbol = NEW2 (nstates, short); accessing_symbol = NEW2 (nstates, short);
@@ -151,7 +171,7 @@ set_accessing_symbol (void)
static void static void
set_shift_table (void) set_shift_table (void)
{ {
register shifts *sp; shifts *sp;
shift_table = NEW2 (nstates, shifts *); shift_table = NEW2 (nstates, shifts *);
@@ -163,7 +183,7 @@ set_shift_table (void)
static void static void
set_reduction_table (void) set_reduction_table (void)
{ {
register reductions *rp; reductions *rp;
reduction_table = NEW2 (nstates, reductions *); reduction_table = NEW2 (nstates, reductions *);
@@ -175,9 +195,9 @@ set_reduction_table (void)
static void static void
set_maxrhs (void) set_maxrhs (void)
{ {
register short *itemp; short *itemp;
register int length; int length;
register int max; int max;
length = 0; length = 0;
max = 0; max = 0;
@@ -189,7 +209,8 @@ set_maxrhs (void)
} }
else else
{ {
if (length > max) max = length; if (length > max)
max = length;
length = 0; length = 0;
} }
} }
@@ -201,12 +222,12 @@ set_maxrhs (void)
static void static void
initialize_LA (void) initialize_LA (void)
{ {
register int i; int i;
register int j; int j;
register int count; int count;
register reductions *rp; reductions *rp;
register shifts *sp; shifts *sp;
register short *np; short *np;
consistent = NEW2 (nstates, char); consistent = NEW2 (nstates, char);
lookaheads = NEW2 (nstates + 1, short); lookaheads = NEW2 (nstates + 1, short);
@@ -214,7 +235,7 @@ initialize_LA (void)
count = 0; count = 0;
for (i = 0; i < nstates; i++) for (i = 0; i < nstates; i++)
{ {
register int k; int k;
lookaheads[i] = count; lookaheads[i] = count;
@@ -268,13 +289,13 @@ initialize_LA (void)
static void static void
set_goto_map (void) set_goto_map (void)
{ {
register shifts *sp; shifts *sp;
register int i; int i;
register int symbol; int symbol;
register int k; int k;
register short *temp_map; short *temp_map;
register int state2; int state2;
register int state1; int state1;
goto_map = NEW2 (nvars + 1, short) - ntokens; goto_map = NEW2 (nvars + 1, short) - ntokens;
temp_map = NEW2 (nvars + 1, short) - ntokens; temp_map = NEW2 (nvars + 1, short) - ntokens;
@@ -286,7 +307,8 @@ set_goto_map (void)
{ {
symbol = accessing_symbol[sp->shifts[i]]; symbol = accessing_symbol[sp->shifts[i]];
if (ISTOKEN(symbol)) break; if (ISTOKEN (symbol))
break;
if (ngotos == MAXSHORT) if (ngotos == MAXSHORT)
fatal (_("too many gotos (max %d)"), MAXSHORT); fatal (_("too many gotos (max %d)"), MAXSHORT);
@@ -320,7 +342,8 @@ set_goto_map (void)
state2 = sp->shifts[i]; state2 = sp->shifts[i];
symbol = accessing_symbol[state2]; symbol = accessing_symbol[state2];
if (ISTOKEN(symbol)) break; if (ISTOKEN (symbol))
break;
k = temp_map[symbol]++; k = temp_map[symbol]++;
from_state[k] = state1; from_state[k] = state1;
@@ -338,10 +361,10 @@ set_goto_map (void)
static int static int
map_goto (int state, int symbol) map_goto (int state, int symbol)
{ {
register int high; int high;
register int low; int low;
register int middle; int middle;
register int s; int s;
low = goto_map[symbol]; low = goto_map[symbol];
high = goto_map[symbol + 1] - 1; high = goto_map[symbol + 1] - 1;
@@ -367,18 +390,18 @@ map_goto (int state, int symbol)
static void static void
initialize_F (void) initialize_F (void)
{ {
register int i; int i;
register int j; int j;
register int k; int k;
register shifts *sp; shifts *sp;
register short *edge; short *edge;
register unsigned *rowp; unsigned *rowp;
register short *rp; short *rp;
register short **reads; short **reads;
register int nedges; int nedges;
register int stateno; int stateno;
register int symbol; int symbol;
register int nwords; int nwords;
nwords = ngotos * tokensetsize; nwords = ngotos * tokensetsize;
F = NEW2 (nwords, unsigned); F = NEW2 (nwords, unsigned);
@@ -440,108 +463,13 @@ initialize_F (void)
} }
static void
build_relations (void)
{
register int i;
register int j;
register int k;
register short *rulep;
register short *rp;
register shifts *sp;
register int length;
register int nedges;
register int done;
register int state1;
register int stateno;
register int symbol1;
register int symbol2;
register short *shortp;
register short *edge;
register short *states;
register short **new_includes;
includes = NEW2(ngotos, short *);
edge = NEW2(ngotos + 1, short);
states = NEW2(maxrhs + 1, short);
for (i = 0; i < ngotos; i++)
{
nedges = 0;
state1 = from_state[i];
symbol1 = accessing_symbol[to_state[i]];
for (rulep = derives[symbol1]; *rulep > 0; rulep++)
{
length = 1;
states[0] = state1;
stateno = state1;
for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++)
{
symbol2 = *rp;
sp = shift_table[stateno];
k = sp->nshifts;
for (j = 0; j < k; j++)
{
stateno = sp->shifts[j];
if (accessing_symbol[stateno] == symbol2) break;
}
states[length++] = stateno;
}
if (!consistent[stateno])
add_lookback_edge(stateno, *rulep, i);
length--;
done = 0;
while (!done)
{
done = 1;
rp--;
/* JF added rp>=ritem && I hope to god its right! */
if (rp>=ritem && ISVAR(*rp))
{
stateno = states[--length];
edge[nedges++] = map_goto(stateno, *rp);
if (nullable[*rp]) done = 0;
}
}
}
if (nedges)
{
includes[i] = shortp = NEW2(nedges + 1, short);
for (j = 0; j < nedges; j++)
shortp[j] = edge[j];
shortp[nedges] = -1;
}
}
new_includes = transpose(includes, ngotos);
for (i = 0; i < ngotos; i++)
if (includes[i])
FREE(includes[i]);
FREE(includes);
includes = new_includes;
FREE(edge);
FREE(states);
}
static void static void
add_lookback_edge (int stateno, int ruleno, int gotono) add_lookback_edge (int stateno, int ruleno, int gotono)
{ {
register int i; int i;
register int k; int k;
register int found; int found;
register shorts *sp; shorts *sp;
i = lookaheads[stateno]; i = lookaheads[stateno];
k = lookaheads[stateno + 1]; k = lookaheads[stateno + 1];
@@ -564,16 +492,15 @@ add_lookback_edge (int stateno, int ruleno, int gotono)
} }
static short ** static short **
transpose (short **R_arg, int n) transpose (short **R_arg, int n)
{ {
register short **new_R; short **new_R;
register short **temp_R; short **temp_R;
register short *nedges; short *nedges;
register short *sp; short *sp;
register int i; int i;
register int k; int k;
nedges = NEW2 (n, short); nedges = NEW2 (n, short);
@@ -620,16 +547,115 @@ transpose (short **R_arg, int n)
} }
static void
build_relations (void)
{
int i;
int j;
int k;
short *rulep;
short *rp;
shifts *sp;
int length;
int nedges;
int done;
int state1;
int stateno;
int symbol1;
int symbol2;
short *shortp;
short *edge;
short *states;
short **new_includes;
includes = NEW2 (ngotos, short *);
edge = NEW2 (ngotos + 1, short);
states = NEW2 (maxrhs + 1, short);
for (i = 0; i < ngotos; i++)
{
nedges = 0;
state1 = from_state[i];
symbol1 = accessing_symbol[to_state[i]];
for (rulep = derives[symbol1]; *rulep > 0; rulep++)
{
length = 1;
states[0] = state1;
stateno = state1;
for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++)
{
symbol2 = *rp;
sp = shift_table[stateno];
k = sp->nshifts;
for (j = 0; j < k; j++)
{
stateno = sp->shifts[j];
if (accessing_symbol[stateno] == symbol2)
break;
}
states[length++] = stateno;
}
if (!consistent[stateno])
add_lookback_edge (stateno, *rulep, i);
length--;
done = 0;
while (!done)
{
done = 1;
rp--;
/* JF added rp>=ritem && I hope to god its right! */
if (rp >= ritem && ISVAR (*rp))
{
stateno = states[--length];
edge[nedges++] = map_goto (stateno, *rp);
if (nullable[*rp])
done = 0;
}
}
}
if (nedges)
{
includes[i] = shortp = NEW2 (nedges + 1, short);
for (j = 0; j < nedges; j++)
shortp[j] = edge[j];
shortp[nedges] = -1;
}
}
new_includes = transpose (includes, ngotos);
for (i = 0; i < ngotos; i++)
if (includes[i])
FREE (includes[i]);
FREE (includes);
includes = new_includes;
FREE (edge);
FREE (states);
}
static void static void
compute_FOLLOWS (void) compute_FOLLOWS (void)
{ {
register int i; int i;
digraph (includes); digraph (includes);
for (i = 0; i < ngotos; i++) for (i = 0; i < ngotos; i++)
{ {
if (includes[i]) FREE(includes[i]); if (includes[i])
FREE (includes[i]);
} }
FREE (includes); FREE (includes);
@@ -639,16 +665,14 @@ compute_FOLLOWS (void)
static void static void
compute_lookaheads (void) compute_lookaheads (void)
{ {
register int i; int i;
register int n; int n;
register unsigned *fp1; unsigned *fp1;
register unsigned *fp2; unsigned *fp2;
register unsigned *fp3; unsigned *fp3;
register shorts *sp; shorts *sp;
register unsigned *rowp; unsigned *rowp;
/* register short *rulep; JF unused */ shorts *sptmp; /* JF */
/* register int count; JF unused */
register shorts *sptmp;/* JF */
rowp = LA; rowp = LA;
n = lookaheads[nstates]; n = lookaheads[nstates];
@@ -667,8 +691,10 @@ compute_lookaheads (void)
} }
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{/* JF removed ref to freed storage */ {
for (sp = lookback[i]; sp; sp = sptmp) { /* JF removed ref to freed storage */
for (sp = lookback[i]; sp; sp = sptmp)
{
sptmp = sp->next; sptmp = sp->next;
FREE (sp); FREE (sp);
} }
@@ -679,84 +705,20 @@ compute_lookaheads (void)
} }
static void void
digraph (short **relation) lalr (void)
{ {
register int i; tokensetsize = WORDSIZE (ntokens);
infinity = ngotos + 2; set_state_table ();
INDEX = NEW2(ngotos + 1, short); set_accessing_symbol ();
VERTICES = NEW2(ngotos + 1, short); set_shift_table ();
top = 0; set_reduction_table ();
set_maxrhs ();
R = relation; initialize_LA ();
set_goto_map ();
for (i = 0; i < ngotos; i++) initialize_F ();
INDEX[i] = 0; build_relations ();
compute_FOLLOWS ();
for (i = 0; i < ngotos; i++) compute_lookaheads ();
{
if (INDEX[i] == 0 && R[i])
traverse(i);
}
FREE(INDEX);
FREE(VERTICES);
}
static void
traverse (register int i)
{
register unsigned *fp1;
register unsigned *fp2;
register unsigned *fp3;
register int j;
register short *rp;
int height;
unsigned *base;
VERTICES[++top] = i;
INDEX[i] = height = top;
base = F + i * tokensetsize;
fp3 = base + tokensetsize;
rp = R[i];
if (rp)
{
while ((j = *rp++) >= 0)
{
if (INDEX[j] == 0)
traverse(j);
if (INDEX[i] > INDEX[j])
INDEX[i] = INDEX[j];
fp1 = base;
fp2 = F + j * tokensetsize;
while (fp1 < fp3)
*fp1++ |= *fp2++;
}
}
if (INDEX[i] == height)
{
for (;;)
{
j = VERTICES[top--];
INDEX[j] = infinity;
if (i == j)
break;
fp1 = base;
fp2 = F + j * tokensetsize;
while (fp1 < fp3)
*fp2++ = *fp1++;
}
}
} }

80
src/lalr.h Normal file
View File

@@ -0,0 +1,80 @@
/* Compute look-ahead criteria for bison,
Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
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 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. */
#ifndef LALR_H_
# define LALR_H_
/* Compute how to make the finite state machine deterministic; find
which rules need lookahead in each state, and which lookahead
tokens they accept. */
void lalr PARAMS ((void));
/* lalr() builds these data structures. */
/* goto_map, from_state and to_state --record each shift transition
which accepts a variable (a nonterminal).
from_state[t] is the state number which a transition leads from and
to_state[t] is the state number it leads to. All the transitions
that accept a particular variable are grouped together and
goto_map[i - ntokens] is the index in from_state and to_state of
the first of them. */
extern short *goto_map;
extern short *from_state;
extern short *to_state;
/* CONSISTENT[S] is nonzero if no lookahead is needed to decide what
to do in state S. */
extern char *consistent;
/* LARULENO is a vector which records the rules that need lookahead in
various states. The elements of LARULENO that apply to state S are
those from LOOKAHEADS[S] through LOOKAHEADS[S+1]-1. Each element
of LARULENO is a rule number.
If LR is the length of LAruleno, then a number from 0 to LR-1 can
specify both a rule and a state where the rule might be applied.
*/
extern short *LAruleno;
/* LA is a lr by ntokens matrix of bits. LA[l, i] is 1 if the rule
LAruleno[l] is applicable in the appropriate state when the next
token is symbol i. If LA[l, i] and LA[l, j] are both 1 for i != j,
it is a conflict. */
extern unsigned *LA;
extern int tokensetsize;
extern short *lookaheads;
extern short *accessing_symbol;
extern core **state_table;
extern shifts **shift_table;
extern reductions **reduction_table;
#endif /* !LALR_H_ */

View File

@@ -98,25 +98,14 @@
#include "state.h" #include "state.h"
#include "complain.h" #include "complain.h"
#include "output.h" #include "output.h"
#include "lalr.h"
extern void berror PARAMS((const char *)); extern void berror PARAMS((const char *));
extern char **tags; extern char **tags;
extern short *user_toknums; extern short *user_toknums;
extern int tokensetsize;
extern int final_state; extern int final_state;
extern core **state_table;
extern shifts **shift_table;
extern errs **err_table; extern errs **err_table;
extern reductions **reduction_table;
extern short *accessing_symbol;
extern unsigned *LA;
extern short *LAruleno;
extern short *lookaheads;
extern char *consistent;
extern short *goto_map;
extern short *from_state;
extern short *to_state;
extern void reader_output_yylsp PARAMS ((FILE *)); extern void reader_output_yylsp PARAMS ((FILE *));

View File

@@ -24,16 +24,11 @@
#include "files.h" #include "files.h"
#include "gram.h" #include "gram.h"
#include "state.h" #include "state.h"
#include "lalr.h"
extern char **tags; extern char **tags;
extern int nstates; extern int nstates;
extern short *accessing_symbol;
extern core **state_table;
extern shifts **shift_table;
extern errs **err_table; extern errs **err_table;
extern reductions **reduction_table;
extern char *consistent;
extern char any_conflicts; extern char any_conflicts;
extern char *conflicts; extern char *conflicts;
extern int final_state; extern int final_state;