Added non-correcting error recovery stuff

This commit is contained in:
ceriel
1997-02-21 11:27:57 +00:00
parent 8ffc86d8ec
commit 0ed5418bec
21 changed files with 3178 additions and 262 deletions

View File

@@ -21,6 +21,10 @@ extern unsigned int LLscnt[];
extern unsigned int LLtcnt[];
extern int LLcsymb;
#if LL_NON_CORR
extern int LLstartsymb;
#endif
#define LLsdecr(d) {LL_assert(LLscnt[d] > 0); LLscnt[d]--;}
#define LLtdecr(d) {LL_assert(LLtcnt[d] > 0); LLtcnt[d]--;}
#define LLsincr(d) LLscnt[d]++

70
util/LLgen/lib/nc_incl Normal file
View File

@@ -0,0 +1,70 @@
#define LLALT 9999 /* Alternative is following */
#define LLTERMINAL 1 /* Symbol is a terminal */
#define LLNONTERMINAL 2 /* Symbol is a nonterminal */
#define LLEORULE 0 /* No more alternatives */
struct lhs { /* LHS of a rule */
int nr; /* Nr of the nonterminal */
struct symbol *rhs; /* Pointer to RHS */
char first[LLSETSIZE]; /* First set */
char follow[LLSETSIZE]; /* Follow set */
char empty; /* Set if nonterminal produces empty */
};
struct symbol { /* Symbol in the RHS of a rule */
int x; /* LLTERMINAL or LLNONTERMINAL */
int nr; /* Nr of the symbol */
struct symbol *link; /* Ptr to next rule with this symbol */
struct symbol *next; /* Ptr to next symbol in this rule */
struct lhs *lhs; /* Ptr to LHS */
};
struct terminal { /* Array with links to terminals in a */
struct symbol *link; /* rule */
};
struct nonterminal { /* Array with links to nt's in a rule */
struct symbol *link; /* and pointer to LHS's */
struct lhs *rule;
};
struct stack_elt { /* Stack element */
int flags; /* Some flags */
int nr; /* Nr of symbol */
int ref_count; /* Nr of predecessors */
int hyp_ref_count; /* Temporary nr of predecessors */
int matched; /* Nr of LHS trying to match */
int nr_nexts; /* Nr of successors */
struct edge *edges; /* Array of edges to other stack elt's*/
};
/* Possible flags in a stack element */
#define LLHEAD 1 /* Stack element is a head */
#define LLDUMMY 2 /* Stack element is substituted */
#define LLGEN_SEARCH 8 /* Set by 'generate_heads()' */
struct edge { /* Edges of a stack element */
char flags; /* Some flags */
struct stack_elt *ptr; /* Array with pointers to stack elt's */
};
/* Possible flags in an edge */
#define LLLOOP 1 /* Belongs to a loop */
#define LLLOOP_SEARCH 2 /* Used by 'loop()' */
#define LLHYP_SEARCH 4 /* Used by 'hyp_run()' */
#define PRINT_SEARCH 8 /* DEBUG */
#define LLMARK_SEARCH 16 /* Used by 'mark_loop()' */
#define LLYES 32
#define LLNO 64
#define LLEOSTACK -1 /* Indicates last element of a stack */
#define LLHEADS_BUF_INCR 10 /* Nr of elements the buffer will be */
#define LLCLEANUP_BUF_INCR 25 /* increased by */
#define LL_VIS_INCR 200
/* Macro's to manipulate bit sets */
#define LLIN(a, i) ((a)[(i)/8] & (1 << ((i) % 8)))
#define LLPUTIN(a, i) ((a)[(i)/8] |= (1 << ((i) % 8)))

1791
util/LLgen/lib/nc_rec Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,11 @@ unsigned int LLscnt[LL_NSETS];
int LLcsymb, LLsymb;
static int LLlevel;
#if LL_NON_CORR
int LLstartsymb;
static int fake_eof = 0;
#endif
#if LL_ANSI_C
#define LL_VOIDCST (void)
void LLmessage(int);
@@ -39,7 +44,38 @@ LLscan(t)
/*
* Check if the next symbol is equal to the parameter
*/
#if LL_NON_CORR
/* See if the error recovery has eaten an eof */
if (fake_eof) {
LLsymb = EOFILE;
fake_eof = 0;
}
else {
LLsymb = LL_LEXI();
}
if (LLsymb == t) {
#else
if ((LLsymb = LL_LEXI()) == t) {
#endif
#if LL_NON_CORR
/* Check if a previous parser has 'crashed', in that
* case continue with non-correcting parser
*/
if (err_seen && !nc_done) {
LLnc_recover();
nc_done = 1;
/* Remember that the error recovery has eaten an eof */
fake_eof = 1;
if (t != LLsymb) {
LLerror(t);
}
else
return;
}
#endif
return;
}
/*
@@ -54,6 +90,31 @@ void LLread(void) {
#else
LLread() {
#endif
#if LL_NON_CORR
/* Again, check if another parser has crashed,
* in that case intercept and go to the
* non-correcting parser
*/
if (err_seen && !nc_done) {
LLnc_recover();
nc_done = 1;
/* Pretend we read end of file */
LLsymb = EOFILE;
LLcsymb = LLindex[EOFILE];
fake_eof = 0;
return;
}
if (fake_eof) {
LLsymb = EOFILE;
LLcsymb = LLindex[EOFILE];
fake_eof = 0;
return;
}
#endif
for (;;) {
if ((LLcsymb = LLindex[(LLsymb = LL_LEXI())]) >= 0) return;
LLmessage(0);
@@ -85,6 +146,16 @@ LLerror(t)
return;
}
#endif
#if LL_NON_CORR
if ((!nc_done) && (LLsymb > 0) && (LLsymb != EOFILE)) {
LLmessage(0);
LLnc_recover();
nc_done = 1;
LLsymb = EOFILE;
}
#endif
if ((LLcsymb = LLindex[LLsymb]) < 0) {
LLmessage(0);
LLread();
@@ -97,7 +168,25 @@ LLerror(t)
LL_VOIDCST LLskip();
#endif
LLtcnt[i]--;
if (LLsymb != t) LLmessage(t);
if (LLsymb != t) {
#if LL_NON_CORR
/* A little kludge here; when using non-correcting recovery
* it can happen that a program is correct but incomplete.
* Here, we test this, and make sure the appropriate
* message is generated
*/
if (! nc_done) {
int oldLLsymb;
oldLLsymb = LLsymb;
LLsymb = EOFILE;
LLmessage(0);
nc_done = 1;
/* Not really, but to prevent more than 1 error message */
LLsymb = oldLLsymb;
}
#endif
LLmessage(t);
}
}
#if LL_ANSI_C
@@ -121,6 +210,14 @@ LLsafeerror(t)
}
return;
}
#endif
#if LL_NON_CORR
if ((!nc_done) && (LLsymb > 0) && (LLsymb != EOFILE)) {
LLmessage(0);
LLnc_recover();
nc_done = 1;
LLsymb = EOFILE;
}
#endif
LLmessage(t);
}
@@ -265,7 +362,19 @@ static int LLdoskip(e)
continue;
}
#endif /* LL_USERHOOK */
#if LL_NON_CORR
if ((!nc_done) && (LLsymb > 0)) {
LLmessage(0);
LLnc_recover();
nc_done = 1;
fake_eof = 1;
}
else {
LLmessage(0);
}
#else
LLmessage(0);
#endif
retval = 1;
LLread();
}