home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
online
/
source
/
c
/
compilers
/
mpw-perl-byacc1.8.1.sit.hqx
/
mpw-perl-byacc1.8.1
/
output.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-20
|
23KB
|
1,367 lines
#include "defs.h"
static int nvectors;
static int nentries;
static short **froms;
static short **tos;
static short *tally;
static short *width;
static short *state_count;
static short *order;
static short *base;
static short *pos;
static int maxtable;
static short *table;
static short *check;
static int lowzero;
static int high;
output()
{
free_itemsets();
free_shifts();
free_reductions();
Cooperate();
output_stored_text();
Cooperate();
output_defines();
Cooperate();
output_rule_data();
Cooperate();
output_yydefred();
Cooperate();
output_actions();
Cooperate();
free_parser();
Cooperate();
output_debug();
Cooperate();
output_stype();
Cooperate();
if (rflag) write_section(tables);
write_section(header);
Cooperate();
if (language == C) {
output_trailing_text();
Cooperate();
}
write_section(body);
Cooperate();
output_semantic_actions();
Cooperate();
write_section(trailer);
Cooperate();
if (language == PERL)
output_trailing_text();
}
static write_num(value)
int value;
{
Cooperate();
switch (language)
{
case PERL:
fprintf(output_file, "%5d,", value);
break;
case C:
fprintf(output_file, "%5d,", value);
break;
}
}
static start_num_array(name, indent, first)
char *name;
int indent, first;
{
Cooperate();
switch (language)
{
case PERL:
fprintf(output_file, "@%s = (%*d,", name, indent+7, first);
break;
case C:
fprintf(output_file, "short %s[] = {%*d,", name, indent, first);
break;
}
}
static start_string_array(name, nl)
char *name;
int nl;
{
Cooperate();
switch (language)
{
case PERL:
fprintf(output_file, "@%s = (%s", name, nl ? "\n" : "");
break;
case C:
fprintf(output_file, "char *%s[] = {%s", name, nl ? "\n": "");
break;
}
}
static end_num_array()
{
Cooperate();
switch (language)
{
case PERL:
fprintf(output_file, "\n);\n");
break;
case C:
fprintf(output_file, "\n};\n");
break;
}
}
static end_string_array(nl)
int nl;
{
Cooperate();
switch (language)
{
case PERL:
fprintf(output_file, "%s);\n", nl ? "\n" : "");
break;
case C:
fprintf(output_file, "%s};\n", nl ? "\n" : "");
break;
}
}
static start_define(file)
FILE *file;
{
Cooperate();
switch (language)
{
case PERL:
fprintf(file, "$");
break;
case C:
fprintf(file, "#define ");
break;
}
}
static end_define(file, value)
FILE* file;
int value;
{
Cooperate();
if (language == PERL)
fprintf(file, "=%d;\n", value);
else
fprintf(file, " %d\n", value);
}
static write_define(name, value)
char* name;
int value;
{
Cooperate();
start_define(code_file);
fprintf(code_file, "%s", name);
end_define(code_file, value);
}
static write_null()
{
Cooperate();
switch (language)
{
case PERL:
fprintf(output_file, "'',");
break;
case C:
fprintf(output_file, "0,");
break;
}
}
output_rule_data()
{
register int i;
register int j;
start_num_array("yylhs", 42, symbol_value[start_symbol]);
j = 10;
for (i = 3; i < nrules; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
++j;
write_num(symbol_value[rlhs[i]]);
}
if (!rflag) outline += 2;
end_num_array();
start_num_array("yylen", 42, 2);
j = 10;
for (i = 3; i < nrules; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
j++;
write_num(rrhs[i + 1] - rrhs[i] - 1);
}
if (!rflag) outline += 2;
end_num_array();
}
output_yydefred()
{
register int i, j;
start_num_array("yydefred", 39, (defred[0] ? defred[0] - 2 : 0));
j = 10;
for (i = 1; i < nstates; i++)
{
if (j < 10)
++j;
else
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
write_num(defred[i] ? defred[i] - 2 : 0);
}
if (!rflag) outline += 2;
end_num_array();
}
output_actions()
{
Cooperate();
nvectors = 2*nstates + nvars;
froms = NEW2(nvectors, short *);
tos = NEW2(nvectors, short *);
tally = NEW2(nvectors, short);
width = NEW2(nvectors, short);
token_actions();
FREE(lookaheads);
FREE(LA);
FREE(LAruleno);
FREE(accessing_symbol);
goto_actions();
FREE(goto_map + ntokens);
FREE(from_state);
FREE(to_state);
sort_actions();
pack_table();
output_base();
output_table();
output_check();
}
token_actions()
{
register int i, j;
register int shiftcount, reducecount;
register int max, min;
register short *actionrow, *r, *s;
register action *p;
actionrow = NEW2(2*ntokens, short);
for (i = 0; i < nstates; ++i)
{
if (parser[i])
{
Cooperate();
for (j = 0; j < 2*ntokens; ++j)
actionrow[j] = 0;
shiftcount = 0;
reducecount = 0;
for (p = parser[i]; p; p = p->next)
{
if (p->suppressed == 0)
{
if (p->action_code == SHIFT)
{
++shiftcount;
actionrow[p->symbol] = p->number;
}
else if (p->action_code == REDUCE && p->number != defred[i])
{
++reducecount;
actionrow[p->symbol + ntokens] = p->number;
}
}
}
Cooperate();
tally[i] = shiftcount;
tally[nstates+i] = reducecount;
width[i] = 0;
width[nstates+i] = 0;
if (shiftcount > 0)
{
froms[i] = r = NEW2(shiftcount, short);
tos[i] = s = NEW2(shiftcount, short);
min = MAXSHORT;
max = 0;
for (j = 0; j < ntokens; ++j)
{
if (actionrow[j])
{
if (min > symbol_value[j])
min = symbol_value[j];
if (max < symbol_value[j])
max = symbol_value[j];
*r++ = symbol_value[j];
*s++ = actionrow[j];
}
}
width[i] = max - min + 1;
}
if (reducecount > 0)
{
froms[nstates+i] = r = NEW2(reducecount, short);
tos[nstates+i] = s = NEW2(reducecount, short);
min = MAXSHORT;
max = 0;
for (j = 0; j < ntokens; ++j)
{
if (actionrow[ntokens+j])
{
if (min > symbol_value[j])
min = symbol_value[j];
if (max < symbol_value[j])
max = symbol_value[j];
*r++ = symbol_value[j];
*s++ = actionrow[ntokens+j] - 2;
}
}
width[nstates+i] = max - min + 1;
}
}
}
FREE(actionrow);
}
goto_actions()
{
register int i, j, k;
Cooperate();
state_count = NEW2(nstates, short);
k = default_goto(start_symbol + 1);
start_num_array("yydgoto", 40, k);
save_column(start_symbol + 1, k);
j = 10;
for (i = start_symbol + 2; i < nsyms; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
++j;
k = default_goto(i);
write_num(k);
save_column(i, k);
}
if (!rflag) outline += 2;
end_num_array();
FREE(state_count);
}
int
default_goto(symbol)
int symbol;
{
register int i;
register int m;
register int n;
register int default_state;
register int max;
Cooperate();
m = goto_map[symbol];
n = goto_map[symbol + 1];
if (m == n) return (0);
for (i = 0; i < nstates; i++)
state_count[i] = 0;
for (i = m; i < n; i++)
state_count[to_state[i]]++;
max = 0;
default_state = 0;
for (i = 0; i < nstates; i++)
{
if (state_count[i] > max)
{
max = state_count[i];
default_state = i;
}
}
return (default_state);
}
save_column(symbol, default_state)
int symbol;
int default_state;
{
register int i;
register int m;
register int n;
register short *sp;
register short *sp1;
register short *sp2;
register int count;
register int symno;
Cooperate();
m = goto_map[symbol];
n = goto_map[symbol + 1];
count = 0;
for (i = m; i < n; i++)
{
if (to_state[i] != default_state)
++count;
}
if (count == 0) return;
symno = symbol_value[symbol] + 2*nstates;
froms[symno] = sp1 = sp = NEW2(count, short);
tos[symno] = sp2 = NEW2(count, short);
for (i = m; i < n; i++)
{
if (to_state[i] != default_state)
{
*sp1++ = from_state[i];
*sp2++ = to_state[i];
}
}
tally[symno] = count;
width[symno] = sp1[-1] - sp[0] + 1;
}
sort_actions()
{
register int i;
register int j;
register int k;
register int t;
register int w;
Cooperate();
order = NEW2(nvectors, short);
nentries = 0;
for (i = 0; i < nvectors; i++)
{
if (tally[i] > 0)
{
t = tally[i];
w = width[i];
j = nentries - 1;
while (j >= 0 && (width[order[j]] < w))
j--;
while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
j--;
for (k = nentries - 1; k > j; k--)
order[k + 1] = order[k];
order[j + 1] = i;
nentries++;
}
}
}
pack_table()
{
register int i;
register int place;
register int state;
Cooperate();
base = NEW2(nvectors, short);
pos = NEW2(nentries, short);
maxtable = 1000;
table = NEW2(maxtable, short);
check = NEW2(maxtable, short);
lowzero = 0;
high = 0;
for (i = 0; i < maxtable; i++)
check[i] = -1;
for (i = 0; i < nentries; i++)
{
state = matching_vector(i);
if (state < 0)
place = pack_vector(i);
else
place = base[state];
pos[i] = place;
base[order[i]] = place;
}
for (i = 0; i < nvectors; i++)
{
if (froms[i])
FREE(froms[i]);
if (tos[i])
FREE(tos[i]);
}
FREE(froms);
FREE(tos);
FREE(pos);
}
/* The function matching_vector determines if the vector specified by */
/* the input parameter matches a previously considered vector. The */
/* test at the start of the function checks if the vector represents */
/* a row of shifts over terminal symbols or a row of reductions, or a */
/* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
/* check if a column of shifts over a nonterminal symbols matches a */
/* previously considered vector. Because of the nature of LR parsing */
/* tables, no two columns can match. Therefore, the only possible */
/* match would be between a row and a column. Such matches are */
/* unlikely. Therefore, to save time, no attempt is made to see if a */
/* column matches a previously considered vector. */
/* */
/* Matching_vector is poorly designed. The test could easily be made */
/* faster. Also, it depends on the vectors being in a specific */
/* order. */
int
matching_vector(vector)
int vector;
{
register int i;
register int j;
register int k;
register int t;
register int w;
register int match;
register int prev;
Cooperate();
i = order[vector];
if (i >= 2*nstates)
return (-1);
t = tally[i];
w = width[i];
for (prev = vector - 1; prev >= 0; prev--)
{
j = order[prev];
if (width[j] != w || tally[j] != t)
return (-1);
match = 1;
for (k = 0; match && k < t; k++)
{
if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
match = 0;
}
if (match)
return (j);
}
return (-1);
}
int
pack_vector(vector)
int vector;
{
register int i, j, k, l;
register int t;
register int loc;
register int ok;
register short *from;
register short *to;
int newmax;
Cooperate();
i = order[vector];
t = tally[i];
assert(t);
from = froms[i];
to = tos[i];
j = lowzero - from[0];
for (k = 1; k < t; ++k)
if (lowzero - from[k] > j)
j = lowzero - from[k];
for (;; ++j)
{
if (j == 0)
continue;
ok = 1;
for (k = 0; ok && k < t; k++)
{
loc = j + from[k];
if (loc >= maxtable)
{
if (loc >= MAXTABLE)
fatal("maximum table size exceeded");
newmax = maxtable;
do { newmax += 200; } while (newmax <= loc);
table = (short *) REALLOC(table, newmax*sizeof(short));
if (table == 0) no_space();
check = (short *) REALLOC(check, newmax*sizeof(short));
if (check == 0) no_space();
for (l = maxtable; l < newmax; ++l)
{
table[l] = 0;
check[l] = -1;
}
maxtable = newmax;
}
if (check[loc] != -1)
ok = 0;
}
for (k = 0; ok && k < vector; k++)
{
if (pos[k] == j)
ok = 0;
}
if (ok)
{
for (k = 0; k < t; k++)
{
loc = j + from[k];
table[loc] = to[k];
check[loc] = from[k];
if (loc > high) high = loc;
}
while (check[lowzero] != -1)
++lowzero;
return (j);
}
}
}
output_base()
{
register int i, j;
start_num_array("yysindex", 39, base[0]);
j = 10;
for (i = 1; i < nstates; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
++j;
write_num(base[i]);
}
if (!rflag) outline += 2;
end_num_array();
start_num_array("yyrindex", 39, base[nstates]);
j = 10;
for (i = nstates + 1; i < 2*nstates; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
++j;
write_num(base[i]);
}
if (!rflag) outline += 2;
end_num_array();
start_num_array("yygindex", 39, base[2*nstates]);
j = 10;
for (i = 2*nstates + 1; i < nvectors - 1; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
++j;
write_num(base[i]);
}
if (!rflag) outline += 2;
end_num_array();
FREE(base);
}
output_table()
{
register int i;
register int j;
Cooperate();
++outline;
write_define("YYTABLESIZE", high);
start_num_array("yytable", 40, table[0]);
j = 10;
for (i = 1; i <= high; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
++j;
write_num(table[i]);
}
if (!rflag) outline += 2;
end_num_array();
FREE(table);
}
output_check()
{
register int i;
register int j;
start_num_array("yycheck", 40, check[0]);
j = 10;
for (i = 1; i <= high; i++)
{
if (j >= 10)
{
Cooperate();
if (!rflag) ++outline;
putc('\n', output_file);
j = 1;
}
else
++j;
write_num(check[i]);
}
if (!rflag) outline += 2;
end_num_array();
FREE(check);
}
int
is_C_identifier(name)
char *name;
{
register char *s;
register int c;
s = name;
c = *s;
if (c == '"')
{
c = *++s;
if (!isalpha(c) && c != '_' && c != '$')
return (0);
else if (language==PERL && c == '$')
return (0);
while ((c = *++s) != '"')
{
if (!isalnum(c) && c != '_' && c != '$')
return (0);
else if (language==PERL && c == '$')
return (0);
}
return (1);
}
if (!isalpha(c) && c != '_' && c != '$')
return (0);
else if (language==PERL && c == '$')
return (0);
while (c = *++s)
{
if (!isalnum(c) && c != '_' && c != '$')
return (0);
else if (language==PERL && c == '$')
return (0);
}
return (1);
}
output_defines()
{
register int c, i;
register char *s;
Cooperate();
for (i = 2; i < ntokens; ++i)
{
s = symbol_name[i];
if (is_C_identifier(s))
{
start_define(code_file);
if (dflag)
start_define(defines_file);
c = *s;
if (c == '"')
{
while ((c = *++s) != '"')
{
putc(c, code_file);
if (dflag) putc(c, defines_file);
}
}
else
{
do
{
putc(c, code_file);
if (dflag) putc(c, defines_file);
}
while (c = *++s);
}
++outline;
end_define(code_file, symbol_value[i]);
if (dflag)
end_define(defines_file, symbol_value[i]);
}
}
++outline;
write_define("YYERRCODE", symbol_value[1]);
if (dflag && unionized && language == C)
{
fclose(union_file);
union_file = fopen(union_file_name, "r");
if (union_file == NULL) open_error(union_file_name);
while ((c = getc(union_file)) != EOF)
putc(c, defines_file);
fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE yylval;\n");
}
}
output_stored_text()
{
register int c;
register FILE *in, *out;
Cooperate();
fclose(text_file);
text_file = fopen(text_file_name, "r");
if (text_file == NULL)
open_error(text_file_name);
in = text_file;
if ((c = getc(in)) == EOF)
return;
out = code_file;
if (c == '\n')
++outline;
putc(c, out);
while ((c = getc(in)) != EOF)
{
if (c == '\n')
++outline;
putc(c, out);
}
if (!lflag)
fprintf(out, line_format, ++outline + 1, code_file_name);
}
output_debug()
{
register int i, j, k, max;
char **symnam, *s;
Cooperate();
++outline;
write_define("YYFINAL", final_state);
outline += 3;
fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
tflag);
if (rflag)
fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
tflag);
max = 0;
for (i = 2; i < ntokens; ++i)
if (symbol_value[i] > max)
max = symbol_value[i];
++outline;
write_define("YYMAXTOKEN", max);
symnam = (char **) MALLOC((max+1)*sizeof(char *));
if (symnam == 0) no_space();
/* Note that it is not necessary to initialize the element */
/* symnam[max]. */
for (i = 0; i < max; ++i)
symnam[i] = 0;
for (i = ntokens - 1; i >= 2; --i)
symnam[symbol_value[i]] = symbol_name[i];
symnam[0] = "end-of-file";
if (!rflag) ++outline;
fprintf(output_file, "#if YYDEBUG\n");
start_string_array("yyname", 0);
j = 80;
for (i = 0; i <= max; ++i)
{
Cooperate();
if (s = symnam[i])
{
if (s[0] == '"')
{
k = 7;
while (*++s != '"')
{
++k;
if (*s == '\\')
{
k += 2;
if (*++s == '\\')
++k;
}
}
j += k;
if (j > 80)
{
if (!rflag) ++outline;
putc('\n', output_file);
j = k;
}
fprintf(output_file, "\"\\\"");
s = symnam[i];
while (*++s != '"')
{
if (*s == '\\')
{
fprintf(output_file, "\\\\");
if (*++s == '\\')
fprintf(output_file, "\\\\");
else
putc(*s, output_file);
}
else
putc(*s, output_file);
}
fprintf(output_file, "\\\"\",");
}
else if (s[0] == '\'')
{
if (s[1] == '"')
{
j += 7;
if (j > 80)
{
if (!rflag) ++outline;
putc('\n', output_file);
j = 7;
}
fprintf(output_file, "\"'\\\"'\",");
}
else
{
k = 5;
while (*++s != '\'')
{
++k;
if (*s == '\\')
{
k += 2;
if (*++s == '\\')
++k;
}
}
j += k;
if (j > 80)
{
if (!rflag) ++outline;
putc('\n', output_file);
j = k;
}
fprintf(output_file, "\"'");
s = symnam[i];
while (*++s != '\'')
{
if (*s == '\\')
{
fprintf(output_file, "\\\\");
if (*++s == '\\')
fprintf(output_file, "\\\\");
else
putc(*s, output_file);
}
else
putc(*s, output_file);
}
fprintf(output_file, "'\",");
}
}
else
{
k = strlen(s) + 3;
j += k;
if (j > 80)
{
if (!rflag) ++outline;
putc('\n', output_file);
j = k;
}
putc('"', output_file);
do { putc(*s, output_file); } while (*++s);
fprintf(output_file, "\",");
}
}
else
{
j += 2;
if (j > 80)
{
if (!rflag) ++outline;
putc('\n', output_file);
j = 2;
}
write_null();
}
}
if (!rflag) outline += 2;
end_string_array(1);
FREE(symnam);
if (!rflag) ++outline;
start_string_array("yyrule", 1);
for (i = 2; i < nrules; ++i)
{
Cooperate();
if (language == PERL && symbol_name[rlhs[i]][0] == '$')
fprintf(output_file, "\"\\%s :", symbol_name[rlhs[i]]);
else
fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
for (j = rrhs[i]; ritem[j] > 0; ++j)
{
s = symbol_name[ritem[j]];
if (s[0] == '"')
{
fprintf(output_file, " \\\"");
while (*++s != '"')
{
if (*s == '\\')
{
if (s[1] == '\\')
fprintf(output_file, "\\\\\\\\");
else
fprintf(output_file, "\\\\%c", s[1]);
++s;
}
else
putc(*s, output_file);
}
fprintf(output_file, "\\\"");
}
else if (s[0] == '\'')
{
if (s[1] == '"')
fprintf(output_file, " '\\\"'");
else if (s[1] == '\\')
{
if (s[2] == '\\')
fprintf(output_file, " '\\\\\\\\");
else
fprintf(output_file, " '\\\\%c", s[2]);
s += 2;
while (*++s != '\'')
putc(*s, output_file);
putc('\'', output_file);
}
else
fprintf(output_file, " '%c'", s[1]);
}
else
fprintf(output_file, " %s", s);
}
if (!rflag) ++outline;
fprintf(output_file, "\",\n");
}
if (!rflag) outline += 2;
end_string_array(0);
fprintf(output_file, "#endif\n");
}
output_stype()
{
if (!unionized && ntags == 0 && language == C)
{
outline += 3;
fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
}
}
output_trailing_text()
{
register int c, last;
register FILE *in, *out;
Cooperate();
if (line == 0)
return;
in = input_file;
out = code_file;
c = *cptr;
if (c == '\n')
{
++lineno;
if ((c = getc(in)) == EOF)
return;
if (!lflag)
{
++outline;
fprintf(out, line_format, lineno, input_file_name);
}
if (c == '\n')
++outline;
putc(c, out);
last = c;
}
else
{
if (!lflag)
{
++outline;
fprintf(out, line_format, lineno, input_file_name);
}
do { putc(c, out); } while ((c = *++cptr) != '\n');
++outline;
putc('\n', out);
last = '\n';
}
while ((c = getc(in)) != EOF)
{
if (c == '\n')
++outline;
putc(c, out);
last = c;
}
if (last != '\n')
{
++outline;
putc('\n', out);
}
if (!lflag)
fprintf(out, line_format, ++outline + 1, code_file_name);
}
output_semantic_actions()
{
register int c, last;
register FILE *out;
Cooperate();
fclose(action_file);
action_file = fopen(action_file_name, "r");
if (action_file == NULL)
open_error(action_file_name);
if ((c = getc(action_file)) == EOF)
return;
out = code_file;
last = c;
if (c == '\n')
++outline;
putc(c, out);
while ((c = getc(action_file)) != EOF)
{
if (c == '\n')
++outline;
putc(c, out);
last = c;
}
if (last != '\n')
{
++outline;
putc('\n', out);
}
if (!lflag)
fprintf(out, line_format, ++outline + 1, code_file_name);
}
free_itemsets()
{
register core *cp, *next;
FREE(state_table);
for (cp = first_state; cp; cp = next)
{
next = cp->next;
FREE(cp);
}
}
free_shifts()
{
register shifts *sp, *next;
FREE(shift_table);
for (sp = first_shift; sp; sp = next)
{
next = sp->next;
FREE(sp);
}
}
free_reductions()
{
register reductions *rp, *next;
FREE(reduction_table);
for (rp = first_reduction; rp; rp = next)
{
next = rp->next;
FREE(rp);
}
}