Files
pcas/src/libCom/yacc/lr0.c
T
Michael DavidsaverandAndrew Johnson f7fc564556 Fold antelope/flex and asHost into libCom
Build lexer and parser from libCom/Makefile.
Since libCom now includes asLib.c and asLib_lex.c we must build
antelope and flex without linking them to Com.  This works because
they only need epicsTempFile anyway.  However make doesn't like a
subdirectory with the same name as a target object, so the antelope
source directory is now called yacc.  The two main.c files were also
renamed to avoid other build problems.

Merge asHost into Com and remove mentions in CONFIG_BASE

Lots of noise since SRCS must be renamed to Com_SRCS
2011-02-25 15:39:44 -06:00

614 lines
9.8 KiB
C

/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include "defs.h"
extern short *itemset;
extern short *itemsetend;
extern unsigned *ruleset;
int nstates;
core *first_state;
shifts *first_shift;
reductions *first_reduction;
static core **state_set;
static core *this_state;
static core *last_state;
static shifts *last_shift;
static reductions *last_reduction;
static int nshifts;
static short *shift_symbol;
static short *redset;
static short *shiftset;
static short **kernel_base;
static short **kernel_end;
static short *kernel_items;
static int get_state(int symbol);
static void initialize_states(void);
static void new_itemsets(void);
static core *new_state(int symbol);
static void save_shifts(void);
static void save_reductions(void);
#ifdef DEBUG
static void print_derives(void);
#endif
static void
allocate_itemsets(void)
{
short *itemp;
short *item_end;
int symbol;
int i;
int count;
int max;
short *symbol_count;
count = 0;
symbol_count = NEW2(nsyms, short);
item_end = ritem + nitems;
for (itemp = ritem; itemp < item_end; itemp++)
{
symbol = *itemp;
if (symbol >= 0)
{
count++;
symbol_count[symbol]++;
}
}
kernel_base = NEW2(nsyms, short *);
kernel_items = NEW2(count, short);
count = 0;
max = 0;
for (i = 0; i < nsyms; i++)
{
kernel_base[i] = kernel_items + count;
count += symbol_count[i];
if (max < symbol_count[i])
max = symbol_count[i];
}
shift_symbol = symbol_count;
kernel_end = NEW2(nsyms, short *);
}
static void
allocate_storage(void)
{
allocate_itemsets();
shiftset = NEW2(nsyms, short);
redset = NEW2(nrules + 1, short);
state_set = NEW2(nitems, core *);
}
static void
append_states(void)
{
int i;
int j;
int symbol;
#ifdef TRACE
fprintf(stderr, "Entering append_states()\n");
#endif
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;
}
for (i = 0; i < nshifts; i++)
{
symbol = shift_symbol[i];
shiftset[i] = get_state(symbol);
}
}
static void
free_storage(void)
{
FREE(shift_symbol);
FREE(redset);
FREE(shiftset);
FREE(kernel_base);
FREE(kernel_end);
FREE(kernel_items);
FREE(state_set);
}
static void
generate_states(void)
{
allocate_storage();
itemset = NEW2(nitems, short);
ruleset = NEW2(WORDSIZE(nrules), unsigned);
set_first_derives();
initialize_states();
while (this_state)
{
closure(this_state->items, this_state->nitems);
save_reductions();
new_itemsets();
append_states();
if (nshifts > 0)
save_shifts();
this_state = this_state->next;
}
finalize_closure();
free_storage();
}
static int
get_state(int symbol)
{
int key;
short *isp1;
short *isp2;
short *iend;
core *sp;
int found;
int n;
#ifdef TRACE
fprintf(stderr, "Entering get_state(%d)\n", symbol);
#endif
isp1 = kernel_base[symbol];
iend = kernel_end[symbol];
n = iend - isp1;
key = *isp1;
assert(0 <= key && key < nitems);
sp = state_set[key];
if (sp)
{
found = 0;
while (!found)
{
if (sp->nitems == n)
{
found = 1;
isp1 = kernel_base[symbol];
isp2 = sp->items;
while (found && isp1 < iend)
{
if (*isp1++ != *isp2++)
found = 0;
}
}
if (!found)
{
if (sp->link)
{
sp = sp->link;
}
else
{
sp = sp->link = new_state(symbol);
found = 1;
}
}
}
}
else
{
state_set[key] = sp = new_state(symbol);
}
return (sp->number);
}
static void
initialize_states(void)
{
int i;
short *start_derives;
core *p;
start_derives = derives[start_symbol];
for (i = 0; start_derives[i] >= 0; ++i)
continue;
p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
if (p == 0) no_space();
p->next = 0;
p->link = 0;
p->number = 0;
p->accessing_symbol = 0;
p->nitems = i;
for (i = 0; start_derives[i] >= 0; ++i)
p->items[i] = rrhs[start_derives[i]];
first_state = last_state = this_state = p;
nstates = 1;
}
static void
new_itemsets(void)
{
int i;
int shiftcount;
short *isp;
short *ksp;
int symbol;
for (i = 0; i < nsyms; i++)
kernel_end[i] = 0;
shiftcount = 0;
isp = itemset;
while (isp < itemsetend)
{
i = *isp++;
symbol = ritem[i];
if (symbol > 0)
{
ksp = kernel_end[symbol];
if (!ksp)
{
shift_symbol[shiftcount++] = symbol;
ksp = kernel_base[symbol];
}
*ksp++ = i + 1;
kernel_end[symbol] = ksp;
}
}
nshifts = shiftcount;
}
static core *
new_state(int symbol)
{
int n;
core *p;
short *isp1;
short *isp2;
short *iend;
#ifdef TRACE
fprintf(stderr, "Entering new_state(%d)\n", symbol);
#endif
if (nstates >= MAXSHORT)
fatal("too many states");
isp1 = kernel_base[symbol];
iend = kernel_end[symbol];
n = iend - isp1;
p = (core *) allocate((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);
}
#ifdef DEBUG
static void
show_cores(void)
{
core *p;
int i, j, k, n;
int itemno;
k = 0;
for (p = first_state; p; ++k, p = p->next)
{
if (k) printf("\n");
printf("state %d, number = %d, accessing symbol = %s\n",
k, p->number, symbol_name[p->accessing_symbol]);
n = p->nitems;
for (i = 0; i < n; ++i)
{
itemno = p->items[i];
printf("%4d ", itemno);
j = itemno;
while (ritem[j] >= 0) ++j;
printf("%s :", symbol_name[rlhs[-ritem[j]]]);
j = rrhs[-ritem[j]];
while (j < itemno)
printf(" %s", symbol_name[ritem[j++]]);
printf(" .");
while (ritem[j] >= 0)
printf(" %s", symbol_name[ritem[j++]]);
printf("\n");
fflush(stdout);
}
}
}
static void
show_ritems(void)
{
int i;
for (i = 0; i < nitems; ++i)
printf("ritem[%d] = %d\n", i, ritem[i]);
}
static void
show_rrhs(void)
{
int i;
for (i = 0; i < nrules; ++i)
printf("rrhs[%d] = %d\n", i, rrhs[i]);
}
static void
show_shifts(void)
{
shifts *p;
int i, j, k;
k = 0;
for (p = first_shift; p; ++k, p = p->next)
{
if (k) printf("\n");
printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
p->nshifts);
j = p->nshifts;
for (i = 0; i < j; ++i)
printf("\t%d\n", p->shift[i]);
}
}
#endif
static void
save_shifts(void)
{
shifts *p;
short *sp1;
short *sp2;
short *send;
p = (shifts *) allocate((unsigned) (sizeof(shifts) +
(nshifts - 1) * sizeof(short)));
p->number = this_state->number;
p->nshifts = nshifts;
sp1 = shiftset;
sp2 = p->shift;
send = shiftset + nshifts;
while (sp1 < send)
*sp2++ = *sp1++;
if (last_shift)
{
last_shift->next = p;
last_shift = p;
}
else
{
first_shift = p;
last_shift = p;
}
}
static void
save_reductions(void)
{
short *isp;
short *rp1;
short *rp2;
int item;
int count;
reductions *p;
short *rend;
count = 0;
for (isp = itemset; isp < itemsetend; isp++)
{
item = ritem[*isp];
if (item < 0)
{
redset[count++] = -item;
}
}
if (count)
{
p = (reductions *) allocate((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;
}
}
}
static void
set_derives(void)
{
int i, k;
int lhs;
short *rules;
derives = NEW2(nsyms, short *);
rules = NEW2(nvars + nrules, short);
k = 0;
for (lhs = start_symbol; lhs < nsyms; lhs++)
{
derives[lhs] = rules + k;
for (i = 0; i < nrules; i++)
{
if (rlhs[i] == lhs)
{
rules[k] = i;
k++;
}
}
rules[k] = -1;
k++;
}
#ifdef DEBUG
print_derives();
#endif
}
void
free_derives(void)
{
FREE(derives[start_symbol]);
FREE(derives);
}
#ifdef DEBUG
static void
print_derives(void)
{
int i;
short *sp;
printf("\nDERIVES\n\n");
for (i = start_symbol; i < nsyms; i++)
{
printf("%s derives ", symbol_name[i]);
for (sp = derives[i]; *sp >= 0; sp++)
{
printf(" %d", *sp);
}
putchar('\n');
}
putchar('\n');
}
#endif
static void
set_nullable(void)
{
int i, j;
int empty;
int done;
nullable = MALLOC(nsyms);
if (nullable == 0) no_space();
for (i = 0; i < nsyms; ++i)
nullable[i] = 0;
done = 0;
while (!done)
{
done = 1;
for (i = 1; i < nitems; i++)
{
empty = 1;
while ((j = ritem[i]) >= 0)
{
if (!nullable[j])
empty = 0;
++i;
}
if (empty)
{
j = rlhs[-j];
if (!nullable[j])
{
nullable[j] = 1;
done = 0;
}
}
}
}
#ifdef DEBUG
for (i = 0; i < nsyms; i++)
{
if (nullable[i])
printf("%s is nullable\n", symbol_name[i]);
else
printf("%s is not nullable\n", symbol_name[i]);
}
#endif
}
void
free_nullable(void)
{
FREE(nullable);
}
void
lr0(void)
{
set_derives();
set_nullable();
generate_states();
}