From: ceriel Date: Tue, 26 Nov 1991 15:38:41 +0000 (+0000) Subject: produce ANSI C under -a option X-Git-Tag: release-5-5~594 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=35260bae58af2915d52479c3ac2846bc7ebdedb8;p=ack.git produce ANSI C under -a option --- diff --git a/util/LLgen/LLgen.1 b/util/LLgen/LLgen.1 index 3a44d304c..8f9e94d50 100644 --- a/util/LLgen/LLgen.1 +++ b/util/LLgen/LLgen.1 @@ -4,7 +4,7 @@ .SH NAME LLgen, an extended LL(1) parser generator .SH SYNOPSIS -LLgen [ \-vxw ] [ \-j[\fInum\fP] ] [ \-l\fInum\fP ] [ \-h\fInum\fP ] file ... +LLgen [ \-vxwa ] [ \-j[\fInum\fP] ] [ \-l\fInum\fP ] [ \-h\fInum\fP ] file ... .SH DESCRIPTION \fILLgen\fP converts a context-free grammar into a set of @@ -76,6 +76,8 @@ symbols and these extended sets are also included in the file. .IP \fB\-w\fP no warnings are given. +.IP \fB\-a\fP +Produce ANSI C function headers and prototypes. .IP \fB\-j\fP[\fInum\fP] when this flag is given, \fILLgen\fP will generate dense switches, so that the compiler can generate a jump table for it. This will only be diff --git a/util/LLgen/lib/incl b/util/LLgen/lib/incl index 793bc1dae..636026075 100644 --- a/util/LLgen/lib/incl +++ b/util/LLgen/lib/incl @@ -25,3 +25,32 @@ extern int LLcsymb; #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 LLnewlevel(unsigned int *); +extern void LLoldlevel(unsigned int *); +#ifndef LL_FASTER +extern void LLscan(int); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(int, int); +#endif +#else /* not LL_ANSI_C */ +extern LLread(); +extern int LLskip(); +extern int LLnext(); +extern LLerror(); +extern LLnewlevel(); +extern LLoldlevel(); +#ifndef LL_FASTER +extern LLscan(); +#endif +#ifndef LLNOFIRSTS +extern int LLfirst(); +#endif +#endif /* not LL_ANSI_C */ diff --git a/util/LLgen/lib/rec b/util/LLgen/lib/rec index 109c99f53..5a23082c1 100644 --- a/util/LLgen/lib/rec +++ b/util/LLgen/lib/rec @@ -3,37 +3,35 @@ * This file is copied into Lpars.c. */ -# ifndef lint +#ifndef lint static char *rcsid = "$Header$"; -# endif +#endif unsigned int LLtcnt[LL_NTERMINALS]; unsigned int LLscnt[LL_NSETS]; int LLcsymb, LLsymb; static int LLlevel; -/* In this file are defined: */ -extern LLread(); -extern int LLskip(); -extern int LLnext(); -#ifndef LL_FASTER -extern LLscan(); +#if LL_ANSI_C +void LLmessage(int); #endif -extern LLerror(); -# ifndef LLNOFIRSTS -extern int LLfirst(); -# endif -extern LLnewlevel(); -extern LLoldlevel(); - #ifdef LL_USERHOOK +#if LL_ANSI_C +static void LLdoskip(int); +static int LLuserhook(int, int*); +#else static 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 @@ -48,7 +46,11 @@ LLscan(t) } #endif +#if LL_ANSI_C +void LLread(void) { +#else LLread() { +#endif for (;;) { if ((LLcsymb = LLindex[(LLsymb = LL_LEXI())]) >= 0) return; LLmessage(0); @@ -56,8 +58,12 @@ LLread() { /* NOTREACHED */ } +#if LL_ANSI_C +void LLerror(int t) +#else LLerror(t) int t; +#endif { register int i; @@ -67,7 +73,7 @@ LLerror(t) #ifdef LL_USERHOOK static int lst[] = { EOFILE, 0 }; if (LLuserhook(EOFILE, lst)) /* nothing */; -#endif LL_USERHOOK +#endif /* LL_USERHOOK */ if (LLsymb != EOFILE && LLsymb > 0) { LLmessage(-1); while ((LLsymb = LL_LEXI()) > 0 && LLsymb != EOFILE) @@ -91,17 +97,25 @@ LLerror(t) if (LLsymb != t) LLmessage(t); } -# ifndef LLNOFIRSTS -LLfirst(x, d) { +#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 +#endif -LLnext(n) +#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", @@ -122,7 +136,11 @@ LLnext(n) return retval; } -LLskip() { +#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 */ @@ -130,20 +148,27 @@ LLskip() { return LLdoskip(0); } -static int -LLuserhook(exp, list) - int exp; +#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(exp, list); + LL_USERHOOK(e, list); LLread(); return LLsymb != old; } -static -LLmklist(list) +#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; @@ -167,13 +192,16 @@ LLmklist(list) *list = 0; } -static -LLdoskip(exp) - int exp; +#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 +#endif /* LL_USERHOOK */ register int i; int retval; int LLi, LLb; @@ -181,13 +209,13 @@ LLdoskip(exp) retval = 0; #ifdef LL_USERHOOK LLmklist(list); - LLx = LLuserhook(exp, list); + LLx = LLuserhook(e, list); if (LLx) retval = 1; -#endif LL_USERHOOK +#endif /* LL_USERHOOK */ for (;;) { if (LLtcnt[LLcsymb] != 0) { #ifdef LL_USERHOOK - if (!exp || !LLx || LLcsymb == LLindex[exp]) + if (!e || !LLx || LLcsymb == LLindex[e]) #endif return retval; } @@ -197,7 +225,7 @@ LLdoskip(exp) if (LLscnt[i] != 0) { if (LLsets[LL_SSIZE*i+LLi] & LLb) { #ifdef LL_USERHOOK - if (!exp || !LLx || LLcsymb == LLindex[exp]) + if (!e || !LLx || LLcsymb == LLindex[e]) #endif return retval; } @@ -205,10 +233,10 @@ LLdoskip(exp) } #ifdef LL_USERHOOK if (LLx) { - LLx = LLuserhook(exp, list); + LLx = LLuserhook(e, list); continue; } -#endif LL_USERHOOK +#endif /* LL_USERHOOK */ LLmessage(0); retval = 1; LLread(); @@ -216,7 +244,11 @@ LLdoskip(exp) /* NOTREACHED */ } +#if LL_ANSI_C +void LLnewlevel(unsigned int *LLsinfo) { +#else LLnewlevel(LLsinfo) unsigned int *LLsinfo; { +#endif register int i; if (LLlevel++) { @@ -234,16 +266,18 @@ LLnewlevel(LLsinfo) unsigned int *LLsinfo; { LLtincr(0); } -LLoldlevel(LLsinfo) - unsigned int *LLsinfo; -{ +#if LL_ANSI_C +void LLoldlevel(unsigned int *LLsinfo) { +#else +LLoldlevel(LLsinfo) unsigned int *LLsinfo; { +#endif register int i; LLtdecr(0); -# ifdef LL_DEBUG +#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 +#endif if (--LLlevel) { for (i = LL_NSETS - 1; i >= 0; i--) { LLscnt[i] = LLsinfo[LL_NTERMINALS+i]; diff --git a/util/LLgen/src/LLgen.g b/util/LLgen/src/LLgen.g index 07c392aa4..3ab9807d2 100644 --- a/util/LLgen/src/LLgen.g +++ b/util/LLgen/src/LLgen.g @@ -29,6 +29,7 @@ static string rcsid = "$Header$"; p_mem alloc(), ralloc(); string store(); p_gram search(); +long ftell(); static int nparams; /* parameter count for nonterminals */ static int acount; /* count #of global actions */ @@ -211,6 +212,7 @@ rule { register p_nont p; p->n_count = acount; acount = 0; p->n_lineno = linecount; + p->n_off = ftell(fact); } [ params { p->n_flags |= PARAMS; if (nparams > 15) { diff --git a/util/LLgen/src/compute.c b/util/LLgen/src/compute.c index 272dfcbdd..cde5d7794 100644 --- a/util/LLgen/src/compute.c +++ b/util/LLgen/src/compute.c @@ -131,19 +131,48 @@ do_compute() { STATIC createsets() { /* - * Allocate space for the sets + * Allocate space for the sets. Also determine which files use + * which nonterminals, and determine which nonterminals can be + * made static. */ register p_nont p; + register p_file f; + register p_start st; + register int i; + int n = NINTS(NBYTES(nnonterms)); + p_mem alloc(); - for (p = nonterms; p < maxnt; p++) { - p->n_first = get_set(); - p->n_follow = get_set(); - walk(p->n_rule); + for (f = files; f < maxfiles; f++) { + register p_set s; + f->f_used = s = (p_set) alloc((unsigned)n*sizeof(*(f->f_used))); + for (i = n; i; i--) *s++ = 0; + for (i = f->f_nonterminals; i != -1; i = p->n_next) { + p = &nonterms[i]; + p->n_flags |= GENSTATIC; + p->n_first = get_set(); + p->n_follow = get_set(); + walk(f->f_used, p->n_rule); + } + } + for (f = files; f < maxfiles; f++) { + for (i = f->f_nonterminals; i != -1; i = p->n_next) { + register p_file f2; + + p = &nonterms[i]; + for (f2 = files; f2 < maxfiles; f2++) { + if (f2 != f && IN(f2->f_used, i)) { + p->n_flags &= ~GENSTATIC; + } + } + } + } + for (st = start; st; st = st->ff_next) { + nonterms[st->ff_nont].n_flags &= ~GENSTATIC; } } STATIC -walk(p) register p_gram p; { +walk(u, p) p_set u; register p_gram p; { /* * Walk through the grammar rule p, allocating sets */ @@ -156,7 +185,7 @@ walk(p) register p_gram p; { q = g_getterm(p); q->t_first = get_set(); q->t_follow = get_set(); - walk(q->t_rule); + walk(u, q->t_rule); break; } case ALTERNATION : { register p_link l; @@ -164,7 +193,12 @@ walk(p) register p_gram p; { l = g_getlink(p); l->l_symbs = get_set(); l->l_others = get_set(); - walk(l->l_rule); + walk(u, l->l_rule); + break; } + case NONTERM : { + register int i = g_getcont(p); + + PUTIN(u, i); break; } case EORULE : return; diff --git a/util/LLgen/src/extern.h b/util/LLgen/src/extern.h index 8bcf9c695..13aed5ba9 100644 --- a/util/LLgen/src/extern.h +++ b/util/LLgen/src/extern.h @@ -75,3 +75,4 @@ extern string rec_file, incl_file; extern int low_percentage, high_percentage; extern int min_cases_for_jmptable; extern int jmptable_option; +extern int ansi_c; diff --git a/util/LLgen/src/gencode.c b/util/LLgen/src/gencode.c index 9ed83cc26..c3e6248ea 100644 --- a/util/LLgen/src/gencode.c +++ b/util/LLgen/src/gencode.c @@ -56,6 +56,8 @@ STATIC prset(); STATIC macro(); STATIC controlline(); STATIC getparams(); +STATIC getansiparams(); +STATIC genprototypes(); STATIC gettok(); STATIC rulecode(); STATIC int * dopush(); @@ -113,6 +115,8 @@ gencode(argc) { opentemp(f_input); correct_prefix(); /* generate code ... */ + if (ansi_c) fputs("#define LL_ANSI_C 1\n", fpars); + fprintf(fpars, "#define LL_LEXI %s\n", lexical); copyfile(incl_file); generate(p); getaction(2); @@ -123,6 +127,7 @@ gencode(argc) { } geninclude(); genrecovery(); + fclose(fact); } STATIC @@ -165,8 +170,10 @@ genrecovery() { opentemp((string) 0); f = fpars; correct_prefix(); - copyfile(incl_file); if (!firsts) fputs("#define LLNOFIRSTS\n", f); + if (ansi_c) fputs("#define LL_ANSI_C 1\n", f); + fprintf(f, "#define LL_LEXI %s\n", lexical); + copyfile(incl_file); for (st = start; st; st = st->ff_next) { /* Make sure that every set the parser needs is in the list * before generating a define of the number of them! @@ -178,17 +185,23 @@ genrecovery() { } i = maxptr - setptr; fprintf(f, -"#define LL_LEXI %s\n#define LL_SSIZE %d\n#define LL_NSETS %d\n#define LL_NTERMINALS %d\n", - lexical, +"#define LL_SSIZE %d\n#define LL_NSETS %d\n#define LL_NTERMINALS %d\n", nbytes, i > 0 ? i : 1, ntokens); if (onerror) fprintf(f,"#define LL_USERHOOK %s\n", onerror); /* Now generate the routines that call the startsymbols */ + if (ansi_c) for (st = start; st; st = st->ff_next) { + p = &nonterms[st->ff_nont]; + fputs("void ", f); + genextname(st->ff_nont, p->n_name, f); + fputs("(void);\n", f); + } for (st = start; st; st = st->ff_next) { - fputs(st->ff_name, f); + if (ansi_c) fputs("void ", f); + fprintf(f, "%s(%s)", st->ff_name, ansi_c ? "void" : ""); p = &nonterms[st->ff_nont]; - fputs("() {\n\tunsigned int s[LL_NTERMINALS+LL_NSETS+2];\n\tLLnewlevel(s);\n\tLLread();\n", f); + fputs(" {\n\tunsigned int s[LL_NTERMINALS+LL_NSETS+2];\n\tLLnewlevel(s);\n\tLLread();\n", f); if (g_gettype(p->n_rule) == ALTERNATION) { genpush(findindex(p->n_contains)); } @@ -238,6 +251,7 @@ generate(f) p_file f; { int i; register p_first ff; int mustpop; + int is_first = 1; fprintf(fpars, "#define LL_LEXI %s\n", lexical); listcount = 0; @@ -258,13 +272,18 @@ generate(f) p_file f; { getntparams(p) == 0) { continue; } + if (is_first) genprototypes(f); + is_first = 0; + if (p->n_flags & GENSTATIC) fputs("static ", fpars); + if (ansi_c) fputs("void ", fpars); genextname(s, p->n_name, fpars); if (p->n_flags & PARAMS) { fputs("(\n", fpars); controlline(); - getparams(); + if (ansi_c) getansiparams(1); + else getparams(); } - else fputs("() {\n", fpars); + else fprintf(fpars, "(%s) {\n", ansi_c ? "void" : ""); if (p->n_flags & LOCALS) getaction(1); i = getntsafe(p); mustpop = NOPOP; @@ -380,6 +399,71 @@ getparams() { fprintf(fpars, "%c {\n",add_semi); } +STATIC +genprototypes(f) + register p_file f; +{ + /* + * Generate prototypes for all nonterminals + */ + register int i; + register p_nont p; + long off = ftell(fact); + + for (i = 0; i < nnonterms; i++) { + if (! IN(f->f_used, i)) continue; + p = &nonterms[i]; + if (g_gettype(p->n_rule) == EORULE && + getntparams(p) == 0) { + continue; + } + if (ansi_c || (p->n_flags & GENSTATIC)) { + if (p->n_flags & GENSTATIC) fputs("static ", fpars); + if (ansi_c) fputs("void ", fpars); + genextname(i, p->n_name, fpars); + if (! ansi_c) fputs("();\n", fpars); + else if (p->n_flags & PARAMS) { + fputs("(\n", fpars); + fseek(fact, p->n_off, 0); + controlline(); + getansiparams(0); + fseek(fact, off, 0); + } + else fputs("(void);\n", fpars); + } + } +} + +STATIC +getansiparams(mkdef) { + /* getansiparams is called if a nonterminal has parameters + * and an ANSI C function definition/declaration has to be produced. + * If a definition has to be produced, "mkdef" is set to 1. + */ + register int l; + char add_semi = ' '; + int delayed = 0; + + ltext[0] = '\0'; + while ((l = gettok()) != ENDDECL) { + if (delayed) { + fputc(',', fpars); + delayed = 0; + } + if ((l == ';' || l == ',') && ltext[0] != '\0') { + /* + * The last identifier found before a ';' or a ',' + * must be a parameter + */ + delayed = 1; + ltext[0] = '\0'; + } + else if (l == IDENT) fprintf(fpars, "%s", ltext); + else fputc(l, fpars); + } + fprintf(fpars, ") %c\n", mkdef ? '{' : ';'); +} + STATIC gettok() { /* Read from the action file. */ diff --git a/util/LLgen/src/global.c b/util/LLgen/src/global.c index ac0523625..66f29325a 100644 --- a/util/LLgen/src/global.c +++ b/util/LLgen/src/global.c @@ -66,3 +66,4 @@ string rec_file, incl_file; int low_percentage = 10, high_percentage = 30; int min_cases_for_jmptable = 8; int jmptable_option; +int ansi_c = 0; diff --git a/util/LLgen/src/main.c b/util/LLgen/src/main.c index 584842c42..eb49ccbf5 100644 --- a/util/LLgen/src/main.c +++ b/util/LLgen/src/main.c @@ -100,6 +100,10 @@ main(argc,argv) register string argv[]; { ntneeded = 1; ntprint = 1; continue; + case 'a': + case 'A': + ansi_c = 1; + continue; default: fprintf(stderr,"illegal option : %c\n",*arg); exit(1); diff --git a/util/LLgen/src/types.h b/util/LLgen/src/types.h index 931765f22..69d286bd4 100644 --- a/util/LLgen/src/types.h +++ b/util/LLgen/src/types.h @@ -105,6 +105,7 @@ typedef struct { */ # define getntparams(p) ((p)->n_flags&017) # define setntparams(p,i) {assert(((unsigned)(i))<=017);(p)->n_flags&=~017;(p)->n_flags|=(i);} +# define GENSTATIC 01000 /* set if routine can be made static */ # define RECURSIVE 02000 /* Set if the default rule is recursive */ # define PARAMS 04000 /* tells if a nonterminal has parameters */ # define EMPTY 010000 /* tells if a nonterminal produces empty */ @@ -133,6 +134,7 @@ typedef struct { p_set n_contains; /* pointer to symbols that can be produced */ string n_name; /* name of nonterminal */ int n_next; /* index of next nonterminal */ + long n_off; /* index of parameters in action file */ } t_nont, *p_nont; /* @@ -225,6 +227,7 @@ typedef struct f_file { */ int f_nonterminals; /* list of nonterminals in this file */ int f_terminals; /* list of terminals in this file */ + p_set f_used; /* set of nonterminals used in this file */ } t_file, *p_file; typedef struct info_alloc {