From: ceriel Date: Thu, 3 Oct 1985 12:38:55 +0000 (+0000) Subject: More safety, also after terms and nonterminals. X-Git-Tag: release-5-5~5404 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=d07e8114c66a71128d55c2e56eb1b1018bd2490b;p=ack.git More safety, also after terms and nonterminals. --- diff --git a/util/LLgen/src/check.c b/util/LLgen/src/check.c index 9d3a5b95a..ed4b3f899 100644 --- a/util/LLgen/src/check.c +++ b/util/LLgen/src/check.c @@ -204,13 +204,16 @@ check(p) register p_gram p; { switch (g_gettype(p)) { case EORULE : return; - case NONTERM : - if (g_getnpar(p)!=((nonterms[g_getnont(p)].n_flags&077) >> 3)){ + case NONTERM : { + register p_nont n; + + n = &nonterms[g_getnont(p)]; + if (g_getnpar(p) != getntparams(n)) { error(p->g_lineno, "Call of %s : parameter count mismatch", (min_nt_ent+g_getnont(p))->h_name); } - break; + break; } case TERM : { register p_term q; diff --git a/util/LLgen/src/compute.c b/util/LLgen/src/compute.c index 9c2c66dec..30ca87771 100644 --- a/util/LLgen/src/compute.c +++ b/util/LLgen/src/compute.c @@ -670,28 +670,28 @@ co_safes() { /* * Don't know anything yet */ - setntsafe(&(p->n_flags), NOSAFETY); + setntsafe(p, NOSAFETY); + setntout(p, NOSAFETY); } for (st = start; st; st = st->ff_next) { /* * But start symbols are called with lookahead done */ p = st->ff_nont; - setntsafe(&(p->n_flags),SCANDONE); + setntsafe(p,SCANDONE); } change = 1; while (change) { change = 0; for (p = nonterms; p < maxnt; p++) { - i = getntsafe(p->n_flags); + i = getntsafe(p); if (i == NOSAFETY) { - change = 1; continue; } - if (do_safes(p->n_rule, i) == 2 && - !(p->n_flags & NNOSCAN)) { - p->n_flags |= NNOSCAN; + i = do_safes(p->n_rule, i); + if (getntout(p) != i) { change = 1; + setntout(p, i); } } } @@ -705,8 +705,6 @@ do_safes(p,safe) register p_gram p; { */ register retval; - if (safe == NOSCANDONE) retval = 2; - else retval = 1; for (;;) { switch (g_gettype(p)) { case ACTION: @@ -724,10 +722,10 @@ do_safes(p,safe) register p_gram p; { rep = r_getkind(&(q->t_reps)); retval = do_safes(q->t_rule, t_safety(rep,i,q->t_flags&PERSISTENT,safe)); - if (retval == 2 && (!(q->t_flags & TNOSCAN))) { - q->t_flags |= TNOSCAN; + if (retval != gettout(q)) { + settout(q, retval); } - safe = t_after(rep, i, q->t_flags & TNOSCAN); + safe = t_after(rep, i, gettout(q)); break; } case ALTERNATION : { register p_link l; @@ -736,51 +734,53 @@ do_safes(p,safe) register p_gram p; { f = 1; while (g_gettype(p) == ALTERNATION) { l = (p_link) pentry[g_getcont(p)]; - if (safe && (l->l_flag & DEF)) { + if (safe > SAFE && (l->l_flag & DEF)) { i = do_safes(l->l_rule,SAFESCANDONE); } else i = do_safes(l->l_rule,SAFE); if (f) retval = i; - else retval &= i; + else if (i != retval) { + if (i == NOSCANDONE || + retval == NOSCANDONE) { + retval = SCANDONE; + } + else if (i > retval) retval = i; + } p++; f = 0; } return retval; } case NONTERM : { register p_nont n; - int nsafe, osafe;; + int nsafe, osafe; n = &nonterms[g_getnont(p)]; - nsafe = getntsafe(n->n_flags); + nsafe = getntsafe(n); osafe = safe; - if (!(n->n_flags & NNOSCAN)) { - safe = SCANDONE; - } - else safe = NOSCANDONE; + safe = getntout(n); + if (safe == NOSAFETY) safe = SCANDONE; if (osafe == nsafe) break; if (nsafe == NOSAFETY) { change = 1; - setntsafe(&(n->n_flags), osafe); + setntsafe(n, osafe); break; } if (osafe == NOSCANDONE || nsafe == NOSCANDONE) { if (nsafe != SCANDONE) { change = 1; - setntsafe(&(n->n_flags), SCANDONE); + setntsafe(n, SCANDONE); } break; } if (osafe > nsafe) { - setntsafe(&(n->n_flags), osafe); + setntsafe(n, osafe); change = 1; } break; } case EORULE : - return retval; + return safe; } p++; - if (safe == NOSCANDONE) retval = 2; - else retval = 1; } } @@ -814,10 +814,13 @@ t_safety(rep, count, persistent, safety) { /* NOTREACHED */ } -t_after(rep, count, noscan) { +t_after(rep, count, outsafety) { if (count == 0 && (rep == STAR || rep == PLUS)) { return SAFESCANDONE; } - if (rep == FIXED && noscan) return NOSCANDONE; - return SCANDONE; + if (rep != FIXED) { + if (outsafety <= SAFESCANDONE) return SAFESCANDONE; + return SCANDONE; + } + return outsafety; } diff --git a/util/LLgen/src/gencode.c b/util/LLgen/src/gencode.c index e3fe33dda..751357c01 100644 --- a/util/LLgen/src/gencode.c +++ b/util/LLgen/src/gencode.c @@ -173,7 +173,7 @@ genrecovery() { fprintf(f, "\tL%d_%s();\n", st->ff_nont-nonterms, (min_nt_ent+(st->ff_nont-nonterms))->h_name); - if (st->ff_nont->n_flags & NNOSCAN) { + if (getntout(st->ff_nont) == NOSCANDONE) { fputs("\tLLscan(EOFILE);\n",f); } else fputs("\tif (LLsymb != EOFILE) LLerror(EOFILE);\n",f); @@ -240,7 +240,7 @@ generate(f) p_file f; { else fputs(") {\n", fd); fputs("register struct LLxx *LLx = &LLxx;\n#ifdef lint\nLLx=LLx;\n#endif\n", fd); if (p->n_flags & LOCALS) getaction(1); - i = getntsafe(p->n_flags); + i = getntsafe(p); mustpop = 0; if (g_gettype(p->n_rule) == ALTERNATION) { mustpop = 1; @@ -252,7 +252,8 @@ generate(f) p_file f; { nlabel = 1; rulecode(p->n_rule, i, - !(p->n_flags & NNOSCAN), mustpop); + getntout(p) != NOSCANDONE, + mustpop); fputs(c_close, fd); } } @@ -443,7 +444,7 @@ rulecode(p,safety,mustscan,mustpop) register p_gram p; { n = &nonterms[g_getnont(p)]; t= min_nt_ent+(n-nonterms); if (safety == NOSCANDONE && - getntsafe(n->n_flags) < NOSCANDONE) fputs(c_read, f); + getntsafe(n) < NOSCANDONE) fputs(c_read, f); if (toplevel == 0 && g_gettype(n->n_rule) != ALTERNATION) { fputs(c_LLptrmin, f); @@ -453,8 +454,7 @@ rulecode(p,safety,mustscan,mustpop) register p_gram p; { fprintf(f,"L%d_%s(",n-nonterms, t->h_name); if (params) getaction(0); fputs(");\n",f); - safety = NOSCANDONE; - if (!(n->n_flags & NNOSCAN)) safety = SCANDONE; + safety = getntout(n); break; } case TERM : safety = codeforterm((p_term) pentry[g_getcont(p)], @@ -707,13 +707,11 @@ codeforterm(q,safety,toplevel) register p_term q; { register int i; register int rep; int persistent; - int noscan; f = fpars; i = r_getnum(&(q->t_reps)); rep = r_getkind(&(q->t_reps)); persistent = (q->t_flags & PERSISTENT); - noscan = (q->t_flags & TNOSCAN); if (safety == NOSCANDONE && (rep != FIXED || i == 0)) { fputs(c_read, f); if (rep == FIXED && g_gettype(q->t_rule) != ALTERNATION) { @@ -726,7 +724,7 @@ codeforterm(q,safety,toplevel) register p_term q; { fputs("for (;;) {\nif (!LL_i--) {\nLLptr++;\n", f); fputs("break;\n}\n", f); if (rep == FIXED) { - if (noscan && safety == NOSCANDONE) { + if (gettout(q) == NOSCANDONE && safety == NOSCANDONE) { fputs(c_read,f); } } @@ -739,7 +737,7 @@ codeforterm(q,safety,toplevel) register p_term q; { genifhead(q,rep); } rulecode(q->t_rule,t_safety(rep,i,persistent,safety), - rep != FIXED || !noscan, + rep != FIXED || gettout(q) != NOSCANDONE, rep == FIXED && i == 0 && g_gettype(q->t_rule) == ALTERNATION); /* in the case of '+', the if is after the code for the rule */ if (rep == PLUS) { @@ -761,7 +759,7 @@ codeforterm(q,safety,toplevel) register p_term q; { fputs(c_close, f);/* Close Register ... */ } } - return t_after(rep, i, noscan); + return t_after(rep, i, gettout(q)); } STATIC diff --git a/util/LLgen/src/types.h b/util/LLgen/src/types.h index 0188ce62e..49181bfcb 100644 --- a/util/LLgen/src/types.h +++ b/util/LLgen/src/types.h @@ -108,15 +108,11 @@ typedef struct gram { */ typedef struct { short n_flags; /* low order three bits are reserved - * for "safety" information, - * the next three bits are reserved for * the parameter count */ -# define getntsafe(f) ((f)&07) -# define setntsafe(p,i) {assert(((unsigned)(i))<=7);*(p)&=~07;*(p)|=(i);} - +# define getntparams(p) ((p)->n_flags&07) +# define setntparams(p,i) {assert(((unsigned)(i))<=7);(p)->n_flags&=~07;(p)->n_flags|=(i);} # define RECURSIVE 00100 /* Set if the default rule is recursive */ -# define NNOSCAN 00200 /* Set if the nonterminal does not scan ahead */ # define CONTIN 00400 /* continuation already computed? */ # define BUSY 01000 /* or are we busy computing it? */ # define PARAMS 02000 /* tells if a nonterminal has parameters */ @@ -125,8 +121,14 @@ typedef struct { # define LOCALS 020000 /* local declarations ? */ # define REACHABLE 040000 /* can this nonterminal be reached ? */ # define VERBOSE 0100000 /* Set if in LL.output file */ + char n_insafety; + char n_outsafety; +# define getntsafe(p) ((p)->n_insafety) +# define setntsafe(p,i) {assert(((unsigned)(i))<=NOSAFETY);(p)->n_insafety=(i);} +# define getntout(p) ((p)->n_outsafety) +# define setntout(p,i) {assert(((unsigned)(i))<=NOSAFETY);(p)->n_outsafety=(i);} short n_count; /* pieces of code before this rule */ - int n_lineno; /* declared on line ... */ + short n_lineno; /* declared on line ... */ p_gram n_rule; /* pointer to right hand side of rule */ union { p_set n_f; /* ptr to "first" set */ @@ -192,11 +194,12 @@ typedef short t_reps,*p_reps; typedef struct term { t_reps t_reps; /* repeats ? */ short t_flags; +# define gettout(q) ((q)->t_flags&07) +# define settout(q,i) {assert(((unsigned)(i))<=NOSAFETY);(q)->t_flags&=~07;(q)->t_flags|=i;} # define PERSISTENT 010 /* Set if this term has %persistent */ # define RESOLVER 020 /* Set if this term has %while */ # define EMPTYFIRST 0100 /* Error, empty first */ # define EMPTYTERM 0200 /* Error, term can produce empty */ -# define TNOSCAN 0400 /* Set if this term does not scan ahead */ /* # define NOCONF 01000 see link structure */ p_gram t_rule; /* pointer to this term */