More safety, also after terms and nonterminals.
authorceriel <none@none>
Thu, 3 Oct 1985 12:38:55 +0000 (12:38 +0000)
committerceriel <none@none>
Thu, 3 Oct 1985 12:38:55 +0000 (12:38 +0000)
util/LLgen/src/check.c
util/LLgen/src/compute.c
util/LLgen/src/gencode.c
util/LLgen/src/types.h

index 9d3a5b9..ed4b3f8 100644 (file)
@@ -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;
 
index 9c2c66d..30ca877 100644 (file)
@@ -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;
 }
index e3fe33d..751357c 100644 (file)
@@ -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
index 0188ce6..49181bf 100644 (file)
@@ -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 */