* Copyright (c) 1989 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)output.c 5.4 (Berkeley) %G%";
static short *state_count
;
output_semantic_actions();
fprintf(output_file
, "short yylhs[] = {%42d,",
symbol_value
[start_symbol
]);
for (i
= 3; i
< nrules
; i
++)
fprintf(output_file
, "%5d,", symbol_value
[rlhs
[i
]]);
fprintf(output_file
, "\n};\n");
fprintf(output_file
, "short yylen[] = {%42d,", 2);
for (i
= 3; i
< nrules
; i
++)
fprintf(output_file
, "%5d,", rrhs
[i
+ 1] - rrhs
[i
] - 1);
fprintf(output_file
, "\n};\n");
fprintf(output_file
, "short yydefred[] = {%39d,",
(defred
[0] ? defred
[0] - 2 : 0));
for (i
= 1; i
< nstates
; i
++)
fprintf(output_file
, "%5d,", (defred
[i
] ? defred
[i
] - 2 : 0));
fprintf(output_file
, "\n};\n");
nvectors
= 2*nstates
+ nvars
;
froms
= NEW2(nvectors
, short *);
tos
= NEW2(nvectors
, short *);
tally
= NEW2(nvectors
, short);
width
= NEW2(nvectors
, short);
FREE(goto_map
+ ntokens
);
register int shiftcount
, reducecount
;
register short *actionrow
, *r
, *s
;
actionrow
= NEW2(2*ntokens
, short);
for (i
= 0; i
< nstates
; ++i
)
for (j
= 0; j
< 2*ntokens
; ++j
)
for (p
= parser
[i
]; p
; p
= p
->next
)
if (p
->action_code
== SHIFT
)
actionrow
[p
->symbol
] = p
->number
;
else if (p
->action_code
== REDUCE
&& p
->number
!= defred
[i
])
actionrow
[p
->symbol
+ ntokens
] = p
->number
;
tally
[nstates
+i
] = reducecount
;
froms
[i
] = r
= NEW2(shiftcount
, short);
tos
[i
] = s
= NEW2(shiftcount
, short);
for (j
= 0; j
< ntokens
; ++j
)
if (min
> symbol_value
[j
])
if (max
< symbol_value
[j
])
width
[i
] = max
- min
+ 1;
froms
[nstates
+i
] = r
= NEW2(reducecount
, short);
tos
[nstates
+i
] = s
= NEW2(reducecount
, short);
for (j
= 0; j
< ntokens
; ++j
)
if (actionrow
[ntokens
+j
])
if (min
> symbol_value
[j
])
if (max
< symbol_value
[j
])
*s
++ = actionrow
[ntokens
+j
] - 2;
width
[nstates
+i
] = max
- min
+ 1;
state_count
= NEW2(nstates
, short);
k
= default_goto(start_symbol
+ 1);
fprintf(output_file
, "short yydgoto[] = {%40d,", k
);
save_column(start_symbol
+ 1, k
);
for (i
= start_symbol
+ 2; i
< nsyms
; i
++)
fprintf(output_file
, "%5d,", k
);
fprintf(output_file
, "\n};\n");
register int default_state
;
n
= goto_map
[symbol
+ 1];
for (i
= 0; i
< nstates
; i
++)
state_count
[to_state
[i
]]++;
for (i
= 0; i
< nstates
; i
++)
if (state_count
[i
] > max
)
save_column(symbol
, default_state
)
n
= goto_map
[symbol
+ 1];
if (to_state
[i
] != default_state
)
symno
= symbol_value
[symbol
] + 2*nstates
;
froms
[symno
] = sp1
= sp
= NEW2(count
, short);
tos
[symno
] = sp2
= NEW2(count
, short);
if (to_state
[i
] != default_state
)
width
[symno
] = sp1
[-1] - sp
[0] + 1;
order
= NEW2(nvectors
, short);
for (i
= 0; i
< nvectors
; i
++)
while (j
>= 0 && (width
[order
[j
]] < w
))
while (j
>= 0 && (width
[order
[j
]] == w
) && (tally
[order
[j
]] < t
))
for (k
= nentries
- 1; k
> j
; k
--)
base
= NEW2(nvectors
, short);
pos
= NEW2(nentries
, short);
table
= NEW2(maxtable
, short);
check
= NEW2(maxtable
, short);
for (i
= 0; i
< maxtable
; i
++)
for (i
= 0; i
< nentries
; i
++)
state
= matching_vector(i
);
for (i
= 0; i
< nvectors
; i
++)
/* 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 */
for (prev
= vector
- 1; prev
>= 0; prev
--)
if (width
[j
] != w
|| tally
[j
] != t
)
for (k
= 0; match
&& k
< t
; k
++)
if (tos
[j
][k
] != tos
[i
][k
] || froms
[j
][k
] != froms
[i
][k
])
if (lowzero
- from
[k
] > j
)
for (k
= 0; ok
&& k
< t
; k
++)
fatal("maximum table size exceeded");
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
)
for (k
= 0; ok
&& k
< vector
; k
++)
if (loc
> high
) high
= loc
;
while (check
[lowzero
] != -1)
fprintf(output_file
, "short yysindex[] = {%39d,", base
[0]);
for (i
= 1; i
< nstates
; i
++)
fprintf(output_file
, "%5d,", base
[i
]);
fprintf(output_file
, "\n};\nshort yyrindex[] = {%39d,",
for (i
= nstates
+ 1; i
< 2*nstates
; i
++)
fprintf(output_file
, "%5d,", base
[i
]);
fprintf(output_file
, "\n};\nshort yygindex[] = {%39d,",
for (i
= 2*nstates
+ 1; i
< nvectors
- 1; i
++)
fprintf(output_file
, "%5d,", base
[i
]);
fprintf(output_file
, "\n};\n");
fprintf(output_file
, "#define YYTABLESIZE %d\n", high
);
fprintf(output_file
, "short yytable[] = {%40d,", table
[0]);
for (i
= 1; i
<= high
; i
++)
fprintf(output_file
, "%5d,", table
[i
]);
fprintf(output_file
, "\n};\n");
fprintf(output_file
, "short yycheck[] = {%40d,", check
[0]);
for (i
= 1; i
<= high
; i
++)
fprintf(output_file
, "%5d,", check
[i
]);
fprintf(output_file
, "\n};\n");
if (!isalpha(c
) && c
!= '_' && c
!= '$')
while ((c
= *++s
) != '"')
if (!isalnum(c
) && c
!= '_' && c
!= '$')
if (!isalpha(c
) && c
!= '_' && c
!= '$')
if (!isalnum(c
) && c
!= '_' && c
!= '$')
for (i
= 2; i
< ntokens
; ++i
)
fprintf(output_file
, "#define ");
if (dflag
) fprintf(defines_file
, "#define ");
while ((c
= *++s
) != '"')
if (dflag
) putc(c
, defines_file
);
if (dflag
) putc(c
, defines_file
);
fprintf(output_file
, " %d\n", symbol_value
[i
]);
if (dflag
) fprintf(defines_file
, " %d\n", symbol_value
[i
]);
fprintf(output_file
, "#define YYERRCODE %d\n", symbol_value
[1]);
union_file
= fopen(union_file_name
, "r");
if (union_file
== NULL
) open_error(union_file_name
);
while ((c
= getc(union_file
)) != EOF
)
fprintf(defines_file
, " YYSTYPE;\nextern YYSTYPE yylval;\n");
text_file
= fopen(text_file_name
, "r");
if (text_file
== NULL
) open_error(text_file_name
);
if ((c
= getc(in
)) == EOF
)
if (c
== '\n') ++outline
;
while ((c
= getc(in
)) != EOF
)
if (c
== '\n') ++outline
;
fprintf(out
, line_format
, outline
+ 1, output_file_name
);
register int i
, j
, k
, max
;
fprintf(output_file
, "#define YYFINAL %d\n", final_state
);
fprintf(output_file
, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
for (i
= 2; i
< ntokens
; ++i
)
if (symbol_value
[i
] > max
)
fprintf(output_file
, "#define YYMAXTOKEN %d\n", max
);
symnam
= (char **) MALLOC((max
+1)*sizeof(char *));
if (symnam
== 0) no_space();
for (i
= 0; i
< max
; ++i
)
for (i
= ntokens
- 1; i
>= 2; --i
)
symnam
[symbol_value
[i
]] = symbol_name
[i
];
symnam
[0] = "end-of-file";
fprintf(output_file
, "#if YYDEBUG\nchar *yyname[] = {");
for (i
= 0; i
<= max
; ++i
)
fprintf(output_file
, "\"\\\"");
fprintf(output_file
, "\\\\");
fprintf(output_file
, "\\\\");
fprintf(output_file
, "\\\"\",");
fprintf(output_file
, "\"'\\\"'\",");
fprintf(output_file
, "\"'");
fprintf(output_file
, "\\\\");
fprintf(output_file
, "\\\\");
fprintf(output_file
, "'\",");
do { putc(*s
, output_file
); } while (*++s
);
fprintf(output_file
, "\",");
fprintf(output_file
, "0,");
fprintf(output_file
, "\n};\n");
fprintf(output_file
, "char *yyrule[] = {\n");
for (i
= 2; i
< nrules
; ++i
)
fprintf(output_file
, "\"%s :", symbol_name
[rlhs
[i
]]);
for (j
= rrhs
[i
]; ritem
[j
] > 0; ++j
)
s
= symbol_name
[ritem
[j
]];
fprintf(output_file
, " \\\"");
fprintf(output_file
, "\\\\\\\\");
fprintf(output_file
, "\\\\%c", s
[1]);
fprintf(output_file
, "\\\"");
fprintf(output_file
, " '\\\"'");
fprintf(output_file
, " '\\\\\\\\");
fprintf(output_file
, " '\\\\%c", s
[2]);
fprintf(output_file
, " '%c'", s
[1]);
fprintf(output_file
, " %s", s
);
fprintf(output_file
, "\",\n");
fprintf(output_file
, "};\n#endif\n");
if (!unionized
&& ntags
== 0)
fprintf(output_file
, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
if ((c
= getc(input_file
)) == EOF
)
fprintf(output_file
, line_format
, lineno
, input_file_name
);
if (c
== '\n') ++outline
;
fprintf(output_file
, line_format
, lineno
, input_file_name
);
do { putc(c
, output_file
); } while ((c
= *++cptr
) != '\n');
while ((c
= getc(input_file
)) != EOF
)
if (c
== '\n') ++outline
;
fprintf(output_file
, line_format
, outline
+ 1, output_file_name
);
output_semantic_actions()
action_file
= fopen(action_file_name
, "r");
if (action_file
== NULL
) open_error(action_file_name
);
if ((c
= getc(action_file
)) == EOF
)
if (c
== '\n') ++outline
;
while ((c
= getc(action_file
)) != EOF
)
if (c
== '\n') ++outline
;
fprintf(output_file
, line_format
, outline
+ 1, output_file_name
);
register core
*cp
, *next
;
for (cp
= first_state
; cp
; cp
= next
)
register shifts
*sp
, *next
;
for (sp
= first_shift
; sp
; sp
= next
)
register reductions
*rp
, *next
;
for (rp
= first_reduction
; rp
; rp
= next
)