allow for multiple parsers within one program

This commit is contained in:
ceriel 1990-01-29 13:45:42 +00:00
parent 218b982231
commit da48891d6e
7 changed files with 101 additions and 32 deletions

View file

@ -140,6 +140,21 @@ def { register string p; }
else error(linecount,"Duplicate %%lexical"); else error(linecount,"Duplicate %%lexical");
} }
';' ';'
| C_PREFIX C_IDENT
/*
* Prefix of external names (default: LL)
*/
{ if (!prefix) {
prefix = store(lextoken.t_string);
if (strlen(prefix) > 6) {
error(linecount,
"%%prefix too long");
prefix[6] = 0;
}
}
else error(linecount,"Duplicate %%prefix");
}
';'
| C_ONERROR C_IDENT | C_ONERROR C_IDENT
{ if (! onerror) { { if (! onerror) {
onerror = store(lextoken.t_string); onerror = store(lextoken.t_string);
@ -230,7 +245,7 @@ productions(p_gram *p;)
{ if (n_alts >= max_alts-2) { { if (n_alts >= max_alts-2) {
alt_table = (p_gram ) ralloc( alt_table = (p_gram ) ralloc(
(p_mem) alt_table, (p_mem) alt_table,
(max_alts+=ALTINCR)*sizeof(t_gram)); (unsigned)(max_alts+=ALTINCR)*sizeof(t_gram));
} }
if (t & DEF) { if (t & DEF) {
if (haddefault) { if (haddefault) {
@ -316,7 +331,7 @@ simpleproduction(p_gram *p; register int *conflres;)
{ if (n_rules >= max_rules-2) { { if (n_rules >= max_rules-2) {
rule_table = (p_gram) ralloc( rule_table = (p_gram) ralloc(
(p_mem) rule_table, (p_mem) rule_table,
(max_rules+=RULEINCR)*sizeof(t_gram)); (unsigned)(max_rules+=RULEINCR)*sizeof(t_gram));
} }
kind = FIXED; kind = FIXED;
cnt = 0; cnt = 0;
@ -344,7 +359,7 @@ simpleproduction(p_gram *p; register int *conflres;)
if (n_rules >= max_rules-2) { if (n_rules >= max_rules-2) {
rule_table = (p_gram) ralloc( rule_table = (p_gram) ralloc(
(p_mem) rule_table, (p_mem) rule_table,
(max_rules+=RULEINCR)*sizeof(t_gram)); (unsigned)(max_rules+=RULEINCR)*sizeof(t_gram));
} }
} }
elem = *--(q->t_rule); elem = *--(q->t_rule);

View file

@ -55,6 +55,7 @@ extern string e_noopen; /* Error message string used often */
extern int verbose; /* Level of verbosity */ extern int verbose; /* Level of verbosity */
extern int wflag; /* warnings? */ extern int wflag; /* warnings? */
extern string lexical; /* name of lexical analyser */ extern string lexical; /* name of lexical analyser */
extern string prefix; /* prefix of externals */
extern string onerror; /* name of user error handler */ extern string onerror; /* name of user error handler */
extern int ntneeded; /* ntneeded = 1 if nonterminals are included extern int ntneeded; /* ntneeded = 1 if nonterminals are included
* in the sets. * in the sets.

View file

@ -73,6 +73,8 @@ STATIC genincrdecr();
STATIC add_cases(); STATIC add_cases();
STATIC int analyze_switch(); STATIC int analyze_switch();
STATIC out_list(); STATIC out_list();
STATIC genextname();
STATIC correct_prefix();
# define NOPOP -20000 # define NOPOP -20000
@ -90,8 +92,8 @@ doclose(f)
STATIC int * STATIC int *
mk_tokenlist() mk_tokenlist()
{ {
register int *p = (int *)alloc(ntokens * sizeof(int)) + ntokens;
register int i = ntokens; register int i = ntokens;
register int *p = (int *)alloc((unsigned)(i * sizeof(int))) + i;
while (i--) *--p = -1; while (i--) *--p = -1;
@ -111,6 +113,7 @@ gencode(argc) {
/* Open temporary */ /* Open temporary */
f_input = p->f_name; f_input = p->f_name;
opentemp(f_input); opentemp(f_input);
correct_prefix();
/* generate code ... */ /* generate code ... */
copyfile(incl_file); copyfile(incl_file);
generate(p); generate(p);
@ -147,7 +150,7 @@ geninclude() {
} }
} }
doclose(fpars); doclose(fpars);
install(HFILE, "."); install(f_include, ".");
} }
STATIC STATIC
@ -163,6 +166,7 @@ genrecovery() {
opentemp((string) 0); opentemp((string) 0);
f = fpars; f = fpars;
correct_prefix();
copyfile(incl_file); copyfile(incl_file);
if (!firsts) fputs("#define LLNOFIRSTS\n", f); if (!firsts) fputs("#define LLNOFIRSTS\n", f);
for (st = start; st; st = st->ff_next) { for (st = start; st; st = st->ff_next) {
@ -190,9 +194,8 @@ genrecovery() {
if (g_gettype(p->n_rule) == ALTERNATION) { if (g_gettype(p->n_rule) == ALTERNATION) {
genpush(findindex(p->n_contains)); genpush(findindex(p->n_contains));
} }
fprintf(f, "\tL%d_%s();\n", genextname(st->ff_nont, p->n_name, f);
st->ff_nont, fputs("();\n", f);
p->n_name);
if (getntout(p) == NOSCANDONE) { if (getntout(p) == NOSCANDONE) {
fputs("\tLL_NOSCANDONE(EOFILE);\n",f); fputs("\tLL_NOSCANDONE(EOFILE);\n",f);
} }
@ -224,7 +227,7 @@ genrecovery() {
fputs("#define LL_NEWMESS\n", f); fputs("#define LL_NEWMESS\n", f);
copyfile(rec_file); copyfile(rec_file);
doclose(f); doclose(f);
install(RFILE, "."); install(f_rec, ".");
} }
STATIC STATIC
@ -257,12 +260,13 @@ generate(f) p_file f; {
getntparams(p) == 0) { getntparams(p) == 0) {
continue; continue;
} }
fprintf(fpars,"L%d_%s (\n",s->o_index,p->n_name); genextname(s->o_index, p->n_name, fpars);
if (p->n_flags & PARAMS) { if (p->n_flags & PARAMS) {
fputs("(\n", fpars);
controlline(); controlline();
getparams(); getparams();
} }
else fputs(") {\n", fpars); else fputs("() {\n", fpars);
if (p->n_flags & LOCALS) getaction(1); if (p->n_flags & LOCALS) getaction(1);
i = getntsafe(p); i = getntsafe(p);
mustpop = NOPOP; mustpop = NOPOP;
@ -491,12 +495,14 @@ rulecode(p,safety,mustscan,mustpop) register p_gram p; {
getntsafe(n) <= SAFESCANDONE)) { getntsafe(n) <= SAFESCANDONE)) {
genpop(findindex(n->n_contains)); genpop(findindex(n->n_contains));
} }
fprintf(f,"L%d_%s(\n",g_getcont(p), n->n_name); genextname(g_getcont(p), n->n_name, f);
if (g_getnpar(p)) { if (g_getnpar(p)) {
fputs("(\n", f);
controlline(); controlline();
getaction(0); getaction(0);
fputs(");\n",f);
} }
fputs(");\n",f); else fputs("();\n", f);
safety = getntout(n); safety = getntout(n);
break; } break; }
case TERM : case TERM :
@ -604,8 +610,7 @@ alternation(pp, safety, mustscan, mustpop, lb)
compacted = analyze_switch(tokenlist); compacted = analyze_switch(tokenlist);
if (compacted) { if (compacted) {
fputs("{", f); fputs("{", f);
out_list(tokenlist, listcount, casecnt); out_list(tokenlist, listcount++, casecnt);
fprintf(f, "switch(LL%d_tklist[LLcsymb]) {\n", listcount++);
} }
else fputs("switch(LLcsymb) {\n", f); else fputs("switch(LLcsymb) {\n", f);
casecnt = 0; casecnt = 0;
@ -811,7 +816,6 @@ codeforterm(q,safety,toplevel) register p_term q; {
register int rep_kind = r_getkind(q); register int rep_kind = r_getkind(q);
int term_is_persistent = (q->t_flags & PERSISTENT); int term_is_persistent = (q->t_flags & PERSISTENT);
int ispushed = NOPOP; int ispushed = NOPOP;
int sw = SAFE;
if (!(toplevel > 0 && if (!(toplevel > 0 &&
(safety == 0 || (!onerror && safety <= SAFESCANDONE)) && (safety == 0 || (!onerror && safety <= SAFESCANDONE)) &&
@ -858,7 +862,7 @@ codeforterm(q,safety,toplevel) register p_term q; {
ispushed = NOPOP; ispushed = NOPOP;
} }
if (rep_kind == STAR || rep_kind == OPT) { if (rep_kind == STAR || rep_kind == OPT) {
sw = genswhead(q, rep_kind, rep_count, safety, ispushed); genswhead(q, rep_kind, rep_count, safety, ispushed);
} }
rulecode(q->t_rule, rulecode(q->t_rule,
t_safety(rep_kind,rep_count,term_is_persistent,safety), t_safety(rep_kind,rep_count,term_is_persistent,safety),
@ -872,7 +876,7 @@ codeforterm(q,safety,toplevel) register p_term q; {
if (rep_count) { if (rep_count) {
fputs("if (!LL_i) break;\n", f); fputs("if (!LL_i) break;\n", f);
} }
sw = genswhead(q, rep_kind, rep_count, safety, ispushed); genswhead(q, rep_kind, rep_count, safety, ispushed);
} }
if (rep_kind != OPT && rep_kind != FIXED) fputs("continue;\n", f); if (rep_kind != OPT && rep_kind != FIXED) fputs("continue;\n", f);
if (rep_kind != FIXED) { if (rep_kind != FIXED) {
@ -940,8 +944,7 @@ genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; {
compacted = analyze_switch(tokenlist); compacted = analyze_switch(tokenlist);
fputs("{", f); fputs("{", f);
if (compacted) { if (compacted) {
out_list(tokenlist, listcount, casecnt); out_list(tokenlist, listcount++, casecnt);
fprintf(f, "switch(LL%d_tklist[LLcsymb]) {\n", listcount++);
} }
else fputs("switch(LLcsymb) {\n", f); else fputs("switch(LLcsymb) {\n", f);
casecnt = 0; casecnt = 0;
@ -990,7 +993,6 @@ genswhead(q, rep_kind, rep_count, safety, ispushed) register p_term q; {
genpop(ispushed); genpop(ispushed);
} }
free((p_mem) tokenlist); free((p_mem) tokenlist);
return safeterm;
} }
STATIC STATIC
@ -1132,4 +1134,38 @@ out_list(tokenlist, listno, casecnt)
fprintf(f, "%c%d,", i % 10 == 0 ? '\n': ' ', tokenlist[i]); fprintf(f, "%c%d,", i % 10 == 0 ? '\n': ' ', tokenlist[i]);
} }
fputs(c_arrend, f); fputs(c_arrend, f);
fprintf(f, "switch(LL%d_tklist[LLcsymb]) {\n", listcount);
}
STATIC
genextname(d, s, f)
char *s;
FILE *f;
{
fprintf(f, "%s%d_%s", prefix ? prefix : "LL", d, s);
}
STATIC
correct_prefix()
{
register FILE *f = fpars;
register char *s = prefix;
if (s) {
fprintf(f, "#define LLsymb %ssymb\n", s);
fprintf(f, "#define LLerror %serror\n", s);
fprintf(f, "#ifndef LL_FASTER\n#define LLscan %sscan\n#endif\n", s);
fprintf(f, "#define LLscnt %sscnt\n", s);
fprintf(f, "#define LLtcnt %stcnt\n", s);
fprintf(f, "#define LLcsymb %scsymb\n", s);
fprintf(f, "#define LLread %sread\n", s);
fprintf(f, "#define LLskip %sskip\n", s);
fprintf(f, "#define LLnext %snext\n", s);
fprintf(f, "#define LLfirst %sfirst\n", s);
fprintf(f, "#define LLnewlevel %snewlevel\n", s);
fprintf(f, "#define LLoldlevel %soldlevel\n", s);
fprintf(f, "#define LLlex %slex\n", s);
fprintf(f, "#define LLmessage %smessage\n", s);
}
fprintf(f, "#include \"%s\"\n", f_include);
} }

View file

@ -41,14 +41,17 @@ FILE *fout;
FILE *fpars; FILE *fpars;
FILE *finput; FILE *finput;
FILE *fact; FILE *fact;
string f_pars = PARSERFILE; char f_pars[] = PARSERFILE;
string f_out = OUTFILE; char f_temp[] = ACTFILE;
string f_temp = ACTFILE; char f_out[20];
string f_input; string f_input;
char f_include[20];
char f_rec[20];
string e_noopen = "Cannot open %s"; string e_noopen = "Cannot open %s";
int verbose; int verbose;
int wflag; int wflag;
string lexical; string lexical;
string prefix;
string onerror; string onerror;
int ntneeded; int ntneeded;
int ntprint; int ntprint;

View file

@ -21,17 +21,19 @@
/* FILES */ /* FILES */
# define OUTFILE "LL.output" /* -v option */ # define OUTFILE "%s.output" /* -v option */
# define PARSERFILE "LL.xxx" /* This is what we want */ # define PARSERFILE "xxxXXXXXX" /* This is what we want */
# define ACTFILE "LL.temp" /* temporary file to save actions */ # define ACTFILE "tempXXXXXX" /* temporary file to save actions */
# define HFILE "Lpars.h" /* file for "#define's " */ # define HFILE "%spars.h" /* file for "#define's " */
# define RFILE "Lpars.c" /* Error recovery */ # define RFILE "%spars.c" /* Error recovery */
extern FILE *finput; extern FILE *finput;
extern FILE *fpars; extern FILE *fpars;
extern FILE *fact; extern FILE *fact;
extern FILE *fout; extern FILE *fout;
extern string f_pars; extern char f_pars[];
extern string f_temp; extern char f_temp[];
extern string f_out; extern char f_out[];
extern string f_input; extern string f_input;
extern char f_include[];
extern char f_rec[];

View file

@ -36,6 +36,7 @@ extern fatal();
extern comfatal(); extern comfatal();
extern copyfile(); extern copyfile();
extern install(); extern install();
extern char *mktemp();
# ifndef NDEBUG # ifndef NDEBUG
extern badassertion(); extern badassertion();
# endif not NDEBUG # endif not NDEBUG
@ -129,12 +130,21 @@ main(argc,argv) register string argv[]; {
# ifndef NDEBUG # ifndef NDEBUG
} }
# endif # endif
mktemp(f_temp);
mktemp(f_pars);
if ((fact = fopen(f_temp,"w")) == NULL) { if ((fact = fopen(f_temp,"w")) == NULL) {
fputs("Cannot create temporary\n",stderr); fputs("Cannot create temporary\n",stderr);
exit(1); exit(1);
} }
name_init(); name_init();
readgrammar(argc,argv); readgrammar(argc,argv);
sprintf(f_out, OUTFILE, prefix ? prefix : "LL");
/* for the following two filenames only one L is used; historical
reasons ...
*/
sprintf(f_include, HFILE, prefix ? prefix : "L");
sprintf(f_rec, RFILE, prefix ? prefix : "L");
setinit(ntneeded); setinit(ntneeded);
maxnt = &nonterms[nnonterms]; maxnt = &nonterms[nnonterms];
maxt = &tokens[ntokens]; maxt = &tokens[ntokens];

View file

@ -56,6 +56,7 @@ STATIC string vallookup();
%token C_PERSISTENT ; %token C_PERSISTENT ;
%token C_FIRST ; %token C_FIRST ;
%token C_LEXICAL ; %token C_LEXICAL ;
%token C_PREFIX ;
%token C_ONERROR ; %token C_ONERROR ;
%token C_AVOID ; %token C_AVOID ;
%token C_PREFER ; %token C_PREFER ;
@ -91,6 +92,7 @@ static t_keyw resword[] = {
{ "start", C_START }, { "start", C_START },
{ "lexical", C_LEXICAL }, { "lexical", C_LEXICAL },
{ "onerror", C_ONERROR }, { "onerror", C_ONERROR },
{ "prefix", C_PREFIX },
{ 0, 0 } { 0, 0 }
}; };