xref: /original-bsd/usr.bin/yacc/main.c (revision d08c9fe5)
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  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 char copyright[] =
13 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
14  All rights reserved.\n";
15 #endif /* not lint */
16 
17 #ifndef lint
18 static char sccsid[] = "@(#)main.c	5.5 (Berkeley) 05/24/93";
19 #endif /* not lint */
20 
21 #include <signal.h>
22 #include "defs.h"
23 
24 char dflag;
25 char lflag;
26 char rflag;
27 char tflag;
28 char vflag;
29 
30 char *symbol_prefix;
31 char *file_prefix = "y";
32 char *myname = "yacc";
33 char *temp_form = "yacc.XXXXXXX";
34 
35 int lineno;
36 int outline;
37 
38 char *action_file_name;
39 char *code_file_name;
40 char *defines_file_name;
41 char *input_file_name = "";
42 char *output_file_name;
43 char *text_file_name;
44 char *union_file_name;
45 char *verbose_file_name;
46 
47 FILE *action_file;	/*  a temp file, used to save actions associated    */
48 			/*  with rules until the parser is written	    */
49 FILE *code_file;	/*  y.code.c (used when the -r option is specified) */
50 FILE *defines_file;	/*  y.tab.h					    */
51 FILE *input_file;	/*  the input file				    */
52 FILE *output_file;	/*  y.tab.c					    */
53 FILE *text_file;	/*  a temp file, used to save text until all	    */
54 			/*  symbols have been defined			    */
55 FILE *union_file;	/*  a temp file, used to save the union		    */
56 			/*  definition until all symbol have been	    */
57 			/*  defined					    */
58 FILE *verbose_file;	/*  y.output					    */
59 
60 int nitems;
61 int nrules;
62 int nsyms;
63 int ntokens;
64 int nvars;
65 
66 int   start_symbol;
67 char  **symbol_name;
68 short *symbol_value;
69 short *symbol_prec;
70 char  *symbol_assoc;
71 
72 short *ritem;
73 short *rlhs;
74 short *rrhs;
75 short *rprec;
76 char  *rassoc;
77 short **derives;
78 char *nullable;
79 
80 extern char *mktemp();
81 extern char *getenv();
82 
83 
done(k)84 done(k)
85 int k;
86 {
87     if (action_file) { fclose(action_file); unlink(action_file_name); }
88     if (text_file) { fclose(text_file); unlink(text_file_name); }
89     if (union_file) { fclose(union_file); unlink(union_file_name); }
90     exit(k);
91 }
92 
93 
94 void
onintr(signo)95 onintr(signo)
96 	int signo;
97 {
98     done(1);
99 }
100 
101 
set_signals()102 set_signals()
103 {
104 #ifdef SIGINT
105     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
106 	signal(SIGINT, onintr);
107 #endif
108 #ifdef SIGTERM
109     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
110 	signal(SIGTERM, onintr);
111 #endif
112 #ifdef SIGHUP
113     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
114 	signal(SIGHUP, onintr);
115 #endif
116 }
117 
118 
usage()119 usage()
120 {
121     fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-p symbol_prefix] filename\n", myname);
122     exit(1);
123 }
124 
125 
getargs(argc,argv)126 getargs(argc, argv)
127 int argc;
128 char *argv[];
129 {
130     register int i;
131     register char *s;
132 
133     if (argc > 0) myname = argv[0];
134     for (i = 1; i < argc; ++i)
135     {
136 	s = argv[i];
137 	if (*s != '-') break;
138 	switch (*++s)
139 	{
140 	case '\0':
141 	    input_file = stdin;
142 	    if (i + 1 < argc) usage();
143 	    return;
144 
145 	case '-':
146 	    ++i;
147 	    goto no_more_options;
148 
149 	case 'b':
150 	    if (*++s)
151 		 file_prefix = s;
152 	    else if (++i < argc)
153 		file_prefix = argv[i];
154 	    else
155 		usage();
156 	    continue;
157 
158 	case 'd':
159 	    dflag = 1;
160 	    break;
161 
162 	case 'l':
163 	    lflag = 1;
164 	    break;
165 
166 	case 'p':
167 	    if (*++s)
168 		symbol_prefix = s;
169 	    else if (++i < argc)
170 		symbol_prefix = argv[i];
171 	    else
172 		usage();
173 	    continue;
174 
175 	case 'r':
176 	    rflag = 1;
177 	    break;
178 
179 	case 't':
180 	    tflag = 1;
181 	    break;
182 
183 	case 'v':
184 	    vflag = 1;
185 	    break;
186 
187 	default:
188 	    usage();
189 	}
190 
191 	for (;;)
192 	{
193 	    switch (*++s)
194 	    {
195 	    case '\0':
196 		goto end_of_option;
197 
198 	    case 'd':
199 		dflag = 1;
200 		break;
201 
202 	    case 'l':
203 		lflag = 1;
204 		break;
205 
206 	    case 'r':
207 		rflag = 1;
208 		break;
209 
210 	    case 't':
211 		tflag = 1;
212 		break;
213 
214 	    case 'v':
215 		vflag = 1;
216 		break;
217 
218 	    default:
219 		usage();
220 	    }
221 	}
222 end_of_option:;
223     }
224 
225 no_more_options:;
226     if (i + 1 != argc) usage();
227     input_file_name = argv[i];
228 }
229 
230 
231 char *
allocate(n)232 allocate(n)
233 unsigned n;
234 {
235     register char *p;
236 
237     p = NULL;
238     if (n)
239     {
240 	p = CALLOC(1, n);
241 	if (!p) no_space();
242     }
243     return (p);
244 }
245 
246 
create_file_names()247 create_file_names()
248 {
249     int i, len;
250     char *tmpdir;
251 
252     tmpdir = getenv("TMPDIR");
253     if (tmpdir == 0) tmpdir = "/tmp";
254 
255     len = strlen(tmpdir);
256     i = len + 13;
257     if (len && tmpdir[len-1] != '/')
258 	++i;
259 
260     action_file_name = MALLOC(i);
261     if (action_file_name == 0) no_space();
262     text_file_name = MALLOC(i);
263     if (text_file_name == 0) no_space();
264     union_file_name = MALLOC(i);
265     if (union_file_name == 0) no_space();
266 
267     strcpy(action_file_name, tmpdir);
268     strcpy(text_file_name, tmpdir);
269     strcpy(union_file_name, tmpdir);
270 
271     if (len && tmpdir[len - 1] != '/')
272     {
273 	action_file_name[len] = '/';
274 	text_file_name[len] = '/';
275 	union_file_name[len] = '/';
276 	++len;
277     }
278 
279     strcpy(action_file_name + len, temp_form);
280     strcpy(text_file_name + len, temp_form);
281     strcpy(union_file_name + len, temp_form);
282 
283     action_file_name[len + 5] = 'a';
284     text_file_name[len + 5] = 't';
285     union_file_name[len + 5] = 'u';
286 
287     mktemp(action_file_name);
288     mktemp(text_file_name);
289     mktemp(union_file_name);
290 
291     len = strlen(file_prefix);
292 
293     output_file_name = MALLOC(len + 7);
294     if (output_file_name == 0)
295 	no_space();
296     strcpy(output_file_name, file_prefix);
297     strcpy(output_file_name + len, OUTPUT_SUFFIX);
298 
299     if (rflag)
300     {
301 	code_file_name = MALLOC(len + 8);
302 	if (code_file_name == 0)
303 	    no_space();
304 	strcpy(code_file_name, file_prefix);
305 	strcpy(code_file_name + len, CODE_SUFFIX);
306     }
307     else
308 	code_file_name = output_file_name;
309 
310     if (dflag)
311     {
312 	defines_file_name = MALLOC(len + 7);
313 	if (defines_file_name == 0)
314 	    no_space();
315 	strcpy(defines_file_name, file_prefix);
316 	strcpy(defines_file_name + len, DEFINES_SUFFIX);
317     }
318 
319     if (vflag)
320     {
321 	verbose_file_name = MALLOC(len + 8);
322 	if (verbose_file_name == 0)
323 	    no_space();
324 	strcpy(verbose_file_name, file_prefix);
325 	strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
326     }
327 }
328 
329 
open_files()330 open_files()
331 {
332     create_file_names();
333 
334     if (input_file == 0)
335     {
336 	input_file = fopen(input_file_name, "r");
337 	if (input_file == 0)
338 	    open_error(input_file_name);
339     }
340 
341     action_file = fopen(action_file_name, "w");
342     if (action_file == 0)
343 	open_error(action_file_name);
344 
345     text_file = fopen(text_file_name, "w");
346     if (text_file == 0)
347 	open_error(text_file_name);
348 
349     if (vflag)
350     {
351 	verbose_file = fopen(verbose_file_name, "w");
352 	if (verbose_file == 0)
353 	    open_error(verbose_file_name);
354     }
355 
356     if (dflag)
357     {
358 	defines_file = fopen(defines_file_name, "w");
359 	if (defines_file == 0)
360 	    open_error(defines_file_name);
361 	union_file = fopen(union_file_name, "w");
362 	if (union_file ==  0)
363 	    open_error(union_file_name);
364     }
365 
366     output_file = fopen(output_file_name, "w");
367     if (output_file == 0)
368 	open_error(output_file_name);
369 
370     if (rflag)
371     {
372 	code_file = fopen(code_file_name, "w");
373 	if (code_file == 0)
374 	    open_error(code_file_name);
375     }
376     else
377 	code_file = output_file;
378 }
379 
380 
381 int
main(argc,argv)382 main(argc, argv)
383 int argc;
384 char *argv[];
385 {
386     set_signals();
387     getargs(argc, argv);
388     open_files();
389     reader();
390     lr0();
391     lalr();
392     make_parser();
393     verbose();
394     output();
395     done(0);
396     /*NOTREACHED*/
397 }
398