diff --git a/util/LLgen/src/LLgen.c b/util/LLgen/src/LLgen.c new file mode 100644 index 000000000..6bb52f174 --- /dev/null +++ b/util/LLgen/src/LLgen.c @@ -0,0 +1,1415 @@ +/* LLgen generated code from source LLgen.g */ +#include "Lpars.h" +#define LL_LEXI scanner +#define LLNOFIRSTS +#if __STDC__ || __cplusplus +#define LL_ANSI_C 1 +#endif +#define LL_LEXI scanner +/* $Id$ */ +#ifdef LL_DEBUG +#include +#include +#define LL_assert(x) assert(x) +#else +#define LL_assert(x) /* nothing */ +#endif + +extern int LLsymb; + +#define LL_SAFE(x) /* Nothing */ +#define LL_SSCANDONE(x) if (LLsymb != x) LLsafeerror(x) +#define LL_SCANDONE(x) if (LLsymb != x) LLerror(x) +#define LL_NOSCANDONE(x) LLscan(x) +#ifdef LL_FASTER +#define LLscan(x) if ((LLsymb = LL_LEXI()) != x) LLerror(x) +#endif + +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]++ +#define LLtincr(d) LLtcnt[d]++ + +#if LL_ANSI_C +extern int LL_LEXI(void); +extern void LLread(void); +extern int LLskip(void); +extern int LLnext(int); +extern void LLerror(int); +extern void LLsafeerror(int); +extern void LLnewlevel(unsigned int *); +extern void LLoldlevel(unsigned int *); +#ifndef LL_FASTER +extern void LLscan(int); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(int, int); +#endif +#if LL_NON_CORR +extern void LLnc_recover(void); +#endif +#else /* not LL_ANSI_C */ +extern LLread(); +extern int LLskip(); +extern int LLnext(); +extern LLerror(); +extern LLsafeerror(); +extern LLnewlevel(); +extern LLoldlevel(); +#ifndef LL_FASTER +extern LLscan(); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(); +#endif +#if LL_NON_CORR +extern LLnc_recover(); +#endif +#endif /* not LL_ANSI_C */ +# line 20 "LLgen.g" + +# include +# include +# include "types.h" +# include "io.h" +# include "extern.h" +# include "assert.h" +# include "cclass.h" + +# ifndef NORCSID +static string rcsid = "$Id$"; +# endif +p_mem alloc(), ralloc(); +string store(); +p_gram search(); +long ftell(); + +static int acount; /* count #of global actions */ +static p_term t_list; +static int t_cnt; +static p_gram alt_table; +static int n_alts; +static int max_alts; +#define ALTINCR 32 + +static p_gram rule_table; +static int n_rules; +static int max_rules; +#define RULEINCR 32 + +/* Here are defined : */ +STATIC newnorder(); +STATIC newtorder(); +STATIC mkalt(); +STATIC mkterm(); +STATIC p_gram copyrule(); +/* and of course LLparse() */ + +STATIC +newnorder(index) { + static int porder; + + if (norder != -1) { + nonterms[porder].n_next = index; + } + else norder = index; + porder = index; + nonterms[porder].n_next = -1; +} + +STATIC +newtorder(index) { + static int porder; + + if (torder != -1) { + tokens[porder].t_next = index; + } + else torder = index; + porder = index; + tokens[porder].t_next = -1; +} + +p_init() +{ + alt_table = (p_gram )alloc(ALTINCR*sizeof(t_gram)); + n_alts = 0; + max_alts = ALTINCR; + rule_table = (p_gram )alloc(RULEINCR*sizeof(t_gram)); + n_rules = 0; + max_rules = RULEINCR; +} + +#if LL_ANSI_C +static void LL1_def(void); +static void LL2_rule(void); +static void LL3_listel(void); +static void LL4_firsts(void); +static void LL5_productions( +# line 246 "LLgen.g" +p_gram *p) ; +static void LL6_simpleproduction( +# line 332 "LLgen.g" +p_gram *p ,register int *conflres) ; +static void LL7_elem( +# line 480 "LLgen.g" +register p_gram pres) ; +static void LL8_repeats( +# line 602 "LLgen.g" +int *kind ,int *cnt) ; +static void LL9_number( +# line 619 "LLgen.g" +int *t) ; +#else +static LL1_def(); +static LL2_rule(); +static LL3_listel(); +static LL4_firsts(); +static LL5_productions(); +static LL6_simpleproduction(); +static LL7_elem(); +static LL8_repeats(); +static LL9_number(); +#endif +#if LL_ANSI_C +void +#endif +LL0_spec( +#if LL_ANSI_C +void +#endif +) { +LLsincr(0); +# line 96 "LLgen.g" +{ acount = 0; p_init(); } +for (;;) { +goto L_1; +L_1 : {switch(LLcsymb) { +case /* EOFILE */ 0 : ; +break; +default:{int LL_1=LLnext(0); +;if (!LL_1) { +break; +} +else if (LL_1 & 1) goto L_1;} +case /* C_IDENT */ 2 : ; +case /* C_ACTION */ 7 : ; +case /* C_TOKEN */ 8 : ; +case /* C_START */ 9 : ; +case /* C_FIRST */ 13 : ; +case /* C_LEXICAL */ 14 : ; +case /* C_PREFIX */ 15 : ; +case /* C_ONERROR */ 16 : ; +LL1_def(); +LLread(); +continue; +} +} +LLsdecr(0); +break; +} +# line 98 "LLgen.g" +{ /* + * Put an endmarker in temporary file + */ + putc('\0', fact); + putc('\0', fact); + free((p_mem) rule_table); + free((p_mem) alt_table); + } +} +static +#if LL_ANSI_C +void +#endif +LL1_def( +#if LL_ANSI_C +void +#endif +) { +# line 108 "LLgen.g" + register string p; +switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +LL2_rule(); +break; +case /* C_TOKEN */ 8 : ; +LLtincr(23); +LLtincr(24); +LL_SAFE(C_TOKEN); +LL3_listel(); +LLread(); +for (;;) { +goto L_4; +L_4 : {switch(LLcsymb) { +case /* ';' */ 24 : ; +break; +default:{int LL_2=LLnext(44); +;if (!LL_2) { +break; +} +else if (LL_2 & 1) goto L_4;} +case /* ',' */ 23 : ; +LL_SAFE(','); +LL3_listel(); +LLread(); +continue; +} +} +LLtdecr(23); +break; +} +LLtdecr(24); +LL_SSCANDONE(';'); +break; +case /* C_START */ 9 : ; +LLtincr(23); +LLtincr(2); +LLtincr(24); +LL_SAFE(C_START); +LL_NOSCANDONE(C_IDENT); +# line 118 "LLgen.g" +{ p = store(lextoken.t_string); } +LLtdecr(23); +LL_NOSCANDONE(','); +LLtdecr(2); +LL_NOSCANDONE(C_IDENT); +# line 123 "LLgen.g" +{ /* + * Put the declaration in the list + * of start symbols + */ + register p_gram temp; + register p_start ff; + + temp = search(NONTERM,lextoken.t_string,BOTH); + ff = (p_start) alloc(sizeof(t_start)); + ff->ff_nont = g_getcont(temp); + ff->ff_name = p; + ff->ff_next = start; + start = ff; + while (ff = ff->ff_next) { + if (! strcmp(p, ff->ff_name)) { + error(linecount, "\"%s\" already used in a %%start", p); + break; + } + } + } +LLtdecr(24); +LL_NOSCANDONE(';'); +break; +case /* C_LEXICAL */ 14 : ; +LLtincr(24); +LL_SAFE(C_LEXICAL); +LL_NOSCANDONE(C_IDENT); +# line 149 "LLgen.g" +{ if (!lexical) { + lexical = store(lextoken.t_string); + } + else error(linecount,"Duplicate %%lexical"); + } +LLtdecr(24); +LL_NOSCANDONE(';'); +break; +case /* C_PREFIX */ 15 : ; +LLtincr(24); +LL_SAFE(C_PREFIX); +LL_NOSCANDONE(C_IDENT); +# line 159 "LLgen.g" +{ if (!prefix) { + prefix = store(lextoken.t_string); + if (strlen(prefix) > 6) { + error(linecount, + "%%prefix too long"); + prefix[6] = 0; + } + } + else error(linecount,"Duplicate %%prefix"); + } +LLtdecr(24); +LL_NOSCANDONE(';'); +break; +case /* C_ONERROR */ 16 : ; +LLtincr(24); +LL_SAFE(C_ONERROR); +LL_NOSCANDONE(C_IDENT); +# line 171 "LLgen.g" +{ +#ifdef NON_CORRECTING + if (non_corr) { + warning(linecount, "%%onerror conflicts with -n option"); + } + else +#endif + if (! onerror) { + onerror = store(lextoken.t_string); + } + else error(linecount,"Duplicate %%onerror"); + } +LLtdecr(24); +LL_NOSCANDONE(';'); +break; +default: +LL_SSCANDONE(C_ACTION); +# line 184 "LLgen.g" +{ acount++; } +break; +case /* C_FIRST */ 13 : ; +LL4_firsts(); +break; +} +} +static +#if LL_ANSI_C +void +#endif +LL3_listel( +#if LL_ANSI_C +void +#endif +) { +LL_NOSCANDONE(C_IDENT); +# line 194 "LLgen.g" +{ p_gram temp = search(TERMINAL,lextoken.t_string,ENTERING); + newtorder(g_getcont(temp)); + tokens[g_getcont(temp)].t_lineno = linecount; + } +} +static +#if LL_ANSI_C +void +#endif +LL2_rule( +#if LL_ANSI_C +void +#endif +) { +# line 200 "LLgen.g" + register p_nont p; + p_gram rr; + register p_gram temp; + +LLtincr(6); +LLtincr(7); +LLtincr(25); +LLsincr(1); +LLtincr(24); +LL_SAFE(C_IDENT); +# line 207 "LLgen.g" +{ temp = search(NONTERM,lextoken.t_string,BOTH); + p = &nonterms[g_getcont(temp)]; + if (p->n_rule) { + error(linecount, +"Nonterminal %s already defined", lextoken.t_string); + } + /* + * Remember the order in which the nonterminals + * were defined. Code must be generated in that + * order to keep track with the actions on the + * temporary file + */ + newnorder(p - nonterms); + p->n_count = acount; + acount = 0; + p->n_lineno = linecount; + p->n_off = ftell(fact); + } +LLread(); +goto L_1; +L_1 : {switch(LLcsymb) { +case /* C_ACTION */ 7 : ; +case /* ':' */ 25 : ; +LLtdecr(6); +break; +default:{int LL_3=LLnext(262); +;if (!LL_3) { +LLtdecr(6); +break; +} +else if (LL_3 & 1) goto L_1;} +case /* C_PARAMS */ 6 : ; +LLtdecr(6); +LL_SAFE(C_PARAMS); +# line 225 "LLgen.g" +{ if (lextoken.t_num > 0) { + p->n_flags |= PARAMS; + if (lextoken.t_num > 15) { + error(linecount,"Too many parameters"); + } + else setntparams(p,lextoken.t_num); + } + } +LLread(); +} +} +goto L_2; +L_2 : {switch(LLcsymb) { +case /* ':' */ 25 : ; +LLtdecr(7); +break; +default:{int LL_4=LLnext(263); +;if (!LL_4) { +LLtdecr(7); +break; +} +else if (LL_4 & 1) goto L_2;} +case /* C_ACTION */ 7 : ; +LLtdecr(7); +LL_SAFE(C_ACTION); +# line 234 "LLgen.g" +{ p->n_flags |= LOCALS; } +LLread(); +} +} +LLtdecr(25); +LL_SCANDONE(':'); +# line 236 "LLgen.g" +{ in_production = 1; } +LLread(); +LLsdecr(1); +LL5_productions( +# line 237 "LLgen.g" +&rr); +LLtdecr(24); +LL_SCANDONE(';'); +# line 238 "LLgen.g" +{ in_production = 0; } +# line 243 "LLgen.g" +{ nonterms[g_getcont(temp)].n_rule = rr;} +} +static +#if LL_ANSI_C +void +#endif +LL5_productions( +#if LL_ANSI_C +# line 246 "LLgen.g" +p_gram *p) +#else +# line 246 "LLgen.g" + p) p_gram *p; +#endif +{ +# line 250 "LLgen.g" + p_gram prod; + int conflres = 0; + int t = 0; + int haddefault = 0; + int altcnt = 0; + int o_lc, n_lc; + +LLtincr(26); +# line 257 "LLgen.g" +{ o_lc = linecount; } +LL6_simpleproduction( +# line 258 "LLgen.g" +p,&conflres); +# line 259 "LLgen.g" +{ if (conflres & DEF) haddefault = 1; } +goto L_2; /* so that the label is used for certain */ +L_2: ; +switch(LLcsymb) { +case /* '|' */ 26 : ; +LLtdecr(26); +LLsincr(1); +LLsdecr(1); +LLtincr(26); +for (;;) { +LL_SAFE('|'); +# line 261 "LLgen.g" +{ n_lc = linecount; } +LLread(); +LL6_simpleproduction( +# line 262 "LLgen.g" +&prod,&t); +# line 263 "LLgen.g" +{ if (n_alts >= max_alts-2) { + alt_table = (p_gram ) ralloc( + (p_mem) alt_table, + (unsigned)(max_alts+=ALTINCR)*sizeof(t_gram)); + } + if (t & DEF) { + if (haddefault) { + error(n_lc, + "More than one %%default in alternation"); + } + haddefault = 1; + } + mkalt(*p,conflres,o_lc,&alt_table[n_alts++]); + altcnt++; + o_lc = n_lc; + conflres = t; + t = 0; + *p = prod; + } +goto L_4; +L_4 : {switch(LLcsymb) { +case /* ';' */ 24 : ; +case /* ']' */ 28 : ; +break; +default:{int LL_5=LLnext(124); +;if (!LL_5) { +break; +} +else if (LL_5 & 1) goto L_4;} +case /* '|' */ 26 : ; +continue; +} +} +LLtdecr(26); +break; +} +# line 282 "LLgen.g" +{ if (conflres & (COND|PREFERING|AVOIDING)) { + error(n_lc, + "Resolver on last alternative not allowed"); + } + mkalt(*p,conflres,n_lc,&alt_table[n_alts++]); + altcnt++; + g_settype((&alt_table[n_alts]),EORULE); + *p = copyrule(&alt_table[n_alts-altcnt],altcnt+1); + } +break; +case /* ';' */ 24 : ; +case /* ']' */ 28 : ; +goto L_3; +L_3: ; +LLtdecr(26); +# line 292 "LLgen.g" +{ if (conflres & (COND|PREFERING|AVOIDING)) { + error(o_lc, + "No alternation conflict resolver allowed here"); + } + /* + if (conflres & DEF) { + error(o_lc, + "No %%default allowed here"); + } + */ + } +break; +default: if (LLskip()) goto L_2; +goto L_3; +} +# line 304 "LLgen.g" +{ n_alts -= altcnt; } +} +# line 306 "LLgen.g" + + +STATIC +mkalt(prod,condition,lc,res) p_gram prod; register p_gram res; { + /* + * Create an alternation and initialise it. + */ + register p_link l; + static p_link list; + static int cnt; + + if (! cnt) { + cnt = 50; + list = (p_link) alloc(50 * sizeof(t_link)); + } + cnt--; + l = list++; + l->l_rule = prod; + l->l_flag = condition; + g_setlink(res,l); + g_settype(res,ALTERNATION); + res->g_lineno = lc; + nalts++; +} +static +#if LL_ANSI_C +void +#endif +LL6_simpleproduction( +#if LL_ANSI_C +# line 332 "LLgen.g" +p_gram *p ,register int *conflres) +#else +# line 332 "LLgen.g" + p,conflres) p_gram *p; register int *conflres; +#endif +{ +# line 333 "LLgen.g" + t_gram elem; + int elmcnt = 0; + int cnt, kind; + int termdeleted = 0; + +LLtincr(19); +LLsincr(2); +LLtincr(22); +LLsincr(3); +goto L_1; +L_1 : {switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_IF */ 10 : ; +case /* C_AVOID */ 17 : ; +case /* C_PREFER */ 18 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* C_ILLEGAL */ 22 : ; +case /* ';' */ 24 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +LLtdecr(19); +break; +default:{int LL_6=LLnext(275); +;if (!LL_6) { +LLtdecr(19); +break; +} +else if (LL_6 & 1) goto L_1;} +case /* C_DEFAULT */ 19 : ; +LLtdecr(19); +LL_SAFE(C_DEFAULT); +# line 338 "LLgen.g" +{ *conflres |= DEF; } +LLread(); +} +} +goto L_2; +L_2 : {switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* C_ILLEGAL */ 22 : ; +case /* ';' */ 24 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +LLsdecr(2); +break; +default:{int LL_7=LLnext(-8); +;if (!LL_7) { +LLsdecr(2); +break; +} +else if (LL_7 & 1) goto L_2;} +case /* C_IF */ 10 : ; +case /* C_AVOID */ 17 : ; +case /* C_PREFER */ 18 : ; +LLsdecr(2); +switch(LLcsymb) { +case /* C_IF */ 10 : ; +LL_SAFE(C_IF); +LL_NOSCANDONE(C_EXPR); +# line 344 "LLgen.g" +{ *conflres |= COND; } +break; +default: +LL_SAFE(C_PREFER); +# line 345 "LLgen.g" +{ *conflres |= PREFERING; } +break; +case /* C_AVOID */ 17 : ; +LL_SAFE(C_AVOID); +# line 346 "LLgen.g" +{ *conflres |= AVOIDING; } +break; +} +LLread(); +} +} +goto L_6; +L_6 : {switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* ';' */ 24 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +LLtdecr(22); +break; +default:{int LL_8=LLnext(278); +;if (!LL_8) { +LLtdecr(22); +break; +} +else if (LL_8 & 1) goto L_6;} +case /* C_ILLEGAL */ 22 : ; +LLtdecr(22); +LL_SAFE(C_ILLEGAL); +# line 348 "LLgen.g" +{ +#ifdef NON_CORRECTING + if (n_rules >= max_rules-2) { + rule_table = (p_gram) ralloc( + (p_mem) rule_table, + (unsigned)(max_rules+=RULEINCR)*sizeof(t_gram)); + } + elmcnt++; + rule_table[n_rules++] = + *search(TERMINAL, "LLILLEGAL", BOTH); + if (*conflres & DEF) { + error(linecount, "%%illegal not allowed in %%default rule"); + } +#endif + } +LLread(); +} +} +for (;;) { +goto L_7; +L_7 : {switch(LLcsymb) { +case /* ';' */ 24 : ; +case /* '|' */ 26 : ; +case /* ']' */ 28 : ; +break; +default:{int LL_9=LLnext(-12); +;if (!LL_9) { +break; +} +else if (LL_9 & 1) goto L_7;} +case /* C_IDENT */ 2 : ; +case /* C_NUMBER */ 3 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* '[' */ 27 : ; +case /* '?' */ 29 : ; +case /* '*' */ 30 : ; +case /* '+' */ 31 : ; +LLsincr(4); +LL7_elem( +# line 364 "LLgen.g" +&elem); +# line 365 "LLgen.g" +{ if (n_rules >= max_rules-2) { + rule_table = (p_gram) ralloc( + (p_mem) rule_table, + (unsigned)(max_rules+=RULEINCR)*sizeof(t_gram)); + } + kind = FIXED; + cnt = 0; + } +goto L_9; /* so that the label is used for certain */ +L_9: ; +switch(LLcsymb) { +case /* C_NUMBER */ 3 : ; +case /* '?' */ 29 : ; +case /* '*' */ 30 : ; +case /* '+' */ 31 : ; +LLsdecr(4); +LL8_repeats( +# line 373 "LLgen.g" +&kind, &cnt); +# line 374 "LLgen.g" +{ if (g_gettype(&elem) != TERM) { + rule_table[n_rules] = elem; + g_settype((&rule_table[n_rules+1]),EORULE); + mkterm(copyrule(&rule_table[n_rules],2), + 0, + elem.g_lineno, + &elem); + } + } +break; +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* ';' */ 24 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +goto L_10; +L_10: ; +LLsdecr(4); +# line 384 "LLgen.g" +{ if (g_gettype(&elem) == TERM) { + register p_term q = g_getterm(&elem); + + if (! (q->t_flags & RESOLVER) && + g_gettype(q->t_rule) != ALTERNATION && + g_gettype(q->t_rule) != EORULE) { + while (g_gettype(q->t_rule) != EORULE) { + rule_table[n_rules++] = *q->t_rule++; + elmcnt++; + if (n_rules >= max_rules-2) { + rule_table = (p_gram) ralloc( + (p_mem) rule_table, + (unsigned)(max_rules+=RULEINCR)*sizeof(t_gram)); + } + } + elem = *--(q->t_rule); + n_rules--; + elmcnt--; + if (q == t_list - 1) { + t_list--; + nterms--; + t_cnt++; + } + termdeleted = 1; + } + } + } +break; +default: if (LLskip()) goto L_9; +goto L_10; +} +# line 411 "LLgen.g" +{ if (!termdeleted && g_gettype(&elem) == TERM) { + register p_term q; + + q = g_getterm(&elem); + r_setkind(q,kind); + r_setnum(q,cnt); + if ((q->t_flags & RESOLVER) && + (kind == PLUS || kind == FIXED)) { + error(linecount, + "%%while not allowed in this term"); + } + /* + * A persistent fixed term is the same + * as a non-persistent fixed term. + * Should we complain? + if ((q->t_flags & PERSISTENT) && + kind == FIXED) { + error(linecount, + "Illegal %%persistent"); + } + */ + } + termdeleted = 0; + elmcnt++; + rule_table[n_rules++] = elem; + } +continue; +} +} +LLsdecr(3); +break; +} +# line 437 "LLgen.g" +{ register p_term q; + + g_settype((&rule_table[n_rules]),EORULE); + *p = 0; + n_rules -= elmcnt; + if (g_gettype(&rule_table[n_rules]) == TERM && + elmcnt == 1) { + q = g_getterm(&rule_table[n_rules]); + if (r_getkind(q) == FIXED && + r_getnum(q) == 0) { + *p = q->t_rule; + } + } + if (!*p) *p = copyrule(&rule_table[n_rules], + elmcnt+1); + } +} +# line 454 "LLgen.g" + + +STATIC +mkterm(prod,flags,lc,result) p_gram prod; register p_gram result; { + /* + * Create a term, initialise it and return + * a grammar element containing it + */ + register p_term q; + + if (! t_cnt) { + t_cnt = 50; + t_list = (p_term) alloc(50 * sizeof(t_term)); + } + t_cnt--; + q = t_list++; + q->t_rule = prod; + q->t_contains = 0; + q->t_flags = flags; + g_settype(result,TERM); + g_setterm(result,q); + result->g_lineno = lc; + nterms++; +} +static +#if LL_ANSI_C +void +#endif +LL7_elem( +#if LL_ANSI_C +# line 480 "LLgen.g" +register p_gram pres) +#else +# line 480 "LLgen.g" + pres) register p_gram pres; +#endif +{ +# line 481 "LLgen.g" + register int t = 0; + p_gram p1; + int ln; + p_gram pe; +#ifdef NON_CORRECTING + int erroneous = 0; +#endif + +switch(LLcsymb) { +case /* '[' */ 27 : ; +LLtincr(11); +LLtincr(12); +LLsincr(1); +LLtincr(28); +LL_SAFE('['); +# line 489 "LLgen.g" +{ ln = linecount; } +LLread(); +goto L_4; +L_4 : {switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_IF */ 10 : ; +case /* C_PERSISTENT */ 12 : ; +case /* C_AVOID */ 17 : ; +case /* C_PREFER */ 18 : ; +case /* C_DEFAULT */ 19 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* C_ILLEGAL */ 22 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +LLtdecr(11); +break; +default:{int LL_10=LLnext(267); +;if (!LL_10) { +LLtdecr(11); +break; +} +else if (LL_10 & 1) goto L_4;} +case /* C_WHILE */ 11 : ; +LLtdecr(11); +LL_SAFE(C_WHILE); +LL_NOSCANDONE(C_EXPR); +# line 490 "LLgen.g" +{ t |= RESOLVER; } +LLread(); +} +} +goto L_5; +L_5 : {switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_IF */ 10 : ; +case /* C_AVOID */ 17 : ; +case /* C_PREFER */ 18 : ; +case /* C_DEFAULT */ 19 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* C_ILLEGAL */ 22 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +LLtdecr(12); +break; +default:{int LL_11=LLnext(268); +;if (!LL_11) { +LLtdecr(12); +break; +} +else if (LL_11 & 1) goto L_5;} +case /* C_PERSISTENT */ 12 : ; +LLtdecr(12); +LL_SAFE(C_PERSISTENT); +# line 492 "LLgen.g" +{ t |= PERSISTENT; } +LLread(); +} +} +LLsdecr(1); +LL5_productions( +# line 494 "LLgen.g" +&p1); +LLtdecr(28); +LL_SCANDONE(']'); +# line 495 "LLgen.g" +{ + mkterm(p1,t,ln,pres); + } +LLread(); +break; +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ERRONEOUS */ 21 : ; +LLsincr(5); +goto L_6; +L_6 : {switch(LLcsymb) { +default: +break; +case /* C_ERRONEOUS */ 21 : ; +LL_SAFE(C_ERRONEOUS); +# line 499 "LLgen.g" +{ +#ifdef NON_CORRECTING + erroneous = 1; +#endif + } +LLread(); +} +} +goto L_8; /* so that the label is used for certain */ +L_8: ; +switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +goto L_9; +L_9: ; +LLsdecr(5); +LLtincr(6); +LL_SSCANDONE(C_IDENT); +# line 507 "LLgen.g" +{ pe = search(UNKNOWN,lextoken.t_string,BOTH); + *pres = *pe; +#ifdef NON_CORRECTING + if (erroneous) { + if (g_gettype(pres) != TERMINAL){ + warning(linecount, + "Erroneous only allowed on terminal"); + erroneous = 0; + } + else + pres->g_erroneous = 1; + } +#endif + + } +LLread(); +goto L_10; +L_10 : {switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +case /* C_NUMBER */ 3 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* ';' */ 24 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +case /* '?' */ 29 : ; +case /* '*' */ 30 : ; +case /* '+' */ 31 : ; +LLtdecr(6); +break; +default:{int LL_12=LLnext(262); +;if (!LL_12) { +LLtdecr(6); +break; +} +else if (LL_12 & 1) goto L_10;} +case /* C_PARAMS */ 6 : ; +LLtdecr(6); +LL_SAFE(C_PARAMS); +# line 522 "LLgen.g" +{ if (lextoken.t_num > 15) { + error(linecount,"Too many parameters"); + } else g_setnpar(pres,lextoken.t_num); + if (g_gettype(pres) == TERMINAL) { + error(linecount, + "Terminal with parameters"); + } + } +LLread(); +} +} +break; +default: if (LLskip()) goto L_8; +goto L_9; +case /* C_LITERAL */ 4 : ; +LLsdecr(5); +LL_SAFE(C_LITERAL); +# line 531 "LLgen.g" +{ pe = search(LITERAL,lextoken.t_string,BOTH); + *pres = *pe; +#ifdef NON_CORRECTING + if (erroneous) + pres->g_erroneous = 1; +#endif + } +LLread(); +break; +} +break; +default: +LLtincr(7); +# line 539 "LLgen.g" +{ g_settype(pres,ACTION); + pres->g_lineno = linecount; +#ifdef NON_CORRECTING + g_setsubparse(pres, (p_start) 0); +#endif + } +goto L_11; +L_11 : {switch(LLcsymb) { +default: +break; +case /* C_SUBSTART */ 20 : ; +LLtincr(23); +LLtincr(24); +LL_SAFE(C_SUBSTART); +# line 548 "LLgen.g" +{ +#ifdef NON_CORRECTING + nsubstarts++; +#endif + } +LL_NOSCANDONE(C_IDENT); +# line 555 "LLgen.g" +{ +#ifdef NON_CORRECTING + register p_gram temp; + register p_start subp; + + temp = search(NONTERM,lextoken.t_string,BOTH); + subp = (p_start) alloc (sizeof(t_start)); + + subp->ff_nont = g_getcont(temp); + subp->ff_name = (string) 0; + subp->ff_next = (p_start) 0; + g_setsubparse(pres, subp); +#endif + } +LLread(); +for (;;) { +goto L_12; +L_12 : {switch(LLcsymb) { +case /* ';' */ 24 : ; +break; +default:{int LL_13=LLnext(44); +;if (!LL_13) { +break; +} +else if (LL_13 & 1) goto L_12;} +case /* ',' */ 23 : ; +LL_SAFE(','); +LL_NOSCANDONE(C_IDENT); +# line 571 "LLgen.g" +{ +#ifdef NON_CORRECTING + register p_gram temp; + register p_start ff; + + temp = search(NONTERM,lextoken.t_string,BOTH); + + ff = g_getsubparse(pres); + while (ff) { + if (ff->ff_nont == g_getcont(temp)) { + warning(linecount, "\"%s\" used twice in %%substart", lextoken.t_string); + break; + } + ff = ff->ff_next; + + } + + ff = (p_start) alloc(sizeof(t_start)); + ff->ff_nont = g_getcont(temp); + ff->ff_name = (string) 0; + ff->ff_next = g_getsubparse(pres); + g_setsubparse(pres, ff); +#endif + } +LLread(); +continue; +} +} +LLtdecr(23); +break; +} +LLtdecr(24); +LL_SSCANDONE(';'); +LLread(); +} +} +LLtdecr(7); +LL_SCANDONE(C_ACTION); +LLread(); +break; +} +} +static +#if LL_ANSI_C +void +#endif +LL8_repeats( +#if LL_ANSI_C +# line 602 "LLgen.g" +int *kind ,int *cnt) +#else +# line 602 "LLgen.g" + kind,cnt) int *kind; int *cnt; +#endif +{ +# line 602 "LLgen.g" + int t1 = 0; +switch(LLcsymb) { +default: +LL_SAFE('?'); +# line 604 "LLgen.g" +{ *kind = OPT; } +LLread(); +break; +case /* '*' */ 30 : ; +case /* '+' */ 31 : ; +LLtincr(3); +switch(LLcsymb) { +default: +LL_SAFE('*'); +# line 605 "LLgen.g" +{ *kind = STAR; } +break; +case /* '+' */ 31 : ; +LL_SAFE('+'); +# line 606 "LLgen.g" +{ *kind = PLUS; } +break; +} +LLread(); +goto L_7; +L_7 : {switch(LLcsymb) { +case /* C_IDENT */ 2 : ; +case /* C_LITERAL */ 4 : ; +case /* C_ACTION */ 7 : ; +case /* C_SUBSTART */ 20 : ; +case /* C_ERRONEOUS */ 21 : ; +case /* ';' */ 24 : ; +case /* '|' */ 26 : ; +case /* '[' */ 27 : ; +case /* ']' */ 28 : ; +LLtdecr(3); +break; +default:{int LL_14=LLnext(259); +;if (!LL_14) { +LLtdecr(3); +break; +} +else if (LL_14 & 1) goto L_7;} +case /* C_NUMBER */ 3 : ; +LLtdecr(3); +LL9_number( +# line 608 "LLgen.g" +&t1); +LLread(); +} +} +# line 609 "LLgen.g" +{ if (t1 == 1) { + t1 = 0; + if (*kind == STAR) *kind = OPT; + if (*kind == PLUS) *kind = FIXED; + } + } +break; +case /* C_NUMBER */ 3 : ; +LL9_number( +# line 615 "LLgen.g" +&t1); +LLread(); +break; +} +# line 616 "LLgen.g" +{ *cnt = t1; } +} +static +#if LL_ANSI_C +void +#endif +LL9_number( +#if LL_ANSI_C +# line 619 "LLgen.g" +int *t) +#else +# line 619 "LLgen.g" + t) int *t; +#endif +{ +LL_SAFE(C_NUMBER); +# line 621 "LLgen.g" +{ *t = lextoken.t_num; + if (*t <= 0 || *t >= 8192) { + error(linecount,"Illegal number"); + } + } +} +static +#if LL_ANSI_C +void +#endif +LL4_firsts( +#if LL_ANSI_C +void +#endif +) { +# line 628 "LLgen.g" + register string p; +LLtincr(23); +LLtincr(2); +LLtincr(24); +LL_SAFE(C_FIRST); +LL_NOSCANDONE(C_IDENT); +# line 630 "LLgen.g" +{ p = store(lextoken.t_string); } +LLtdecr(23); +LL_NOSCANDONE(','); +LLtdecr(2); +LL_NOSCANDONE(C_IDENT); +LLtdecr(24); +LL_NOSCANDONE(';'); +# line 632 "LLgen.g" +{ /* + * Store this %first in the list belonging + * to this input file + */ + p_gram temp; + register p_first ff; + + temp = search(NONTERM,lextoken.t_string,BOTH); + ff = (p_first) alloc(sizeof(t_first)); + ff->ff_nont = g_getcont(temp); + ff->ff_name = p; + ff->ff_next = pfile->f_firsts; + pfile->f_firsts = ff; + } +} + +# line 647 "LLgen.g" + + +STATIC p_gram +copyrule(p,length) register p_gram p; { + /* + * Returns a pointer to a grammar rule that was created in + * p. The space pointed to by p can now be reused + */ + register p_gram t; + p_gram rule; + + t = (p_gram) alloc((unsigned) length * sizeof(t_gram)); + rule = t; + while (length--) { + *t++ = *p++; + } + return rule; +} + diff --git a/util/LLgen/src/Lpars.c b/util/LLgen/src/Lpars.c new file mode 100644 index 000000000..e241c0e9a --- /dev/null +++ b/util/LLgen/src/Lpars.c @@ -0,0 +1,826 @@ +/* LLgen generated code from source . */ +#include "Lpars.h" +#define LLNOFIRSTS +#if __STDC__ || __cplusplus +#define LL_ANSI_C 1 +#endif +#define LL_LEXI scanner +/* $Id$ */ +#ifdef LL_DEBUG +#include +#include +#define LL_assert(x) assert(x) +#else +#define LL_assert(x) /* nothing */ +#endif + +extern int LLsymb; + +#define LL_SAFE(x) /* Nothing */ +#define LL_SSCANDONE(x) if (LLsymb != x) LLsafeerror(x) +#define LL_SCANDONE(x) if (LLsymb != x) LLerror(x) +#define LL_NOSCANDONE(x) LLscan(x) +#ifdef LL_FASTER +#define LLscan(x) if ((LLsymb = LL_LEXI()) != x) LLerror(x) +#endif + +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]++ +#define LLtincr(d) LLtcnt[d]++ + +#if LL_ANSI_C +extern int LL_LEXI(void); +extern void LLread(void); +extern int LLskip(void); +extern int LLnext(int); +extern void LLerror(int); +extern void LLsafeerror(int); +extern void LLnewlevel(unsigned int *); +extern void LLoldlevel(unsigned int *); +#ifndef LL_FASTER +extern void LLscan(int); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(int, int); +#endif +#if LL_NON_CORR +extern void LLnc_recover(void); +#endif +#else /* not LL_ANSI_C */ +extern LLread(); +extern int LLskip(); +extern int LLnext(); +extern LLerror(); +extern LLsafeerror(); +extern LLnewlevel(); +extern LLoldlevel(); +#ifndef LL_FASTER +extern LLscan(); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(); +#endif +#if LL_NON_CORR +extern LLnc_recover(); +#endif +#endif /* not LL_ANSI_C */ +#define LL_SSIZE 4 +#define LL_NSETS 6 +#define LL_NTERMINALS 32 +#if LL_ANSI_C +void LL0_spec(void); +#endif +#if LL_ANSI_C +void LLparse(void) +#else +LLparse() +#endif + { + unsigned int s[LL_NTERMINALS+LL_NSETS+2]; + LLnewlevel(s); + LLread(); +LL0_spec(); + LL_SCANDONE(EOFILE); + LLoldlevel(s); +} +static char LLsets[] = { +'\204','\343','\1','\0', +'\234','\4','\176','\354', +'\0','\4','\6','\0', +'\234','\0','\60','\350', +'\10','\0','\0','\340', +'\124','\0','\0','\0', +0 }; +#define LLindex (LL_index+1) +static short LL_index[] = {0,0, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +30, +31, +23, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +25, +24, +-1, +-1, +-1, +29, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +27, +-1, +28, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +26, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13, +14, +15, +16, +17, +18, +19, +20, +21, +22, +0 }; +#define LL_NEWMESS +/* + * Some grammar independent code. + * This file is copied into Lpars.c. + */ + +#ifndef lint +static char *rcsid = "$Id$"; +#endif + +unsigned int LLtcnt[LL_NTERMINALS]; +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); +#else +#define LL_VOIDCST +#endif +#ifdef LL_USERHOOK +#if LL_ANSI_C +static int LLdoskip(int); +static int LLuserhook(int, int*); +#else +static int LLdoskip(); +static int LLuserhook(); +#endif +#endif + +#ifndef LL_FASTER +#if LL_ANSI_C +void LLscan(int t) +#else +LLscan(t) + int t; +#endif +{ + /* + * 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; + } + /* + * If we come here, an error has been detected + */ + LLerror(t); +} +#endif + +#if LL_ANSI_C +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); + } + /* NOTREACHED */ +} + +#if LL_ANSI_C +void LLerror(int t) +#else +LLerror(t) + int t; +#endif +{ + register int i; + + if (t == EOFILE && LLsymb <= 0) return; +#ifdef LL_NEWMESS + if (t == EOFILE) { +#ifdef LL_USERHOOK + static int lst[] = { EOFILE, 0 }; + LL_VOIDCST LLuserhook(EOFILE, lst); +#endif /* LL_USERHOOK */ + if (LLsymb != EOFILE && LLsymb > 0) { + LLmessage(-1); + while ((LLsymb = LL_LEXI()) > 0 && LLsymb != EOFILE) + /* nothing */ ; + } + 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(); + } + i = LLindex[t]; + LLtcnt[i]++; +#ifdef LL_USERHOOK + LL_VOIDCST LLdoskip(t); +#else + LL_VOIDCST LLskip(); +#endif + LLtcnt[i]--; + 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 +void LLsafeerror(int t) +#else +LLsafeerror(t) + int t; +#endif +{ + if (t == EOFILE && LLsymb <= 0) return; +#ifdef LL_NEWMESS + if (t == EOFILE) { +#ifdef LL_USERHOOK + static int lst[] = { EOFILE, 0 }; + LL_VOIDCST LLuserhook(EOFILE, lst); +#endif /* LL_USERHOOK */ + if (LLsymb != EOFILE && LLsymb > 0) { + LLmessage(-1); + while ((LLsymb = LL_LEXI()) > 0 && LLsymb != EOFILE) + /* nothing */ ; + } + return; + } +#endif +#if LL_NON_CORR + if ((!nc_done) && (LLsymb > 0) && (LLsymb != EOFILE)) { + LLmessage(0); + LLnc_recover(); + nc_done = 1; + LLsymb = EOFILE; + } + /* 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); +} + +#ifndef LLNOFIRSTS +#if LL_ANSI_C +int LLfirst(int x, int d) { +#else +int LLfirst(x, d) { +#endif + register int i; + + return (i = LLindex[x]) >= 0 && + (LLsets[d + (i >> 3)] & (1 << (i & 07))); +} +#endif + +#if LL_ANSI_C +int LLnext(int n) +#else +int LLnext(n) + int n; +#endif +{ + /* returns: 0 if the current symbol is'nt skipped, and it + is'nt a member of "n", + 1 if we have a new symbol, but it is'nt a member, + 2 if the current symbol is a member, + and 3 if we have a new symbol and it is a member. + So, the low order bit indicates wether we have a new symbol, + and the next bit indicates wether it is a member of "n". + */ + + int retval = 0; + + if (LLskip()) retval = 1; + if (n <= 0 && LLsets[(LLcsymb >> 3) - n] & (1 << (LLcsymb & 07))) { + retval |= 2; + } + else if (n > 0 && LLcsymb == LLindex[n]) retval |= 2; + return retval; +} + +#if LL_ANSI_C +int LLskip(void) { +#else +int LLskip() { +#endif + /* returns 0 if the current symbol is'nt skipped, and + 1 if it is, t.i., we have a new symbol + */ +#ifdef LL_USERHOOK + return LLdoskip(0); +} + +#if LL_ANSI_C +extern void LL_USERHOOK(int, int *); +static int LLuserhook(int e, int *list) +#else +static int LLuserhook(e, list) + int e; + int *list; +#endif +{ + int old = LLsymb; + LL_USERHOOK(e, list); + LLread(); + return LLsymb != old; +} + +#if LL_ANSI_C +static void LLmklist(register int *list) +#else +static LLmklist(list) + register int *list; +#endif +{ + char Xset[LL_SSIZE]; + register char *p; + register int i; + + for (p = &Xset[0]; p < &Xset[LL_SSIZE]; ) *p++ = 0; + for (i = 0; i < LL_NTERMINALS; i++) { + if (LLtcnt[i] != 0) Xset[i >> 3] |= (1 << (i & 07)); + } + for (i = LL_NSETS - 1; i >= 0; i--) if (LLscnt[i] != 0) { + register char *q = &LLsets[LL_SSIZE * i]; + + p = &Xset[0]; + while (p < &Xset[LL_SSIZE]) *p++ |= *q++; + } + for (i = 0; i < LL_NTERMINALS; i++) { + if (Xset[i >> 3] & (1 << (i & 07))) { + *list++ = LLtok[i]; + } + } + *list = 0; +} + +#if LL_ANSI_C +static int LLdoskip(int e) +#else +static int LLdoskip(e) + int e; +#endif +{ + int LLx; + int list[LL_NTERMINALS+1]; +#endif /* LL_USERHOOK */ + register int i; + int retval; + int LLi, LLb; + + retval = 0; +#ifdef LL_USERHOOK + LLmklist(list); + LLx = LLuserhook(e, list); + if (LLx) retval = 1; +#endif /* LL_USERHOOK */ + for (;;) { + if (LLtcnt[LLcsymb] != 0) { +#ifdef LL_USERHOOK + if (!e || !LLx || LLcsymb == LLindex[e]) +#endif + return retval; + } + LLi = LLcsymb >> 3; + LLb = 1 << (LLcsymb & 07); + for (i = LL_NSETS - 1; i >= 0; i--) { + if (LLscnt[i] != 0) { + if (LLsets[LL_SSIZE*i+LLi] & LLb) { +#ifdef LL_USERHOOK + if (!e || !LLx || LLcsymb == LLindex[e]) +#endif + return retval; + } + } + } +#ifdef LL_USERHOOK + if (LLx) { + LLx = LLuserhook(e, list); + 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(); + } + /* NOTREACHED */ +} + +#if LL_ANSI_C +void LLnewlevel(unsigned int *LLsinfo) { +#else +LLnewlevel(LLsinfo) unsigned int *LLsinfo; { +#endif + register int i; + + if (LLlevel++) { + LLsinfo[LL_NSETS+LL_NTERMINALS] = (unsigned) LLsymb; + LLsinfo[LL_NSETS+LL_NTERMINALS+1] = (unsigned) LLcsymb; + for (i = LL_NTERMINALS - 1; i >= 0; i--) { + LLsinfo[i] = LLtcnt[i]; + LLtcnt[i] = 0; + } + for (i = LL_NSETS - 1; i >= 0; i--) { + LLsinfo[LL_NTERMINALS+i] = LLscnt[i]; + LLscnt[i] = 0; + } + } + LLtincr(0); +} + +#if LL_ANSI_C +void LLoldlevel(unsigned int *LLsinfo) { +#else +LLoldlevel(LLsinfo) unsigned int *LLsinfo; { +#endif + register int i; + + LLtdecr(0); +#ifdef LL_DEBUG + for (i = 0; i < LL_NTERMINALS; i++) LL_assert(LLtcnt[i] == 0); + for (i = 0; i < LL_NSETS; i++) LL_assert(LLscnt[i] == 0); +#endif + if (--LLlevel) { + for (i = LL_NSETS - 1; i >= 0; i--) { + LLscnt[i] = LLsinfo[LL_NTERMINALS+i]; + } + for (i = LL_NTERMINALS - 1; i >= 0; i--) { + LLtcnt[i] = LLsinfo[i]; + } + LLsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS]; + LLcsymb = (int) LLsinfo[LL_NSETS+LL_NTERMINALS+1]; + } +} diff --git a/util/LLgen/src/Lpars.h b/util/LLgen/src/Lpars.h new file mode 100644 index 000000000..d7ee15916 --- /dev/null +++ b/util/LLgen/src/Lpars.h @@ -0,0 +1,25 @@ +/* LLgen generated code from source . */ +#define EOFILE 256 +#define LLILLEGAL 257 +#define C_IDENT 258 +#define C_NUMBER 259 +#define C_LITERAL 260 +#define C_EXPR 261 +#define C_PARAMS 262 +#define C_ACTION 263 +#define C_TOKEN 264 +#define C_START 265 +#define C_IF 266 +#define C_WHILE 267 +#define C_PERSISTENT 268 +#define C_FIRST 269 +#define C_LEXICAL 270 +#define C_PREFIX 271 +#define C_ONERROR 272 +#define C_AVOID 273 +#define C_PREFER 274 +#define C_DEFAULT 275 +#define C_SUBSTART 276 +#define C_ERRONEOUS 277 +#define C_ILLEGAL 278 +#define LL_MAXTOKNO 278 diff --git a/util/LLgen/src/tokens.c b/util/LLgen/src/tokens.c new file mode 100644 index 000000000..8fa2b3613 --- /dev/null +++ b/util/LLgen/src/tokens.c @@ -0,0 +1,634 @@ +/* LLgen generated code from source tokens.g */ +#include "Lpars.h" +#define LL_LEXI scanner +#define LLNOFIRSTS +#if __STDC__ || __cplusplus +#define LL_ANSI_C 1 +#endif +#define LL_LEXI scanner +/* $Id$ */ +#ifdef LL_DEBUG +#include +#include +#define LL_assert(x) assert(x) +#else +#define LL_assert(x) /* nothing */ +#endif + +extern int LLsymb; + +#define LL_SAFE(x) /* Nothing */ +#define LL_SSCANDONE(x) if (LLsymb != x) LLsafeerror(x) +#define LL_SCANDONE(x) if (LLsymb != x) LLerror(x) +#define LL_NOSCANDONE(x) LLscan(x) +#ifdef LL_FASTER +#define LLscan(x) if ((LLsymb = LL_LEXI()) != x) LLerror(x) +#endif + +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]++ +#define LLtincr(d) LLtcnt[d]++ + +#if LL_ANSI_C +extern int LL_LEXI(void); +extern void LLread(void); +extern int LLskip(void); +extern int LLnext(int); +extern void LLerror(int); +extern void LLsafeerror(int); +extern void LLnewlevel(unsigned int *); +extern void LLoldlevel(unsigned int *); +#ifndef LL_FASTER +extern void LLscan(int); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(int, int); +#endif +#if LL_NON_CORR +extern void LLnc_recover(void); +#endif +#else /* not LL_ANSI_C */ +extern LLread(); +extern int LLskip(); +extern int LLnext(); +extern LLerror(); +extern LLsafeerror(); +extern LLnewlevel(); +extern LLoldlevel(); +#ifndef LL_FASTER +extern LLscan(); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(); +#endif +#if LL_NON_CORR +extern LLnc_recover(); +#endif +#endif /* not LL_ANSI_C */ + +# line 20 "tokens.g" + +# include "types.h" +# include "io.h" +# include "extern.h" +# include "assert.h" +# include "cclass.h" + +# ifndef NORCSID +static string rcsidc = "$Id$"; +# endif + +/* Here are defined : */ +extern int scanner(); +extern LLmessage(); +extern int input(); +extern unput(); +extern skipcomment(); +# ifdef LINE_DIRECTIVE +STATIC linedirective(); +# endif +STATIC string cpy(); +STATIC string vallookup(); +STATIC copyact(); + +static int nparams; +# line 75 "tokens.g" + + +/* + * Structure for a keyword + */ + +typedef struct keyword { + string w_word; + int w_value; +} t_keyw, *p_keyw; + +/* + * The list of keywords, the most often used keywords come first. + * Linear search is used, as there are not many keywords + */ + +static t_keyw resword[] = { + { "token", C_TOKEN }, + { "avoid", C_AVOID }, + { "prefer", C_PREFER }, + { "persistent", C_PERSISTENT }, + { "default", C_DEFAULT }, + { "if", C_IF }, + { "while", C_WHILE }, + { "first", C_FIRST }, + { "start", C_START }, + { "lexical", C_LEXICAL }, + { "onerror", C_ONERROR }, + { "prefix", C_PREFIX }, +#ifdef NON_CORRECTING + { "substart", C_SUBSTART }, + { "erroneous", C_ERRONEOUS }, + { "illegal", C_ILLEGAL }, +#endif + { 0, 0 } +}; + +static t_token savedtok; /* to save lextoken in case of an insertion */ +# ifdef LINE_DIRECTIVE +static int nostartline; /* = 0 if at the start of a line */ +# endif + +STATIC +copyact(ch1,ch2,flag,level) char ch1,ch2; { + /* + * Copy an action to file f. Opening bracket is ch1, closing bracket + * is ch2. + * If flag & 1, copy opening and closing parameters too. + * If flag & 2, don't allow ','. + */ + static int text_seen = 0; + register FILE *f; + register ch; /* Current char */ + register match; /* used to read strings */ + int saved = linecount; + /* save linecount */ + int sav_strip = strip_grammar; + + f = fact; + if (ch1 == '{' || flag != 1) strip_grammar = 0; + if (!level) { + text_seen = 0; + nparams = 0; /* count comma's */ + putc('\0',f); + fprintf(f,"# line %d \"%s\"\n", linecount,f_input); + } + if (level || (flag & 1)) putc(ch1,f); + for (;;) { + ch = input(); + if (ch == ch2) { + if (!level) { + if (text_seen) nparams++; + } + if (level || (flag & 1)) putc(ch,f); + if (strip_grammar != sav_strip) { + if (ch1 == '{' || flag != 1) putchar(ch); + } + strip_grammar = sav_strip; + return; + } + switch(ch) { + case ')': + case '}': + case ']': + error(linecount,"Parentheses mismatch"); + break; + case '(': + text_seen = 1; + copyact('(',')',flag,level+1); + continue; + case '{': + text_seen = 1; + copyact('{','}',flag,level+1); + continue; + case '[': + text_seen = 1; + copyact('[',']',flag,level+1); + continue; + case '/': + ch = input(); + unput(ch); + if (ch == '*') { + putc('/', f); + skipcomment(1); + continue; + } + ch = '/'; + text_seen = 1; + break; + case ';': + case ',': + if (! level && text_seen) { + text_seen = 0; + nparams++; + if (ch == ',' && (flag & 2)) { + warning(linecount, "Parameters may not be separated with a ','"); + ch = ';'; + } + } + break; + case '\'': + case '"' : + /* + * watch out for brackets in strings, they do not + * count ! + */ + text_seen = 1; + match = ch; + putc(ch,f); + while((ch = input())) { + if (ch == match) break; + if (ch == '\\') { + putc(ch,f); + ch = input(); + } + if (ch == '\n') { + error(linecount,"Newline in string"); + unput(match); + } + putc(ch,f); + } + if (ch == match) break; + /* Fall through */ + case EOF : + if (!level) error(saved,"Action does not terminate"); + strip_grammar = sav_strip; + return; + default: + if (c_class[ch] != ISSPA) text_seen = 1; + } + putc(ch,f); + } +} + +scanner() { + /* + * Lexical analyser, what else + */ + register int ch; /* Current char */ + register char *p = ltext; + int reserved = 0; /* reserved word? */ + char *max = <ext[LTEXTSZ - 1]; + static int nextexpr; + int expect_expr = nextexpr; + long off; + + nextexpr = 0; + if (savedtok.t_tokno) { + /* A token has been inserted. + * Now deliver the last lextoken again + */ + lextoken = savedtok; + savedtok.t_tokno = 0; + return lextoken.t_tokno; + } + for (;;) { + ch = input(); + if (ch == EOF) return ch; +# ifdef LINE_DIRECTIVE + if (ch == '#' && !nostartline) { + linedirective(); + continue; + } +# endif + switch(c_class[ch]) { + case ISACT : + if (ch == '{') { + copyact('{', '}', in_production, 0); + return C_ACTION; + } + assert(ch == '('); + if (expect_expr) { + copyact('(', ')', 1, 0); + return C_EXPR; + } + off = ftell(fact); + copyact('(', ')', in_production != 0 ? 0 : 2, 0); + if (nparams == 0) fseek(fact, off, 0); + lextoken.t_num = nparams; + return C_PARAMS; + case ISLIT : + for (;;) { + ch = input(); + if (ch == '\n' || ch == EOF) { + error(linecount,"Missing '"); + break; + } + if (ch == '\'') break; + if (ch == '\\') { + *p++ = ch; + ch = input(); + } + *p++ = ch; + if (p > max) p--; + } + *p = '\0'; + lextoken.t_string = ltext; + return C_LITERAL; + case ISCOM : + skipcomment(0); + /* Fall through */ + case ISSPA : + continue; + case ISDIG : { + register i = 0; + do { + i = 10 * i + (ch - '0'); + ch= input(); + } while (c_class[ch] == ISDIG); + lextoken.t_num = i; + unput(ch); + return C_NUMBER; } + default: + return ch; + case ISKEY : + reserved = 1; + ch = input(); + /* Fall through */ + case ISLET : + do { + if (reserved && ch >= 'A' && ch <= 'Z') { + ch += 'a' - 'A'; + } + *p++ = ch; + if (p > max) p--; + ch = input(); + } while (c_class[ch] == ISDIG || c_class[ch] == ISLET); + unput(ch); + *p = '\0'; + if (reserved) { /* + * Now search for the keyword + */ + register p_keyw w; + + w = resword; + while (w->w_word) { + if (! strcmp(ltext,w->w_word)) { + /* + * Return token number. + */ + if (w->w_value == C_IF || + w->w_value == C_WHILE) { + nextexpr = 1; + } + return w->w_value; + } + w++; + } + error(linecount,"Illegal reserved word"); + } + lextoken.t_string = ltext; + return C_IDENT; + } + } +} + +static int backupc; /* for unput() */ +static int nonline; /* = 1 if last char read was a newline */ + +input() { + /* + * Low level input routine, used by all other input routines + */ + register c; + + if (c = backupc) { + /* Last char was "unput()". Deliver it again + */ + backupc = 0; + return c; + } + if ((c = getc(finput)) == EOF) { + nonline = 0; + return c; + } +# ifdef LINE_DIRECTIVE + nostartline = 1; +# endif + if (!nonline) { + linecount++; +# ifdef LINE_DIRECTIVE + nostartline = 0; +# endif + nonline = 1; + } + if (c == '\n') nonline = 0; + if (strip_grammar) putchar(c); + return c; +} + +unput(c) { + /* + * "unread" c + */ + backupc = c; +} + +skipcomment(flag) { + /* + * Skip comment. If flag != 0, the comment is inside a fragment + * of C-code, so keep it. + */ + register int ch; + int saved; /* line count on which comment starts */ + + saved = linecount; + if (input() != '*') error(linecount,"Illegal comment"); + if (flag) putc('*', fact); + do { + ch = input(); + if (flag) putc(ch, fact); + while (ch == '*') { + ch = input(); + if (flag) putc(ch, fact); + if (ch == '/') return; + } + } while (ch != EOF); + error(saved,"Comment does not terminate"); +} + +# ifdef LINE_DIRECTIVE +STATIC +linedirective() { + /* + * Read a line directive + */ + register int ch; + register int i; + string s_error = "Illegal line directive"; + string store(); + register string c; + + do { /* + * Skip to next digit + * Do not skip newlines + */ + ch = input(); + } while (ch != '\n' && c_class[ch] != ISDIG); + if (ch == '\n') { + error(linecount,s_error); + return; + } + i = 0; + do { + i = i*10 + (ch - '0'); + ch = input(); + } while (c_class[ch] == ISDIG); + while (ch != '\n' && ch != '"') ch = input(); + if (ch == '"') { + c = ltext; + do { + *c++ = ch = input(); + } while (ch != '"' && ch != '\n'); + if (ch == '\n') { + error(linecount,s_error); + return; + } + *--c = '\0'; + do { + ch = input(); + } while (ch != '\n'); + /* + * Remember the file name + */ + if (strcmp(f_input,ltext)) f_input = store(ltext); + } + linecount = i; +} +# endif + +STATIC string +vallookup(s) { + /* + * Look up the keyword that has token number s + */ + register p_keyw p = resword; + + while (p->w_value) { + if (p->w_value == s) return p->w_word; + p++; + } + return 0; +} + +STATIC string +cpy(s,p,inserted) register string p; { + /* + * Create a piece of error message for token s and put it at p. + * inserted = 0 if the token s was deleted (in which case we have + * attributes), else it was inserted + */ + register string t = 0; + + switch(s) { + case C_IDENT : + if (!inserted) t = lextoken.t_string; + else t = "identifier"; + break; + case C_NUMBER : + t = "number"; + break; + case C_LITERAL : + if (!inserted) { + *p++ = '\''; + t = lextoken.t_string; + break; + } + t = "literal"; + break; + case C_ACTION: + t = "C action"; + break; + case C_PARAMS: + t = "C parameter section"; + break; + case C_EXPR: + t = "C expression"; + break; + case EOFILE : + t = "end-of-file"; + break; + } + if (!t && (t = vallookup(s))) { + *p++ = '%'; + } + if (t) { /* + * We have a string for the token. Copy it + */ + while (*t) *p++ = *t++; + if (s == C_LITERAL && !inserted) { + *p++ = '\''; + } + return p; + } + /* + * The token is a literal + */ + *p++ = '\''; + if (s >= 040 && s <= 0176) *p++ = s; + else { + *p++ = '\\'; + switch(s) { + case '\b' : *p++ = 'b'; break; + case '\f' : *p++ = 'f'; break; + case '\n' : *p++ = 'n'; break; + case '\r' : *p++ = 'r'; break; + case '\t' : *p++ = 't'; break; + default : *p++='0'+((s&0377)>>6); *p++='0'+((s>>3)&07); + *p++='0'+(s&07); + } + } + *p++ = '\''; + return p; +} + +string strcpy(); + +LLmessage(d) { + /* + * d is either 0, in which case the current token has been deleted, + * or non-zero, in which case it represents a token that is inserted + * before the current token + */ + register string s,t; + char buf[128]; + + nerrors++; + s = buf; + if (d < 0) { + strcpy(buf, "end-of-file expected"); + } + else if (d == 0) { +#ifdef LLNONCORR + t = " unexpected"; +#else + t = " deleted"; +#endif + s = cpy(LLsymb,s,0); + do *s++ = *t; while (*t++); + } else { + s = cpy(d,s,1); + t = " inserted in front of "; + do *s++ = *t++; while (*t); + s = cpy(LLsymb,s,0); + *s = '\0'; + } + if (d > 0) { /* + * Save the current token and make up some + * attributes for the inserted token + */ + savedtok = lextoken; + savedtok.t_tokno = LLsymb; + if (d == C_IDENT) lextoken.t_string = "dummy_identifier"; + else if (d == C_LITERAL) lextoken.t_string = "dummy_literal"; + else if (d == C_NUMBER) lextoken.t_num = 1; + } +#ifdef LLNONCORR + else +#endif + error(linecount, "%s", buf); + /* Don't change this line to + * error(linecount, buf). + * The string in "buf" might contain '%' ... + */ +#ifdef LLNONCORR + in_production = 1; + /* To prevent warnings from copyact */ +#endif +} +