improved userhook handling, requiring a change in LLnext and LLskip
This commit is contained in:
parent
451c0d6679
commit
717af548d5
|
@ -44,7 +44,6 @@ static string c_read = "LLread();\n";
|
||||||
# define IDENT 0401
|
# define IDENT 0401
|
||||||
|
|
||||||
static int nlabel; /* count for the generation of labels */
|
static int nlabel; /* count for the generation of labels */
|
||||||
static int nvar; /* count for generation of variables */
|
|
||||||
static int firsts; /* are there any? */
|
static int firsts; /* are there any? */
|
||||||
|
|
||||||
/* In this file the following routines are defined: */
|
/* In this file the following routines are defined: */
|
||||||
|
@ -247,7 +246,6 @@ generate(f) p_file f; {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nlabel = 1;
|
nlabel = 1;
|
||||||
nvar = 1;
|
|
||||||
rulecode(p->n_rule,
|
rulecode(p->n_rule,
|
||||||
i,
|
i,
|
||||||
getntout(p) != NOSCANDONE,
|
getntout(p) != NOSCANDONE,
|
||||||
|
@ -485,7 +483,7 @@ rulecode(p,safety,mustscan,mustpop) register p_gram p; {
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
case ALTERNATION :
|
case ALTERNATION :
|
||||||
alternation(p, safety, mustscan, mustpop, 0, 0);
|
alternation(p, safety, mustscan, mustpop, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
|
@ -494,7 +492,7 @@ rulecode(p,safety,mustscan,mustpop) register p_gram p; {
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
alternation(p, safety, mustscan, mustpop, lb, var) register p_gram p; {
|
alternation(p, safety, mustscan, mustpop, lb) register p_gram p; {
|
||||||
register FILE *f = fpars;
|
register FILE *f = fpars;
|
||||||
register p_link l;
|
register p_link l;
|
||||||
int hulp, hulp1,hulp2;
|
int hulp, hulp1,hulp2;
|
||||||
|
@ -510,14 +508,13 @@ alternation(p, safety, mustscan, mustpop, lb, var) register p_gram p; {
|
||||||
hulp1 = nlabel++;
|
hulp1 = nlabel++;
|
||||||
hulp2 = nlabel++;
|
hulp2 = nlabel++;
|
||||||
if (!lb) lb = hulp1;
|
if (!lb) lb = hulp1;
|
||||||
if (safety <= SAFESCANDONE) unsafe = 0;
|
if (!onerror && safety <= SAFESCANDONE) unsafe = 0;
|
||||||
if (!unsafe) {
|
if (!unsafe) {
|
||||||
genpop(mustpop);
|
genpop(mustpop);
|
||||||
mustpop = NOPOP;
|
mustpop = NOPOP;
|
||||||
}
|
}
|
||||||
if (unsafe && hulp1 == lb) {
|
if (unsafe && hulp1 == lb) {
|
||||||
var = ++nvar;
|
fprintf(f,"L_%d: \n", hulp1);
|
||||||
fprintf(f,"{ int LL_%d = 0;\nL_%d: \n", var, hulp1);
|
|
||||||
}
|
}
|
||||||
fputs("switch(LLcsymb) {\n", f);
|
fputs("switch(LLcsymb) {\n", f);
|
||||||
while (g_gettype(p) != EORULE) {
|
while (g_gettype(p) != EORULE) {
|
||||||
|
@ -525,8 +522,8 @@ alternation(p, safety, mustscan, mustpop, lb, var) register p_gram p; {
|
||||||
if (unsafe && (l->l_flag & DEF)) {
|
if (unsafe && (l->l_flag & DEF)) {
|
||||||
haddefault = 1;
|
haddefault = 1;
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
"default: if (!LL_%d && LLskip()) {LL_%d = 1; goto L_%d;}\ngoto L_%d;\n",
|
"default: if (LLskip()) goto L_%d;\ngoto L_%d;\n",
|
||||||
var, var, lb, hulp2);
|
lb, hulp2);
|
||||||
}
|
}
|
||||||
if (l->l_flag & COND) {
|
if (l->l_flag & COND) {
|
||||||
set = setalloc();
|
set = setalloc();
|
||||||
|
@ -541,8 +538,8 @@ alternation(p, safety, mustscan, mustpop, lb, var) register p_gram p; {
|
||||||
fprintf(f,") goto L_%d;\n", hulp);
|
fprintf(f,") goto L_%d;\n", hulp);
|
||||||
}
|
}
|
||||||
if (!haddefault && (l->l_flag & DEF)) {
|
if (!haddefault && (l->l_flag & DEF)) {
|
||||||
fputs("default:\n", f);
|
|
||||||
haddefault = 1;
|
haddefault = 1;
|
||||||
|
fputs("default:\n", f);
|
||||||
}
|
}
|
||||||
else gencases(l->l_symbs);
|
else gencases(l->l_symbs);
|
||||||
nsafe = SAFE;
|
nsafe = SAFE;
|
||||||
|
@ -569,18 +566,18 @@ alternation(p, safety, mustscan, mustpop, lb, var) register p_gram p; {
|
||||||
else {
|
else {
|
||||||
gencases(l->l_others);
|
gencases(l->l_others);
|
||||||
safety = SAFE;
|
safety = SAFE;
|
||||||
|
unsafe = 0;
|
||||||
}
|
}
|
||||||
if (safety <= SAFESCANDONE) {
|
if (! unsafe) {
|
||||||
genpop(mustpop);
|
genpop(mustpop);
|
||||||
mustpop = NOPOP;
|
mustpop = NOPOP;
|
||||||
}
|
}
|
||||||
alternation(p,safety,mustscan,mustpop,lb,var);
|
alternation(p,safety,mustscan,mustpop,lb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
fputs(c_close, f);
|
fputs(c_close, f);
|
||||||
if (unsafe && hulp1 == lb) fputs(c_close, f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int *
|
STATIC int *
|
||||||
|
@ -718,7 +715,8 @@ codeforterm(q,safety,toplevel) register p_term q; {
|
||||||
rep = r_getkind(q);
|
rep = r_getkind(q);
|
||||||
persistent = (q->t_flags & PERSISTENT);
|
persistent = (q->t_flags & PERSISTENT);
|
||||||
ispushed = NOPOP;
|
ispushed = NOPOP;
|
||||||
if (!(toplevel > 0 && safety <= SAFESCANDONE &&
|
if (!(toplevel > 0 &&
|
||||||
|
(safety == 0 || (!onerror && safety <= SAFESCANDONE)) &&
|
||||||
(rep == OPT || (rep == FIXED && i == 0)))) {
|
(rep == OPT || (rep == FIXED && i == 0)))) {
|
||||||
ispushed = findindex(q->t_contains);
|
ispushed = findindex(q->t_contains);
|
||||||
}
|
}
|
||||||
|
@ -756,7 +754,8 @@ codeforterm(q,safety,toplevel) register p_term q; {
|
||||||
/* '+' or '*', so generate infinite loop */
|
/* '+' or '*', so generate infinite loop */
|
||||||
fputs("for (;;) {\n",f);
|
fputs("for (;;) {\n",f);
|
||||||
}
|
}
|
||||||
else if (safety <= SAFESCANDONE && rep == OPT) {
|
else if (rep == OPT &&
|
||||||
|
(safety == 0 || (!onerror && safety <= SAFESCANDONE))) {
|
||||||
genpop(ispushed);
|
genpop(ispushed);
|
||||||
ispushed = NOPOP;
|
ispushed = NOPOP;
|
||||||
}
|
}
|
||||||
|
@ -780,9 +779,6 @@ codeforterm(q,safety,toplevel) register p_term q; {
|
||||||
if (rep != OPT && rep != FIXED) fputs("continue;\n", f);
|
if (rep != OPT && rep != FIXED) fputs("continue;\n", f);
|
||||||
if (rep != FIXED) {
|
if (rep != FIXED) {
|
||||||
fputs(c_close, f); /* Close switch */
|
fputs(c_close, f); /* Close switch */
|
||||||
if (sw > SAFESCANDONE && (q->t_flags & RESOLVER)) {
|
|
||||||
fputs(c_close, f);
|
|
||||||
}
|
|
||||||
if (rep != OPT) {
|
if (rep != OPT) {
|
||||||
genpop(ispushed);
|
genpop(ispushed);
|
||||||
fputs(c_break, f);
|
fputs(c_break, f);
|
||||||
|
@ -805,18 +801,16 @@ genswhead(q, rep, cnt, safety, ispushed) register p_term q; {
|
||||||
register FILE *f;
|
register FILE *f;
|
||||||
p_set p1;
|
p_set p1;
|
||||||
p_set setalloc();
|
p_set setalloc();
|
||||||
int hulp1, hulp2, var;
|
int hulp1, hulp2;
|
||||||
int safeterm;
|
int safeterm;
|
||||||
|
int termissafe = 0;
|
||||||
|
|
||||||
f = fpars;
|
f = fpars;
|
||||||
if (rep == PLUS) safeterm = gettout(q);
|
if (rep == PLUS) safeterm = gettout(q);
|
||||||
else if (rep == OPT) safeterm = safety;
|
else if (rep == OPT) safeterm = safety;
|
||||||
else /* if (rep == STAR) */ safeterm = max(safety, gettout(q));
|
else /* if (rep == STAR) */ safeterm = max(safety, gettout(q));
|
||||||
if ((q->t_flags & RESOLVER) && safeterm > SAFESCANDONE) {
|
hulp2 = nlabel++;
|
||||||
hulp2 = nlabel++;
|
fprintf(f, "L_%d : ", hulp2);
|
||||||
var = nvar++;
|
|
||||||
fprintf(f, "{ int LL_%d = 0;\nL_%d : ", var, hulp2);
|
|
||||||
}
|
|
||||||
fputs("switch(LLcsymb) {\n", f);
|
fputs("switch(LLcsymb) {\n", f);
|
||||||
if (q->t_flags & RESOLVER) {
|
if (q->t_flags & RESOLVER) {
|
||||||
hulp1 = nlabel++;
|
hulp1 = nlabel++;
|
||||||
|
@ -837,29 +831,29 @@ genswhead(q, rep, cnt, safety, ispushed) register p_term q; {
|
||||||
getaction(0);
|
getaction(0);
|
||||||
fprintf(f, ") goto L_%d;\n", hulp1);
|
fprintf(f, ") goto L_%d;\n", hulp1);
|
||||||
}
|
}
|
||||||
if (safeterm <= SAFESCANDONE) fputs("default:\n", f);
|
if (safeterm == 0 || (!onerror && safeterm <= SAFESCANDONE)) {
|
||||||
|
fputs("default:\n", f);
|
||||||
|
termissafe = 1;
|
||||||
|
}
|
||||||
else gencases(q->t_follow);
|
else gencases(q->t_follow);
|
||||||
if (rep == OPT) genpop(ispushed);
|
if (rep == OPT) genpop(ispushed);
|
||||||
fputs(c_break, f);
|
fputs(c_break, f);
|
||||||
if (safeterm > SAFESCANDONE) {
|
if (! termissafe) {
|
||||||
int i;
|
int i;
|
||||||
|
static int nvar;
|
||||||
|
|
||||||
assert(ispushed != NOPOP);
|
assert(ispushed != NOPOP);
|
||||||
if (ispushed >= 0) i = -ispushed;
|
if (ispushed >= 0) i = -ispushed;
|
||||||
else i = tokens[-(ispushed+1)].t_tokno;
|
else i = tokens[-(ispushed+1)].t_tokno;
|
||||||
fputs("default: if (", f);
|
++nvar;
|
||||||
if (q->t_flags & RESOLVER) {
|
fprintf(f,"default:{int LL_%d=LLnext(%d);\n;if (!LL_%d) {\n",
|
||||||
fprintf(f, "LL_%d ||", var);
|
nvar, i, nvar);
|
||||||
}
|
|
||||||
fprintf(f, "!LLnext(%d)) {\n", i);
|
|
||||||
if (rep == OPT) genpop(ispushed);
|
if (rep == OPT) genpop(ispushed);
|
||||||
fputs(c_break, f);
|
fputs(c_break, f);
|
||||||
fputs(c_close, f);
|
fputs(c_close, f);
|
||||||
if (q->t_flags & RESOLVER) {
|
fprintf(f,"else if (LL_%d & 1) goto L_%d;}\n",nvar, hulp2);
|
||||||
fprintf(f,"LL_%d = 1;\ngoto L_%d;\n", var, hulp2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((q->t_flags & PERSISTENT) && safeterm != SAFE) {
|
if (!onerror && (q->t_flags & PERSISTENT) && safeterm != SAFE) {
|
||||||
gencases(q->t_contains);
|
gencases(q->t_contains);
|
||||||
}
|
}
|
||||||
else gencases(q->t_first);
|
else gencases(q->t_first);
|
||||||
|
|
Loading…
Reference in a new issue