1 #include "defs.h"
2 #include <signal.h>
3 #include <stdio.h>
4 #include <unistd.h>
5
6 char dflag;
7 char lflag;
8 char rflag;
9 char tflag;
10 char vflag;
11 int Eflag = 0;
12
13 char *symbol_prefix = "yy";
14 char *myname = "yacc";
15 #if defined(__MSDOS__) || defined(_WIN32)
16 #define DIR_CHAR '\\'
17 #define DEFAULT_TMPDIR "."
18 char *file_prefix = "y";
19 #else /* Unix */
20 #define DIR_CHAR '/'
21 #define DEFAULT_TMPDIR "/tmp"
22 char *file_prefix = 0;
23 #endif
24 char *temp_form = "yacc_t_XXXXXX";
25
26 int outline;
27
28 char *action_file_name;
29 char *code_file_name;
30 char *defines_file_name;
31 char include_defines;
32 char *output_file_name;
33 char *text_file_name;
34 char *union_file_name;
35 char *verbose_file_name;
36
37 FILE *action_file; /* a temp file, used to save actions associated */
38 /* with rules until the parser is written */
39 FILE *code_file; /* y.code.c (used when the -r option is specified) */
40 FILE *defines_file; /* y.tab.h */
41 FILE *output_file; /* y.tab.c */
42 FILE *text_file; /* a temp file, used to save text until all */
43 /* symbols have been defined */
44 FILE *union_file; /* a temp file, used to save the union */
45 /* definition until all symbol have been */
46 /* defined */
47 FILE *verbose_file; /* y.output */
48
49 int nitems;
50 int nrules;
51 int nsyms;
52 int ntokens;
53 int nvars;
54
55 int start_symbol;
56 char **symbol_name;
57 Yshort *symbol_value;
58 Yshort *symbol_prec;
59 char *symbol_assoc;
60
61 Yshort *ritem;
62 Yshort *rlhs;
63 Yshort *rrhs;
64 Yshort *rprec;
65 char *rassoc;
66 Yshort **derives;
67 char *nullable;
68
69
done(int k)70 void done(int k)
71 {
72 if (action_file) { fclose(action_file); unlink(action_file_name); }
73 if (text_file) { fclose(text_file); unlink(text_file_name); }
74 if (union_file) { fclose(union_file); unlink(union_file_name); }
75 exit(k);
76 }
77
78
onintr(int ignore)79 void onintr(int ignore)
80 {
81 done(1);
82 }
83
84
set_signals()85 void set_signals()
86 {
87 #ifdef SIGINT
88 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
89 signal(SIGINT, onintr);
90 #endif
91 #ifdef SIGTERM
92 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
93 signal(SIGTERM, onintr);
94 #endif
95 #ifdef SIGHUP
96 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
97 signal(SIGHUP, onintr);
98 #endif
99 }
100
101
usage()102 void usage()
103 {
104 fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-S skeleton file] "
105 "[-p symbol_prefix] filename\n", myname);
106 exit(1);
107 }
108
109
getargs(int argc,char ** argv)110 void getargs(int argc, char **argv)
111 {
112 register int i;
113 register char *s;
114
115 if (argc > 0) myname = argv[0];
116 for (i = 1; i < argc; ++i)
117 {
118 s = argv[i];
119 if (*s != '-') break;
120 switch (*++s)
121 {
122 case '\0':
123 read_from_file("-");
124 if (i + 1 < argc) usage();
125 return;
126
127 case '-':
128 ++i;
129 goto no_more_options;
130
131 case 'b':
132 if (*++s)
133 file_prefix = s;
134 else if (++i < argc)
135 file_prefix = argv[i];
136 else
137 usage();
138 continue;
139
140 case 'p':
141 if (*++s)
142 symbol_prefix = s;
143 else if (++i < argc)
144 symbol_prefix = argv[i];
145 else
146 usage();
147 continue;
148
149 case 'd':
150 dflag = 1;
151 break;
152
153 case 'D':
154 /* Find the preprocessor variable */
155 { char **ps;
156 char *var_name = s + 1;
157 extern char *defd_vars[];
158 for(ps=&defd_vars[0]; *ps; ps++) {
159 if(strcmp(*ps,var_name)==0) {
160 error(input_file->lineno, 0, 0,
161 "Preprocessor variable %s already defined", var_name);
162 }
163 }
164 *ps = MALLOC(strlen(var_name)+1);
165 strcpy(*ps, var_name);
166 *++ps = NULL;
167 }
168 continue;
169
170 case 'E':
171 Eflag = 1;
172 break;
173
174 case 'l':
175 lflag = 1;
176 break;
177
178 case 'r':
179 rflag = 1;
180 break;
181
182 case 't':
183 tflag = 1;
184 break;
185
186 case 'v':
187 vflag = 1;
188 break;
189
190 case 'y':
191 file_prefix = "y";
192 break;
193
194 case 'S':
195 if (*++s)
196 read_skel(s);
197 else if (++i < argc)
198 read_skel(argv[i]);
199 else
200 usage();
201 continue;
202
203 default:
204 usage();
205 }
206
207 for (;;)
208 {
209 switch (*++s)
210 {
211 case '\0':
212 goto end_of_option;
213
214 case 'd':
215 dflag = 1;
216 break;
217
218 case 'l':
219 lflag = 1;
220 break;
221
222 case 'r':
223 rflag = 1;
224 break;
225
226 case 't':
227 tflag = 1;
228 break;
229
230 case 'v':
231 vflag = 1;
232 break;
233
234 case 'y':
235 file_prefix = "y";
236 break;
237
238 default:
239 usage();
240 }
241 }
242 end_of_option:;
243 }
244
245 no_more_options:;
246 if (i + 1 != argc) usage();
247 read_from_file(argv[i]);
248
249 if (!file_prefix) {
250 if (input_file && input_file->name) {
251 file_prefix = strdup(input_file->name);
252 if ((s = strrchr(file_prefix, '.')))
253 *s = 0;
254 } else {
255 file_prefix = "y";
256 }
257 }
258
259 /* Replace symbol prefix in the skeleton */
260 if (strcmp(symbol_prefix, "yy")) {
261 struct section *s;
262 char **l, *q, *n, *p;
263
264 for (s = section_list; s->name; s++)
265 for (l = s->ptr; *l; l++) {
266 /* Very conservative estimate */
267 p = n = malloc(strlen(*l) * strlen(symbol_prefix));
268 for (q = *l; *q; q++)
269 if (q[0] == 'y' && q[1] == 'y') {
270 strcpy(p, symbol_prefix);
271 p += strlen(symbol_prefix);
272 q++;
273 } else
274 *p++ = *q;
275 *p = 0;
276 *l = realloc(n ,strlen(n) + 1);
277 }
278 }
279 }
280
allocate(unsigned n)281 char *allocate(unsigned n)
282 {
283 register char *p;
284
285 p = NULL;
286 if (n)
287 {
288 /* VM: add a few bytes here, cause
289 * Linux calloc does not like sizes like 32768 */
290 p = CALLOC(1, n+10);
291 if (!p) no_space();
292 }
293 return (p);
294 }
295
296
create_file_names()297 void create_file_names()
298 {
299 int i, len;
300 char *tmpdir;
301
302 tmpdir = getenv("TMPDIR");
303 if (tmpdir == 0) tmpdir = DEFAULT_TMPDIR;
304
305 len = strlen(tmpdir);
306 i = len + 13;
307 if (len && tmpdir[len-1] != DIR_CHAR)
308 ++i;
309
310 action_file_name = MALLOC(i);
311 if (action_file_name == 0) no_space();
312 text_file_name = MALLOC(i);
313 if (text_file_name == 0) no_space();
314 union_file_name = MALLOC(i);
315 if (union_file_name == 0) no_space();
316
317 strcpy(action_file_name, tmpdir);
318 strcpy(text_file_name, tmpdir);
319 strcpy(union_file_name, tmpdir);
320
321 if (len && tmpdir[len - 1] != DIR_CHAR)
322 {
323 action_file_name[len] = DIR_CHAR;
324 text_file_name[len] = DIR_CHAR;
325 union_file_name[len] = DIR_CHAR;
326 ++len;
327 }
328
329 strcpy(action_file_name + len, temp_form);
330 strcpy(text_file_name + len, temp_form);
331 strcpy(union_file_name + len, temp_form);
332
333 action_file_name[len + 5] = 'a';
334 text_file_name[len + 5] = 't';
335 union_file_name[len + 5] = 'u';
336
337 if(mktemp(action_file_name)==NULL) {
338 fprintf(stderr, "btyacc: Cannot create temporary file\n");
339 exit(1);
340 }
341 if(mktemp(text_file_name)==NULL) {
342 fprintf(stderr, "btyacc: Cannot create temporary file\n");
343 exit(1);
344 }
345 if(mktemp(union_file_name)==NULL) {
346 fprintf(stderr, "btyacc: Cannot create temporary file\n");
347 exit(1);
348 }
349
350 len = strlen(file_prefix);
351
352 output_file_name = MALLOC(len + 7);
353 if (output_file_name == 0)
354 no_space();
355 strcpy(output_file_name, file_prefix);
356 strcpy(output_file_name + len, OUTPUT_SUFFIX);
357
358 if (rflag)
359 {
360 code_file_name = MALLOC(len + 8);
361 if (code_file_name == 0)
362 no_space();
363 strcpy(code_file_name, file_prefix);
364 strcpy(code_file_name + len, CODE_SUFFIX);
365 }
366 else
367 code_file_name = output_file_name;
368
369 if (dflag)
370 {
371 defines_file_name = MALLOC(len + 7);
372 if (defines_file_name == 0)
373 no_space();
374 strcpy(defines_file_name, file_prefix);
375 strcpy(defines_file_name + len, DEFINES_SUFFIX);
376 }
377
378 if (vflag)
379 {
380 verbose_file_name = MALLOC(len + 8);
381 if (verbose_file_name == 0)
382 no_space();
383 strcpy(verbose_file_name, file_prefix);
384 strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
385 }
386 }
387
388
open_files()389 void open_files()
390 {
391 create_file_names();
392
393 action_file = fopen(action_file_name, "w");
394 if (action_file == 0)
395 open_error(action_file_name);
396
397 text_file = fopen(text_file_name, "w");
398 if (text_file == 0)
399 open_error(text_file_name);
400
401 if (vflag)
402 {
403 verbose_file = fopen(verbose_file_name, "w");
404 if (verbose_file == 0)
405 open_error(verbose_file_name);
406 }
407
408 if (dflag)
409 {
410 defines_file = fopen(defines_file_name, "w");
411 if (defines_file == 0)
412 open_error(defines_file_name);
413 union_file = fopen(union_file_name, "w");
414 if (union_file == 0)
415 open_error(union_file_name);
416 }
417
418 output_file = fopen(output_file_name, "w");
419 if (output_file == 0)
420 open_error(output_file_name);
421
422 if (rflag)
423 {
424 code_file = fopen(code_file_name, "w");
425 if (code_file == 0)
426 open_error(code_file_name);
427 }
428 else
429 code_file = output_file;
430 }
431
432
main(int argc,char ** argv)433 int main(int argc, char **argv)
434 {
435 set_signals();
436 getargs(argc, argv);
437 open_files();
438 reader();
439 lr0();
440 lalr();
441 make_parser();
442 verbose();
443 output();
444 done(0);
445 return 0;
446 }
447