1 /*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Robert Paul Corbett.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #ifndef lint
38 char copyright[] =
39 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
40 All rights reserved.\n";
41 #endif /* not lint */
42
43 #ifndef lint
44 static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 2/26/91";
45 #endif /* not lint */
46
47 #include <signal.h>
48 #include "defs.h"
49
50 char dflag;
51 char lflag;
52 char rflag;
53 char tflag;
54 char vflag;
55
56 char *file_prefix = "y";
57 char *myname = "yacc";
58 char *temp_form = "yacc.XXXXXXX";
59
60 int lineno;
61 int outline;
62
63 char *action_file_name;
64 char *code_file_name;
65 char *defines_file_name;
66 char *input_file_name = "";
67 char *output_file_name;
68 char *text_file_name;
69 char *union_file_name;
70 char *verbose_file_name;
71
72 FILE *action_file; /* a temp file, used to save actions associated */
73 /* with rules until the parser is written */
74 FILE *code_file; /* y.code.c (used when the -r option is specified) */
75 FILE *defines_file; /* y.tab.h */
76 FILE *input_file; /* the input file */
77 FILE *output_file; /* y.tab.c */
78 FILE *text_file; /* a temp file, used to save text until all */
79 /* symbols have been defined */
80 FILE *union_file; /* a temp file, used to save the union */
81 /* definition until all symbol have been */
82 /* defined */
83 FILE *verbose_file; /* y.output */
84
85 int nitems;
86 int nrules;
87 int nsyms;
88 int ntokens;
89 int nvars;
90
91 int start_symbol;
92 char **symbol_name;
93 short *symbol_value;
94 short *symbol_prec;
95 char *symbol_assoc;
96
97 short *ritem;
98 short *rlhs;
99 short *rrhs;
100 short *rprec;
101 char *rassoc;
102 short **derives;
103 char *nullable;
104
105 extern char *mktemp();
106 extern char *getenv();
107
108
done(k)109 done(k)
110 int k;
111 {
112 if (action_file) { fclose(action_file); unlink(action_file_name); }
113 if (text_file) { fclose(text_file); unlink(text_file_name); }
114 if (union_file) { fclose(union_file); unlink(union_file_name); }
115 exit(k);
116 }
117
118
119 void
onintr()120 onintr()
121 {
122 done(1);
123 }
124
125
set_signals()126 set_signals()
127 {
128 #ifdef SIGINT
129 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
130 signal(SIGINT, onintr);
131 #endif
132 #ifdef SIGTERM
133 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
134 signal(SIGTERM, onintr);
135 #endif
136 #ifdef SIGHUP
137 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
138 signal(SIGHUP, onintr);
139 #endif
140 }
141
142
usage()143 usage()
144 {
145 fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] filename\n", myname);
146 exit(1);
147 }
148
149
getargs(argc,argv)150 getargs(argc, argv)
151 int argc;
152 char *argv[];
153 {
154 register int i;
155 register char *s;
156
157 if (argc > 0) myname = argv[0];
158 for (i = 1; i < argc; ++i)
159 {
160 s = argv[i];
161 if (*s != '-') break;
162 switch (*++s)
163 {
164 case '\0':
165 input_file = stdin;
166 if (i + 1 < argc) usage();
167 return;
168
169 case '-':
170 ++i;
171 goto no_more_options;
172
173 case 'b':
174 if (*++s)
175 file_prefix = s;
176 else if (++i < argc)
177 file_prefix = argv[i];
178 else
179 usage();
180 continue;
181
182 case 'd':
183 dflag = 1;
184 break;
185
186 case 'l':
187 lflag = 1;
188 break;
189
190 case 'r':
191 rflag = 1;
192 break;
193
194 case 't':
195 tflag = 1;
196 break;
197
198 case 'v':
199 vflag = 1;
200 break;
201
202 default:
203 usage();
204 }
205
206 for (;;)
207 {
208 switch (*++s)
209 {
210 case '\0':
211 goto end_of_option;
212
213 case 'd':
214 dflag = 1;
215 break;
216
217 case 'l':
218 lflag = 1;
219 break;
220
221 case 'r':
222 rflag = 1;
223 break;
224
225 case 't':
226 tflag = 1;
227 break;
228
229 case 'v':
230 vflag = 1;
231 break;
232
233 default:
234 usage();
235 }
236 }
237 end_of_option:;
238 }
239
240 no_more_options:;
241 if (i + 1 != argc) usage();
242 input_file_name = argv[i];
243 }
244
245
246 char *
allocate(n)247 allocate(n)
248 unsigned n;
249 {
250 register char *p;
251
252 p = NULL;
253 if (n)
254 {
255 p = CALLOC(1, n);
256 if (!p) no_space();
257 }
258 return (p);
259 }
260
261
create_file_names()262 create_file_names()
263 {
264 int i, len;
265 char *tmpdir;
266
267 tmpdir = getenv("TMPDIR");
268 if (tmpdir == 0) tmpdir = "/tmp";
269
270 len = strlen(tmpdir);
271 i = len + 13;
272 if (len && tmpdir[len-1] != '/')
273 ++i;
274
275 action_file_name = MALLOC(i);
276 if (action_file_name == 0) no_space();
277 text_file_name = MALLOC(i);
278 if (text_file_name == 0) no_space();
279 union_file_name = MALLOC(i);
280 if (union_file_name == 0) no_space();
281
282 strcpy(action_file_name, tmpdir);
283 strcpy(text_file_name, tmpdir);
284 strcpy(union_file_name, tmpdir);
285
286 if (len && tmpdir[len - 1] != '/')
287 {
288 action_file_name[len] = '/';
289 text_file_name[len] = '/';
290 union_file_name[len] = '/';
291 ++len;
292 }
293
294 strcpy(action_file_name + len, temp_form);
295 strcpy(text_file_name + len, temp_form);
296 strcpy(union_file_name + len, temp_form);
297
298 action_file_name[len + 5] = 'a';
299 text_file_name[len + 5] = 't';
300 union_file_name[len + 5] = 'u';
301
302 mktemp(action_file_name);
303 mktemp(text_file_name);
304 mktemp(union_file_name);
305
306 len = strlen(file_prefix);
307
308 output_file_name = MALLOC(len + 7);
309 if (output_file_name == 0)
310 no_space();
311 strcpy(output_file_name, file_prefix);
312 strcpy(output_file_name + len, OUTPUT_SUFFIX);
313
314 if (rflag)
315 {
316 code_file_name = MALLOC(len + 8);
317 if (code_file_name == 0)
318 no_space();
319 strcpy(code_file_name, file_prefix);
320 strcpy(code_file_name + len, CODE_SUFFIX);
321 }
322 else
323 code_file_name = output_file_name;
324
325 if (dflag)
326 {
327 defines_file_name = MALLOC(len + 7);
328 if (defines_file_name == 0)
329 no_space();
330 strcpy(defines_file_name, file_prefix);
331 strcpy(defines_file_name + len, DEFINES_SUFFIX);
332 }
333
334 if (vflag)
335 {
336 verbose_file_name = MALLOC(len + 8);
337 if (verbose_file_name == 0)
338 no_space();
339 strcpy(verbose_file_name, file_prefix);
340 strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
341 }
342 }
343
344
open_files()345 open_files()
346 {
347 create_file_names();
348
349 if (input_file == 0)
350 {
351 input_file = fopen(input_file_name, "r");
352 if (input_file == 0)
353 open_error(input_file_name);
354 }
355
356 action_file = fopen(action_file_name, "w");
357 if (action_file == 0)
358 open_error(action_file_name);
359
360 text_file = fopen(text_file_name, "w");
361 if (text_file == 0)
362 open_error(text_file_name);
363
364 if (vflag)
365 {
366 verbose_file = fopen(verbose_file_name, "w");
367 if (verbose_file == 0)
368 open_error(verbose_file_name);
369 }
370
371 if (dflag)
372 {
373 defines_file = fopen(defines_file_name, "w");
374 if (defines_file == 0)
375 open_error(defines_file_name);
376 union_file = fopen(union_file_name, "w");
377 if (union_file == 0)
378 open_error(union_file_name);
379 }
380
381 output_file = fopen(output_file_name, "w");
382 if (output_file == 0)
383 open_error(output_file_name);
384
385 if (rflag)
386 {
387 code_file = fopen(code_file_name, "w");
388 if (code_file == 0)
389 open_error(code_file_name);
390 }
391 else
392 code_file = output_file;
393 }
394
395
396 int
main(argc,argv)397 main(argc, argv)
398 int argc;
399 char *argv[];
400 {
401 set_signals();
402 getargs(argc, argv);
403 open_files();
404 reader();
405 lr0();
406 lalr();
407 make_parser();
408 verbose();
409 output();
410 done(0);
411 /*NOTREACHED*/
412 }
413