Added some tests and changed ordering mechanism
This commit is contained in:
parent
7c479cf325
commit
03e1bea097
|
@ -34,8 +34,7 @@ p_gram search();
|
|||
|
||||
static int nparams; /* parameter count for nonterminals */
|
||||
static int acount; /* count #of global actions */
|
||||
static p_order order,
|
||||
maxorder;
|
||||
static int order;
|
||||
static p_term t_list;
|
||||
static int t_cnt;
|
||||
static p_gram alt_table;
|
||||
|
@ -49,29 +48,36 @@ static int max_rules;
|
|||
#define RULEINCR 32
|
||||
|
||||
/* Here are defined : */
|
||||
STATIC p_order neworder();
|
||||
STATIC newnorder();
|
||||
STATIC newtorder();
|
||||
STATIC copyact();
|
||||
STATIC mkalt();
|
||||
STATIC mkterm();
|
||||
STATIC p_gram copyrule();
|
||||
/* and of course LLparse() */
|
||||
|
||||
STATIC p_order
|
||||
neworder(index) {
|
||||
register p_order po;
|
||||
STATIC
|
||||
newnorder(index) {
|
||||
static int porder;
|
||||
|
||||
if ((po = order) == maxorder) {
|
||||
po = (p_order) alloc(20 * sizeof(*order));
|
||||
maxorder = po + 20;
|
||||
if (norder != -1) {
|
||||
nonterms[porder].n_next = index;
|
||||
}
|
||||
order = po + 1;
|
||||
po->o_next = 0;
|
||||
po->o_index = index;
|
||||
if (porder) {
|
||||
porder->o_next = po;
|
||||
else norder = index;
|
||||
porder = index;
|
||||
nonterms[porder].n_next = -1;
|
||||
}
|
||||
|
||||
STATIC
|
||||
newtorder(index) {
|
||||
static int porder;
|
||||
|
||||
if (torder != -1) {
|
||||
tokens[porder].t_next = index;
|
||||
}
|
||||
else sorder = po;
|
||||
return po;
|
||||
else torder = index;
|
||||
porder = index;
|
||||
tokens[porder].t_next = -1;
|
||||
}
|
||||
|
||||
p_init()
|
||||
|
@ -128,6 +134,12 @@ def { register string p; }
|
|||
ff->ff_name = p;
|
||||
ff->ff_next = start;
|
||||
start = ff;
|
||||
while (ff = ff->ff_next) {
|
||||
if (! strcmp(p, ff->ff_name)) {
|
||||
error(linecount, "\"%s\" already used in a %%start", p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
| C_LEXICAL C_IDENT
|
||||
/*
|
||||
|
@ -172,7 +184,10 @@ def { register string p; }
|
|||
*/
|
||||
;
|
||||
|
||||
listel : C_IDENT { search(TERMINAL,lextoken.t_string,ENTERING); }
|
||||
listel : C_IDENT { p_gram temp = search(TERMINAL,lextoken.t_string,ENTERING);
|
||||
newtorder(g_getcont(temp));
|
||||
tokens[g_getcont(temp)].t_lineno = linecount;
|
||||
}
|
||||
;
|
||||
|
||||
rule { register p_nont p;
|
||||
|
@ -194,7 +209,7 @@ rule { register p_nont p;
|
|||
* order to keep track with the actions on the
|
||||
* temporary file
|
||||
*/
|
||||
porder = neworder(p - nonterms);
|
||||
newnorder(p - nonterms);
|
||||
p->n_count = acount;
|
||||
acount = 0;
|
||||
p->n_lineno = linecount;
|
||||
|
|
|
@ -55,7 +55,7 @@ conflchecks() {
|
|||
* must be disjunct.
|
||||
*/
|
||||
register p_nont p;
|
||||
register p_order s;
|
||||
register int s;
|
||||
p_file x = files;
|
||||
|
||||
f_input = x->f_name;
|
||||
|
@ -71,15 +71,15 @@ conflchecks() {
|
|||
*/
|
||||
for (; x < maxfiles; x++) {
|
||||
f_input = x->f_name;
|
||||
for (s = x->f_list; s; s = s->o_next) {
|
||||
p = &nonterms[s->o_index];
|
||||
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
|
||||
p = &nonterms[s];
|
||||
if (check(p->n_rule)) p->n_flags |= VERBOSE;
|
||||
}
|
||||
}
|
||||
for (x = files; x < maxfiles; x++) {
|
||||
f_input = x->f_name;
|
||||
for (s = x->f_list; s; s = s->o_next) {
|
||||
p = &nonterms[s->o_index];
|
||||
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
|
||||
p = &nonterms[s];
|
||||
if (p->n_flags & RECURSIVE) {
|
||||
error(p->n_lineno,
|
||||
"Recursion in default for nonterminal %s",
|
||||
|
|
|
@ -798,16 +798,16 @@ do_safes(p,safe,ch) register p_gram p; register int *ch; {
|
|||
break; }
|
||||
case ALTERNATION : {
|
||||
register p_link l;
|
||||
register int i, f;
|
||||
register int i;
|
||||
|
||||
f = 1;
|
||||
retval = -1;
|
||||
while (g_gettype(p) == ALTERNATION) {
|
||||
l = g_getlink(p);
|
||||
if (safe > SAFE && (l->l_flag & DEF)) {
|
||||
i = do_safes(l->l_rule,SAFESCANDONE,ch);
|
||||
}
|
||||
else i = do_safes(l->l_rule,SAFE,ch);
|
||||
if (f) retval = i;
|
||||
if (retval == -1) retval = i;
|
||||
else if (i != retval) {
|
||||
if (i == NOSCANDONE ||
|
||||
retval == NOSCANDONE) {
|
||||
|
@ -816,7 +816,6 @@ do_safes(p,safe,ch) register p_gram p; register int *ch; {
|
|||
else if (i > retval) retval = i;
|
||||
}
|
||||
p++;
|
||||
f = 0;
|
||||
}
|
||||
return retval; }
|
||||
case NONTERM : {
|
||||
|
|
|
@ -45,7 +45,7 @@ extern p_nont nonterms; /* the nonterminal array */
|
|||
extern p_nont maxnt; /* is filled up until here */
|
||||
extern p_token tokens; /* the token array */
|
||||
extern p_token maxt; /* is filled up until here */
|
||||
extern struct order *sorder, *porder;
|
||||
extern int norder, torder;
|
||||
/* order of nonterminals in the grammar,
|
||||
* important because actions are copied to
|
||||
* a temporary file in the order in which they
|
||||
|
|
|
@ -235,7 +235,7 @@ generate(f) p_file f; {
|
|||
/*
|
||||
* Generates a parsing routine for every nonterminal
|
||||
*/
|
||||
register p_order s;
|
||||
register int s;
|
||||
register p_nont p;
|
||||
int i;
|
||||
register p_first ff;
|
||||
|
@ -249,8 +249,8 @@ generate(f) p_file f; {
|
|||
}
|
||||
|
||||
/* For every nonterminal generate a function */
|
||||
for (s = f->f_list; s; s = s->o_next) {
|
||||
p = &nonterms[s->o_index];
|
||||
for (s = f->f_nonterminals; s != -1; s = p->n_next) {
|
||||
p = &nonterms[s];
|
||||
/* Generate functions in the order in which the nonterminals
|
||||
* were defined in the grammar. This is important, because
|
||||
* of synchronisation with the action file
|
||||
|
@ -260,7 +260,7 @@ generate(f) p_file f; {
|
|||
getntparams(p) == 0) {
|
||||
continue;
|
||||
}
|
||||
genextname(s->o_index, p->n_name, fpars);
|
||||
genextname(s, p->n_name, fpars);
|
||||
if (p->n_flags & PARAMS) {
|
||||
fputs("(\n", fpars);
|
||||
controlline();
|
||||
|
@ -297,7 +297,7 @@ prset(p) p_set p; {
|
|||
for (;;) {
|
||||
i = (unsigned) *p++;
|
||||
for (k = 0; k < sizeof(int); k++) {
|
||||
fprintf(fpars,"0%o,",(i & 0377));
|
||||
fprintf(fpars,"0%o,",(int)(i & 0377));
|
||||
i >>= 8;
|
||||
if (--j == 0) {
|
||||
fputs("\n",fpars);
|
||||
|
@ -574,6 +574,7 @@ alternation(pp, safety, mustscan, mustpop, lb)
|
|||
p = pp;
|
||||
}
|
||||
while (g_gettype(p) != EORULE) {
|
||||
set = 0;
|
||||
l = g_getlink(p);
|
||||
if (l->l_flag & COND) {
|
||||
if (!(l->l_flag & NOCONF)) {
|
||||
|
@ -884,7 +885,7 @@ genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; {
|
|||
register FILE *f = fpars;
|
||||
p_set p1;
|
||||
p_set setalloc();
|
||||
int hulp1, hulp2;
|
||||
int hulp1 = 0, hulp2;
|
||||
int safeterm;
|
||||
int termissafe = 0;
|
||||
int casecnt = 0;
|
||||
|
|
|
@ -33,7 +33,7 @@ p_token tokens;
|
|||
p_token maxt;
|
||||
int ntokens;
|
||||
int nterms, nalts;
|
||||
p_order porder, sorder;
|
||||
int norder, torder;
|
||||
p_start start;
|
||||
int linecount;
|
||||
int assval;
|
||||
|
|
|
@ -171,7 +171,7 @@ main(argc,argv) register string argv[]; {
|
|||
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: %u\n", sbrk(0) - (char *) &end);
|
||||
fprintf(stderr, "total memory used: %ld\n", (long)(sbrk(0) - (char *) &end));
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
@ -222,10 +222,11 @@ doparse(p) register p_file p; {
|
|||
p->f_name = f_input;
|
||||
p->f_firsts = 0;
|
||||
pfile = p;
|
||||
sorder = 0;
|
||||
porder = 0;
|
||||
torder = -1;
|
||||
norder = -1;
|
||||
LLparse();
|
||||
p->f_list = sorder;
|
||||
p->f_nonterminals = norder;
|
||||
p->f_terminals = torder;
|
||||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
|
|
|
@ -114,7 +114,7 @@ search(type,str,option) register string str; {
|
|||
* It has type UNKNOWN, LITERAL, TERMINAL or NONTERM.
|
||||
* option can be ENTERING or BOTH (also looking).
|
||||
*/
|
||||
register int val;
|
||||
register int val = 0;
|
||||
register p_entry p;
|
||||
register int i;
|
||||
int type1;
|
||||
|
|
|
@ -37,9 +37,10 @@ co_reach() {
|
|||
* Check for undefined or unreachable nonterminals.
|
||||
*/
|
||||
register p_nont p;
|
||||
register p_token t;
|
||||
register p_start st;
|
||||
register p_file x;
|
||||
register p_order s;
|
||||
register int s;
|
||||
|
||||
/* Check for undefined nonterminals */
|
||||
for (p = nonterms; p < maxnt; p++) {
|
||||
|
@ -63,13 +64,20 @@ co_reach() {
|
|||
*/
|
||||
for (x = files; x < maxfiles; x++) {
|
||||
f_input = x->f_name;
|
||||
for (s = x->f_list; s; s = s->o_next) {
|
||||
p = &nonterms[s->o_index];
|
||||
for (s = x->f_nonterminals; s != -1; s = p->n_next) {
|
||||
p = &nonterms[s];
|
||||
if (! (p->n_flags & REACHABLE)) {
|
||||
warning(p->n_lineno,"nonterminal %s unreachable",
|
||||
p->n_name);
|
||||
}
|
||||
}
|
||||
for (s = x->f_terminals; s != -1; s = t->t_next) {
|
||||
t = &tokens[s];
|
||||
if (! (t->t_flags & REACHABLE)) {
|
||||
warning(t->t_lineno,"terminal %s not used",
|
||||
t->t_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +125,9 @@ reachwalk(p) register p_gram p; {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TERMINAL:
|
||||
tokens[g_getcont(p)].t_flags |= REACHABLE;
|
||||
break;
|
||||
case EORULE :
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ p_set *setptr, *maxptr;
|
|||
static t_info set_info;
|
||||
p_mem alloc();
|
||||
|
||||
setinit(ntneeded) {
|
||||
setinit(nt_needed) {
|
||||
/*
|
||||
* Initialises some variables needed for setcomputations
|
||||
*/
|
||||
|
@ -53,7 +53,7 @@ setinit(ntneeded) {
|
|||
nbytes = NBYTES(ntokens);
|
||||
bitset = ALIGN(nbytes);
|
||||
tsetsize = NINTS(bitset);
|
||||
if (ntneeded) {
|
||||
if (nt_needed) {
|
||||
/* nonterminals must be included in the sets */
|
||||
bitset += NBYTES(nnonterms);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ typedef struct token {
|
|||
} t_x;
|
||||
# define t_string t_x.t_s
|
||||
# define t_num t_x.t_v
|
||||
int t_flags;
|
||||
int t_next;
|
||||
int t_lineno;
|
||||
} t_token, *p_token;
|
||||
|
||||
/*
|
||||
|
@ -131,6 +134,7 @@ typedef struct {
|
|||
p_set n_follow; /* pointer to the "follow" set */
|
||||
p_set n_contains; /* pointer to symbols that can be produced */
|
||||
string n_name; /* name of nonterminal */
|
||||
int n_next; /* index of next nonterminal */
|
||||
} t_nont, *p_nont;
|
||||
|
||||
/*
|
||||
|
@ -212,11 +216,6 @@ typedef struct ff_firsts {
|
|||
typedef t_first t_start;
|
||||
typedef p_first p_start;
|
||||
|
||||
typedef struct order {
|
||||
int o_index; /* index in nonterminal array */
|
||||
struct order *o_next;
|
||||
} t_order, *p_order;
|
||||
|
||||
/*
|
||||
* structure for file names and info
|
||||
*/
|
||||
|
@ -226,7 +225,8 @@ typedef struct f_file {
|
|||
* generated in the target file for this
|
||||
* grammar file
|
||||
*/
|
||||
struct order *f_list; /* list of nonterminals in this file */
|
||||
int f_nonterminals; /* list of nonterminals in this file */
|
||||
int f_terminals; /* list of terminals in this file */
|
||||
} t_file, *p_file;
|
||||
|
||||
typedef struct info_alloc {
|
||||
|
|
Loading…
Reference in a new issue