diff --git a/util/LLgen/src/LLgen.g b/util/LLgen/src/LLgen.g index dbd3ece22..9155f9835 100644 --- a/util/LLgen/src/LLgen.g +++ b/util/LLgen/src/LLgen.g @@ -127,16 +127,23 @@ def { register string p; } start = ff; } | C_LEXICAL C_IDENT + /* + * Declaration of a name for the lexical analyser. + * May appear only once + */ { if (!lexical) { lexical = store(lextoken.t_string); } else error(linecount,"Duplicate %%lexical"); } ';' - /* - * Declaration of a name for the lexical analyser. - * May appear only once - */ + | C_ONERROR C_IDENT + { if (! onerror) { + onerror = store(lextoken.t_string); + } + else error(linecount,"Duplicate %%onerror"); + } + ';' | action(0) { acount++; } /* * A global C-declaration diff --git a/util/LLgen/src/extern.h b/util/LLgen/src/extern.h index 81563af52..a021d78cb 100644 --- a/util/LLgen/src/extern.h +++ b/util/LLgen/src/extern.h @@ -63,6 +63,7 @@ extern struct order *sorder, *porder; extern string e_noopen; /* Error message string used often */ extern int verbose; /* Level of verbosity */ extern string lexical; /* name of lexical analyser */ +extern string onerror; /* name of user error handler */ extern int ntneeded; /* ntneeded = 1 if nonterminals are included * in the sets. */ diff --git a/util/LLgen/src/gencode.c b/util/LLgen/src/gencode.c index f78ff4d19..209f9ab18 100644 --- a/util/LLgen/src/gencode.c +++ b/util/LLgen/src/gencode.c @@ -168,12 +168,13 @@ genrecovery() { } } i = maxptr - setptr; - fprintf(fpars, + fprintf(f, "#define LL_LEXI %s\n#define LL_SSIZE %d\n#define LL_NSETS %d\n#define LL_NTERMINALS %d\n", lexical, nbytes, i > 0 ? i : 1, ntokens); + if (onerror) fprintf(f,"#define LL_USERHOOK %s\n", onerror); /* Now generate the routines that call the startsymbols */ for (st = start; st; st = st->ff_next) { fputs(st->ff_name, f); @@ -471,8 +472,11 @@ rulecode(p,safety,mustscan,mustpop) register p_gram p; { genpop(findindex(n->n_contains)); } if (g_gettype(n->n_rule) == EORULE && - safety == getntout(n) && - ! g_getnpar(p)) break; + safety <= getntout(n) && + ! g_getnpar(p)) { + safety = getntout(n); + break; + } fprintf(f,"L%d_%s(\n",g_getnont(p), n->n_name); if (g_getnpar(p)) { controlline(); diff --git a/util/LLgen/src/global.c b/util/LLgen/src/global.c index ebd1061d1..0dce20634 100644 --- a/util/LLgen/src/global.c +++ b/util/LLgen/src/global.c @@ -58,6 +58,7 @@ string f_input; string e_noopen = "Cannot open %s"; int verbose; string lexical; +string onerror; int ntneeded; int ntprint; # ifndef NDEBUG diff --git a/util/LLgen/src/tokens.g b/util/LLgen/src/tokens.g index 54c883833..8e3d76b61 100644 --- a/util/LLgen/src/tokens.g +++ b/util/LLgen/src/tokens.g @@ -67,6 +67,7 @@ STATIC string vallookup(); %token C_PERSISTENT ; %token C_FIRST ; %token C_LEXICAL ; +%token C_ONERROR ; %token C_AVOID ; %token C_PREFER ; %token C_DEFAULT ; @@ -100,6 +101,7 @@ static t_keyw resword[] = { { "first", C_FIRST }, { "start", C_START }, { "lexical", C_LEXICAL }, + { "onerror", C_ONERROR }, { 0, 0 } };