Browse Source

Added pregenerated versions of the LLgen source files (to ease
bootstrapping issues).

dtrg 17 years ago
parent
commit
26a9b76507
4 changed files with 2900 additions and 0 deletions
  1. 1415 0
      util/LLgen/src/LLgen.c
  2. 826 0
      util/LLgen/src/Lpars.c
  3. 25 0
      util/LLgen/src/Lpars.h
  4. 634 0
      util/LLgen/src/tokens.c

+ 1415 - 0
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 <assert.h>
+#include <stdio.h>
+#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 <stdlib.h>
+# include <string.h>
+# 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;
+}
+

+ 826 - 0
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 <assert.h>
+#include <stdio.h>
+#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];
+	}
+}

+ 25 - 0
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

+ 634 - 0
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 <assert.h>
+#include <stdio.h>
+#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 = &ltext[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
+}
+