# ifndef NORCSID
static string rcsid = "$Header$";
# endif
-p_mem alloc(), new_mem();
+p_mem alloc(), ralloc();
string store();
p_gram search();
static int nparams; /* parameter count for nonterminals */
static int acount; /* count #of global actions */
-static t_info term_info,
- link_info;
static p_order order,
maxorder;
+static p_term t_list;
+static int t_cnt;
/* Here are defined : */
-extern a_init();
STATIC p_order neworder();
STATIC copyact();
STATIC mkalt();
STATIC p_gram copyrule();
/* and of course LLparse() */
-a_init() {
- term_info.i_esize = sizeof (t_term);
- term_info.i_incr = 100;
- link_info.i_esize = sizeof (t_link);
- link_info.i_incr = 100;
- name_init();
-}
-
STATIC p_order
neworder(index) {
register p_order po;
temp = search(NONTERM,lextoken.t_string,BOTH);
ff = (p_start) alloc(sizeof(t_start));
- ff->ff_nont = g_getnont(temp);
+ ff->ff_nont = g_getcont(temp);
ff->ff_name = p;
ff->ff_next = start;
start = ff;
* grammar for a production rule
*/
C_IDENT { temp = search(NONTERM,lextoken.t_string,BOTH);
- p = &nonterms[g_getnont(temp)];
+ p = &nonterms[g_getcont(temp)];
if (p->n_rule) {
error(linecount,
"nonterminal %s already defined", lextoken.t_string);
* Do not use p->n_rule now! The nonterms array
* might have been re-allocated.
*/
- { nonterms[g_getnont(temp)].n_rule = rr;}
+ { nonterms[g_getcont(temp)].n_rule = rr;}
;
action(int n;)
int conflres = 0;
int t = 0;
int haddefault = 0;
- t_gram alts[100];
+ p_gram alts = (p_gram) alloc(200 * sizeof(t_gram));
register p_gram p_alts = alts;
+ unsigned n_alts = 200;
int o_lc, n_lc;
} :
{ o_lc = linecount; }
[
[ '|' { n_lc = linecount; }
simpleproduction(&prod,&t)
- { if (p_alts - alts >= 97) {
- error(n_lc,"Too many alternatives");
- p_alts = alts;
+ { if (p_alts - alts == n_alts) {
+ alts = (p_gram) ralloc(
+ (p_mem) alts,
+ (n_alts+100)*sizeof(t_gram));
+ p_alts = alts + n_alts;
+ n_alts += 100;
}
if (t & DEF) {
if (haddefault) {
*/
}
]
+ { free((p_mem) alts); }
;
{
/*
* Create an alternation and initialise it.
*/
- register int hulp;
register p_link l;
+ static p_link list;
+ static int cnt;
- l = (p_link) new_mem(&link_info);
- links = (p_link) link_info.i_ptr;
- hulp = l - links;
+ if (! cnt) {
+ cnt = 50;
+ list = (p_link) alloc(50 * sizeof(t_link));
+ }
+ cnt--;
+ l = list++;
l->l_rule = prod;
l->l_flag = condition;
- g_setcont(res,hulp);
+ g_setlink(res,l);
g_settype(res,ALTERNATION);
res->g_lineno = lc;
+ nalts++;
}
}
simpleproduction(p_gram *p; register int *conflres;)
- { t_gram rule[100];
+ { p_gram rule = (p_gram) alloc(200 * sizeof(t_gram));
+ unsigned n_rule = 200;
t_gram elem;
register p_gram p_rule = rule;
int cnt, kind;
+ int termdeleted = 0;
} :
[ C_DEFAULT { *conflres = DEF; }
]?
| C_AVOID { *conflres |= AVOIDING; }
]?
[ %persistent elem(&elem)
- { if (p_rule - rule >= 98) {
- error(linecount,"Production too long");
- p_rule = rule;
+ { if (p_rule - rule >= n_rule - 1) {
+ rule = (p_gram) ralloc(
+ (p_mem) rule,
+ (n_rule+100)*sizeof(t_gram));
+ p_rule = rule + n_rule - 1;
+ n_rule += 100;
}
kind = FIXED;
cnt = 0;
&elem);
}
}
- ]? { if (g_gettype(&elem) == TERM) {
+ |
+ { if (g_gettype(&elem) == TERM) {
+ register p_term q = g_getterm(&elem);
+
+ if (g_gettype(q->t_rule) != ALTERNATION &&
+ g_gettype(q->t_rule) != EORULE) {
+ while (g_gettype(q->t_rule) != EORULE) {
+ *p_rule++ = *q->t_rule++;
+ if (p_rule - rule >= n_rule - 1) {
+ rule = (p_gram) ralloc(
+ (p_mem) rule,
+ (n_rule+100)*sizeof(t_gram));
+ p_rule = rule + n_rule - 1;
+ n_rule += 100;
+ }
+ }
+ elem = *--(q->t_rule);
+ p_rule--;
+ if (q == t_list - 1) {
+ t_list--;
+ nterms--;
+ t_cnt++;
+ }
+ termdeleted = 1;
+ }
+ }
+ }
+ ] { if (!termdeleted && g_gettype(&elem) == TERM) {
register p_term q;
- q = &terms[g_getcont(&elem)];
+ q = g_getterm(&elem);
r_setkind(q,kind);
r_setnum(q,cnt);
if ((q->t_flags & RESOLVER) &&
*p = 0;
if (g_gettype(&rule[0]) == TERM &&
p_rule-rule == 1) {
- q = &terms[g_getcont(&rule[0])];
+ q = g_getterm(&rule[0]);
if (r_getkind(q) == FIXED &&
r_getnum(q) == 0) {
*p = q->t_rule;
}
}
if (!*p) *p = copyrule(rule,p_rule-rule+1);
+ free((p_mem) rule);
}
;
{
STATIC
-mkterm(prod,flags,lc, result) p_gram prod; register p_gram result; {
+mkterm(prod,flags,lc,result) p_gram prod; register p_gram result; {
/*
* Create a term, initialise it and return
* a grammar element containing it
*/
register p_term q;
- unsigned hulp;
- q = (p_term) new_mem(&term_info);
- terms = (p_term) term_info.i_ptr;
- hulp = q - terms;
+ if (! t_cnt) {
+ t_cnt = 50;
+ t_list = (p_term) alloc(50 * sizeof(t_term));
+ }
+ t_cnt--;
+ q = t_list++;
q->t_rule = prod;
q->t_contains = 0;
q->t_flags = flags;
g_settype(result,TERM);
- g_setcont(result,hulp);
+ g_setterm(result,q);
result->g_lineno = lc;
+ nterms++;
}
}
elem (register p_gram pres;)
- { register short t = 0;
+ { register int t = 0;
p_gram p1;
int ln;
p_gram pe;
temp = search(NONTERM,lextoken.t_string,BOTH);
ff = (p_first) alloc(sizeof(t_first));
- ff->ff_nont = g_getnont(temp);
+ ff->ff_nont = g_getcont(temp);
ff->ff_name = p;
ff->ff_next = pfile->f_firsts;
pfile->f_firsts = ff;
# $Header$
+EMHOME=../../..
PROF=
LLOPT= # -vvv -x
-CFLAGS=-O -DNDEBUG $(PROF)
+INCLUDES = -I$(EMHOME)/h
+CFLAGS=-O -DNDEBUG $(INCLUDES) $(PROF)
LDFLAGS=-i
OBJECTS = main.o gencode.o compute.o LLgen.o tokens.o check.o reach.o global.o name.o sets.o Lpars.o alloc.o machdep.o cclass.o
CFILES = main.c gencode.c compute.c LLgen.c tokens.c check.c reach.c global.c name.c sets.c Lpars.c alloc.c machdep.c cclass.c
@pr $(FILES) ../lib/rec ../lib/incl Makefile
lint:
- $(LINT) $(CFILES)
+ $(LINT) $(INCLUDES) $(CFILES)
clean:
-rm -f *.o LL.temp LL.xxx LL.output LLgen
# include "types.h"
# include "extern.h"
+# include <local.h>
# ifndef NORCSID
static string rcsid = "$Header$";
if (p->i_max >= p->i_top) { /* No more free elements */
sz = p->i_size;
+#if BIGMACHINE
+ p->i_size += p->i_size;
+ if (! p->i_size)
+ p->i_size += p->i_incr * p->i_esize;
+#else
p->i_size += p->i_incr * p->i_esize;
+#endif
p->i_ptr = !p->i_ptr ?
alloc(p->i_size) :
ralloc(p->i_ptr, p->i_size);
case NONTERM : {
register p_nont n;
- n = &nonterms[g_getnont(p)];
+ n = &nonterms[g_getcont(p)];
if (g_getnpar(p) != getntparams(n)) {
error(p->g_lineno,
"Call of %s : parameter count mismatch",
case TERM : {
register p_term q;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
retval |= check(q->t_rule);
if (r_getkind(q) == FIXED) break;
if (setempty(q->t_first)) {
case ALTERNATION : {
register p_link l;
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
temp = setalloc();
setunion(temp,l->l_symbs);
if(!setintersect(temp,l->l_others)) {
register p_term q;
register int c;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
if (present) prline("\n");
fputs("[ ",f);
level += 4;
case ALTERNATION : {
register p_link l;
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
if (firstalt) {
firstalt = 0;
}
"'%s' " : "%s ", pt->t_string);
break; }
case NONTERM :
- fprintf(f,"%s ",nonterms[g_getnont(p)].n_name);
+ fprintf(f,"%s ",nonterms[g_getcont(p)].n_name);
break;
}
p++;
case EORULE :
return;
case TERM :
- resolve(terms[g_getcont(p)].t_rule);
+ resolve(g_getterm(p)->t_rule);
break;
case ALTERNATION : {
register p_link l;
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
if (l->l_flag & AVOIDING) {
/*
* On conflicting symbols, this rule
* p will not be chosen.
*/
while (g_gettype(p) != EORULE) {
- setminus(links[g_getcont(p)].l_symbs,set);
+ setminus(g_getlink(p)->l_symbs,set);
p++;
}
}
case TERM : {
register p_term q;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
q->t_first = get_set();
q->t_follow = get_set();
walk(q->t_rule);
case ALTERNATION : {
register p_link l;
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
l->l_symbs = get_set();
l->l_others = get_set();
walk(l->l_rule);
case TERM : {
register p_term q;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
if (r_getkind(q) == STAR
|| r_getkind(q) == OPT
|| empty(q->t_rule) ) break;
return 0; }
case ALTERNATION :
- if (empty(links[g_getcont(p)].l_rule)) {
+ if (empty(g_getlink(p)->l_rule)) {
return 1;
}
if (g_gettype(p+1) == EORULE) return 0;
break;
case NONTERM :
- if (nonterms[g_getnont(p)].n_flags & EMPTY) {
+ if (nonterms[g_getcont(p)].n_flags & EMPTY) {
break;
}
/* Fall through */
case TERM : {
register p_term q;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
if (flag == 0) {
if (first(q->t_first,q->t_rule,0))/*nothing*/;
}
case ALTERNATION : {
register p_link l;
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
if (flag == 0) {
if (first(l->l_symbs,l->l_rule,0))/*nothing*/;
}
case NONTERM : {
register p_nont n;
- n = &nonterms[g_getnont(p)];
+ n = &nonterms[g_getcont(p)];
if (noenter == 0) {
s |= setunion(setp,n->n_first);
- if (ntneeded) NTPUTIN(setp,g_getnont(p));
+ if (ntneeded) NTPUTIN(setp,g_getcont(p));
}
p++;
if (n->n_flags & EMPTY) continue;
case TERM : {
register p_term q;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
if (empty(p+1)) {
/*
* If what follows the term can be empty,
/*
* Just propagate setp
*/
- s |= follow(setp,links[g_getcont(p)].l_rule);
+ s |= follow(setp,g_getlink(p)->l_rule);
break;
case NONTERM : {
register p_nont n;
- n = &nonterms[g_getnont(p)];
+ n = &nonterms[g_getcont(p)];
s |= first(n->n_follow,p+1,1);
if (empty(p+1)) {
/*
case TERM : {
register p_term q;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
co_dirsymb(q->t_follow,q->t_rule);
break; }
case ALTERNATION : {
* Save first alternative
*/
if (!s) s = p;
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
co_dirsymb(setp,l->l_rule);
if (empty(l->l_rule)) {
/*
*/
register p_link l1,l2;
- l1 = &links[g_getcont(p)];
+ l1 = g_getlink(p);
p++;
- l2 = &links[g_getcont(p)];
+ l2 = g_getlink(p);
setunion(l1->l_others,l2->l_symbs);
if (g_gettype(p+1) != EORULE) {
/*
*/
register p_length pl;
register p_nont p;
- register p_start st;
- int change = 1;
p_mem alloc();
length = (p_length) alloc((unsigned) (nnonterms * sizeof(*length)));
X.cnt = INFINITY;
X.val = INFINITY;
while (g_gettype(p) != EORULE) {
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
complength(l->l_rule,&i);
if (l->l_flag & DEF) {
X = i;
case TERM : {
register int rep;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
rep = r_getkind(q);
if ((q->t_flags&PERSISTENT) ||
rep==FIXED || rep==PLUS) {
}
break; }
case NONTERM : {
- int nn = g_getnont(p);
+ int nn = g_getcont(p);
register p_length pl = &length[nn];
int x = pl->cnt;
case EORULE:
return;
case TERM:
- setdefaults(terms[g_getcont(p)].t_rule);
+ setdefaults(g_getterm(p)->t_rule);
break;
case ALTERNATION: {
register p_link l, l1;
count.cnt = INFINITY;
count.val = INFINITY;
- l1 = &links[g_getcont(p)];
+ l1 = g_getlink(p);
do {
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
complength(l->l_rule,&i);
if (l->l_flag & DEF) temp = 1;
temp1 = compare(&i, &count);
register p_term q;
int rep;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
rep = r_getkind(q);
if ((q->t_flags & PERSISTENT) ||
rep == PLUS || rep == FIXED) {
case NONTERM : {
register p_nont n;
- n = &nonterms[g_getnont(p)];
+ n = &nonterms[g_getcont(p)];
do_contains(n);
if (set) {
setunion(set, n->n_contains);
- if (ntneeded) NTPUTIN(set, g_getnont(p));
+ if (ntneeded) NTPUTIN(set, g_getcont(p));
}
break; }
case ALTERNATION : {
register p_link l;
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
contains(l->l_rule,
(l->l_flag & DEF) ? set : (p_set) 0);
break; }
register p_term q;
int i,rep;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
i = r_getnum(q);
rep = r_getkind(q);
retval = do_safes(q->t_rule,
f = 1;
while (g_gettype(p) == ALTERNATION) {
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
if (safe > SAFE && (l->l_flag & DEF)) {
i = do_safes(l->l_rule,SAFESCANDONE,ch);
}
register p_nont n;
register int nsafe, osafe;
- n = &nonterms[g_getnont(p)];
+ n = &nonterms[g_getcont(p)];
nsafe = getntsafe(n);
osafe = safe;
safe = getntout(n);
extern char ltext[]; /* input buffer */
extern int nnonterms; /* number of nonterminals */
extern int ntokens; /* number of terminals */
+extern int nterms; /* number of terms */
+extern int nalts; /* number of alternatives */
extern p_start start; /* will contain startsymbols */
extern int linecount; /* line number */
extern int assval; /* to create difference between literals
extern t_token lextoken; /* the current token */
extern int nerrors;
extern string rec_file, incl_file;
-extern p_term terms;
-extern p_link links;
safety = NOSCANDONE;
break; }
case NONTERM : {
- register p_nont n = &nonterms[g_getnont(p)];
+ register p_nont n = &nonterms[g_getcont(p)];
if (safety == NOSCANDONE &&
getntsafe(n) < NOSCANDONE) {
safety = getntout(n);
break;
}
- fprintf(f,"L%d_%s(\n",g_getnont(p), n->n_name);
+ fprintf(f,"L%d_%s(\n",g_getcont(p), n->n_name);
if (g_getnpar(p)) {
controlline();
getaction(0);
safety = getntout(n);
break; }
case TERM :
- safety = codeforterm(&terms[g_getcont(p)],
+ safety = codeforterm(g_getterm(p),
safety,
toplevel);
break;
p_set setalloc();
assert(safety < NOSCANDONE);
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
hulp = nlabel++;
hulp1 = nlabel++;
hulp2 = nlabel++;
}
fputs("switch(LLcsymb) {\n", f);
while (g_gettype(p) != EORULE) {
- l = &links[g_getcont(p)];
+ l = g_getlink(p);
if (unsafe && (l->l_flag & DEF)) {
haddefault = 1;
fprintf(f,
p++;
fprintf(f,"L_%d : ;\n",hulp);
if (g_gettype(p+1) == EORULE) {
- setminus(links[g_getcont(p)].l_symbs, set);
+ setminus(g_getlink(p)->l_symbs, set);
free((p_mem) set);
continue;
}
register p_term q;
int rep, cnt;
- q = &terms[g_getcont(p)];
+ q = g_getterm(p);
rep = r_getkind(q);
cnt = r_getnum(q);
if (!(toplevel > 0 && safety <= SAFESCANDONE &&
case NONTERM : {
register p_nont n;
- n = &nonterms[g_getnont(p)];
+ n = &nonterms[g_getcont(p)];
if (toplevel == 0 ||
(g_gettype(n->n_rule) == ALTERNATION &&
getntsafe(n) > SAFESCANDONE)) {
p_token tokens;
p_token maxt;
int ntokens;
+int nterms, nalts;
p_order porder, sorder;
p_start start;
int linecount;
t_token lextoken;
int nerrors;
string rec_file, incl_file;
-p_link links;
-p_term terms;
*/
-# include "../../../h/em_path.h"
+# include <em_path.h>
# include "types.h"
# ifndef NORCSID
fputs("Cannot create temporary\n",stderr);
exit(1);
}
- a_init();
+ name_init();
readgrammar(argc,argv);
setinit(ntneeded);
maxnt = &nonterms[nnonterms];
else gencode(argc);
UNLINK(f_temp);
UNLINK(f_pars);
+ if (verbose) {
+ extern char *sbrk(), *end;
+
+ fprintf(stderr, "number of nonterminals: %d\n", nnonterms);
+ fprintf(stderr, "number of tokens: %d\n", ntokens);
+ fprintf(stderr, "number of term structures: %d\n", nterms);
+ fprintf(stderr, "number of alternation structures: %d\n", nalts);
+ fprintf(stderr, "total memory used: %d\n", sbrk(0) - (char *) &end);
+ }
exit(0);
}
name_init() {
token_info.i_esize = sizeof (t_token);
- token_info.i_incr = 100;
+ token_info.i_incr = 50;
nont_info.i_esize = sizeof (t_nont);
- nont_info.i_incr = 100;
+ nont_info.i_incr = 50;
search(TERMINAL,"EOFILE",ENTERING);
}
q->n_contains = 0;
g_settype(&(p->h_type), NONTERM);
g_setcont(&(p->h_type), nnonterms);
+ g_setnpar(&(p->h_type), 0);
nnonterms++;
return &(p->h_type);
}
for (;;) {
switch(g_gettype(p)) {
case ALTERNATION :
- reachwalk(links[g_getcont(p)].l_rule);
+ reachwalk(g_getlink(p)->l_rule);
break;
case TERM :
- reachwalk(terms[g_getcont(p)].t_rule);
+ reachwalk(g_getterm(p)->t_rule);
break;
case NONTERM :
- reachable(&nonterms[g_getnont(p)]);
+ reachable(&nonterms[g_getcont(p)]);
break;
case EORULE :
return;
typedef struct gram {
short x; /* for lay-out see comment below */
short g_lineno; /* element found on this line number */
+ union {
+ int g_index;
+ struct term * g_term;
+ struct link * g_link;
+ } g_i;
} t_gram,*p_gram;
/*
* Layout of the field x:
*
- * 15 13 12 9 8 0
- * ------------------------------------------
- * | type | nparams | index |
- * ------------------------------------------
- * of
- * 15 13 12 0
- * ------------------------------------------
- * | type | index |
- * ------------------------------------------
- * dependant on type
- */
-# define UNDEFINED 000777
+ * 15 ....... 7 6 ........ 3 2 .... 0
+ * -----------------------------------
+ * | unused | | nparams | | type |
+ * -----------------------------------
+ */
# define EORULE 00 /* End of (sub)rule */
# define ACTION 01 /* Imbedded action */
# define NONTERM 02 /* A nonterminal */
/*
* Access macros for the x-field of a grammar element
*/
-# define g_gettype(p) (((p)->x>>13)&07)
-# define g_getcont(p) ((p)->x&017777)
-# define g_getnont(p) ((p)->x&0777)
-# define g_getnpar(p) (((p)->x>>9)&017)
-# define g_settype(p,s) { assert(((unsigned)(s))<=07);(p)->x=((p)->x&017777)|((s)<<13);}
-# define g_setcont(p,s) { assert(((unsigned)(s))<=017777);(p)->x=((p)->x&0160000)|(s);}
-# define g_setnont(p,s) { assert(((unsigned)(s))<=0777);(p)->x=((p)->x&0177000)|(s);}
-# define g_setnpar(p,s) { assert(((unsigned)(s))<=017);(p)->x=((p)->x&0160777)|((s)<<9);}
+# define g_gettype(p) ((p)->x&07)
+# define g_getcont(p) ((p)->g_i.g_index)
+# define g_getterm(p) ((p)->g_i.g_term)
+# define g_getlink(p) ((p)->g_i.g_link)
+# define g_getnpar(p) (((p)->x>>3)&017)
+# define g_settype(p,s) { assert(((unsigned)(s))<=07);(p)->x=((p)->x&~07)|(s);}
+# define g_setcont(p,s) ((p)->g_i.g_index=(s))
+# define g_setterm(p,s) ((p)->g_i.g_term = (s))
+# define g_setlink(p,s) ((p)->g_i.g_link = (s))
+# define g_setnpar(p,s) { assert(((unsigned)(s))<=017);(p)->x=((p)->x&~0170)|((s)<<3);}
/*
* Some constants to communicate with the symbol table search routine