xref: /386bsd/usr/src/usr.bin/yacc/main.c (revision a2142627)
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