main.c revision 93831
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1989 The Regents of the University of California. 31590Srgrimes * All rights reserved. 41590Srgrimes * 51590Srgrimes * This code is derived from software contributed to Berkeley by 61590Srgrimes * Robert Paul Corbett. 71590Srgrimes * 81590Srgrimes * Redistribution and use in source and binary forms, with or without 91590Srgrimes * modification, are permitted provided that the following conditions 101590Srgrimes * are met: 111590Srgrimes * 1. Redistributions of source code must retain the above copyright 121590Srgrimes * notice, this list of conditions and the following disclaimer. 131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer in the 151590Srgrimes * documentation and/or other materials provided with the distribution. 161590Srgrimes * 3. All advertising materials mentioning features or use of this software 171590Srgrimes * must display the following acknowledgement: 181590Srgrimes * This product includes software developed by the University of 191590Srgrimes * California, Berkeley and its contributors. 201590Srgrimes * 4. Neither the name of the University nor the names of its contributors 211590Srgrimes * may be used to endorse or promote products derived from this software 221590Srgrimes * without specific prior written permission. 231590Srgrimes * 241590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341590Srgrimes * SUCH DAMAGE. 351590Srgrimes */ 361590Srgrimes 3787628Sdwmalone#if 0 3887628Sdwmalone#ifndef lint 3987628Sdwmalonestatic char sccsid[] = "@(#)main.c 5.5 (Berkeley) 5/24/93"; 4087628Sdwmalone#endif 4187628Sdwmalone#endif 4287628Sdwmalone 4387234Smarkm#include <sys/cdefs.h> 4487517Simp#ifdef __FBSDID 4587234Smarkm__FBSDID("$FreeBSD: head/usr.bin/yacc/main.c 93831 2002-04-04 22:15:13Z obrien $"); 4687517Simp#endif 4787234Smarkm 4893831Sobrien#include <paths.h> 491590Srgrimes#include <signal.h> 5021622Ssteve#include <stdlib.h> 5121622Ssteve#include <string.h> 5221622Ssteve#include <unistd.h> 531590Srgrimes#include "defs.h" 541590Srgrimes 551590Srgrimeschar dflag; 561590Srgrimeschar lflag; 571590Srgrimeschar rflag; 581590Srgrimeschar tflag; 591590Srgrimeschar vflag; 601590Srgrimes 6187171Smarkmconst char *symbol_prefix; 6287171Smarkmconst char *file_prefix = "y"; 6387171Smarkmchar temp_form[] = "yacc.XXXXXXXXXXX"; 641590Srgrimes 651590Srgrimesint lineno; 661590Srgrimesint outline; 671590Srgrimes 681590Srgrimeschar *action_file_name; 691590Srgrimeschar *code_file_name; 701590Srgrimeschar *defines_file_name; 7187171Smarkmconst char *input_file_name = ""; 721590Srgrimeschar *output_file_name; 731590Srgrimeschar *text_file_name; 741590Srgrimeschar *union_file_name; 751590Srgrimeschar *verbose_file_name; 761590Srgrimes 771590SrgrimesFILE *action_file; /* a temp file, used to save actions associated */ 781590Srgrimes /* with rules until the parser is written */ 791590SrgrimesFILE *code_file; /* y.code.c (used when the -r option is specified) */ 801590SrgrimesFILE *defines_file; /* y.tab.h */ 811590SrgrimesFILE *input_file; /* the input file */ 821590SrgrimesFILE *output_file; /* y.tab.c */ 831590SrgrimesFILE *text_file; /* a temp file, used to save text until all */ 841590Srgrimes /* symbols have been defined */ 851590SrgrimesFILE *union_file; /* a temp file, used to save the union */ 861590Srgrimes /* definition until all symbol have been */ 871590Srgrimes /* defined */ 881590SrgrimesFILE *verbose_file; /* y.output */ 891590Srgrimes 901590Srgrimesint nitems; 911590Srgrimesint nrules; 921590Srgrimesint nsyms; 931590Srgrimesint ntokens; 941590Srgrimesint nvars; 951590Srgrimes 961590Srgrimesint start_symbol; 971590Srgrimeschar **symbol_name; 981590Srgrimesshort *symbol_value; 991590Srgrimesshort *symbol_prec; 1001590Srgrimeschar *symbol_assoc; 1011590Srgrimes 1021590Srgrimesshort *ritem; 1031590Srgrimesshort *rlhs; 1041590Srgrimesshort *rrhs; 1051590Srgrimesshort *rprec; 1061590Srgrimeschar *rassoc; 1071590Srgrimesshort **derives; 1081590Srgrimeschar *nullable; 1091590Srgrimes 11092922Simpstatic void create_file_names(void); 11192922Simpstatic void getargs(int, char **); 11292922Simpstatic void onintr(int); 11392922Simpstatic void open_files(void); 11492922Simpstatic void set_signals(void); 11592922Simpstatic void usage(void); 1161590Srgrimes 11793831Sobrienvolatile sig_atomic_t sigdie; 1181590Srgrimes 11993831Sobrien__dead2 void 1201590Srgrimesdone(k) 1211590Srgrimesint k; 1221590Srgrimes{ 1231590Srgrimes if (action_file) { fclose(action_file); unlink(action_file_name); } 1241590Srgrimes if (text_file) { fclose(text_file); unlink(text_file_name); } 1251590Srgrimes if (union_file) { fclose(union_file); unlink(union_file_name); } 12693831Sobrien if (sigdie) { _exit(k); } 1271590Srgrimes exit(k); 1281590Srgrimes} 1291590Srgrimes 1301590Srgrimes 13121622Sstevestatic void 1321590Srgrimesonintr(signo) 13387171Smarkm int signo __unused; 1341590Srgrimes{ 13593831Sobrien sigdie = 1; 1361590Srgrimes done(1); 1371590Srgrimes} 1381590Srgrimes 1391590Srgrimes 14021622Sstevestatic void 1411590Srgrimesset_signals() 1421590Srgrimes{ 1431590Srgrimes#ifdef SIGINT 1441590Srgrimes if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1451590Srgrimes signal(SIGINT, onintr); 1461590Srgrimes#endif 1471590Srgrimes#ifdef SIGTERM 1481590Srgrimes if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 1491590Srgrimes signal(SIGTERM, onintr); 1501590Srgrimes#endif 1511590Srgrimes#ifdef SIGHUP 1521590Srgrimes if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 1531590Srgrimes signal(SIGHUP, onintr); 1541590Srgrimes#endif 1551590Srgrimes} 1561590Srgrimes 1571590Srgrimes 15821622Sstevestatic void 1591590Srgrimesusage() 1601590Srgrimes{ 16128856Scharnier fprintf(stderr, "%s\n%s\n", 16228856Scharnier "usage: yacc [-dlrtv] [-b file_prefix] [-o output_filename]", 16328856Scharnier " [-p symbol_prefix] filename"); 1641590Srgrimes exit(1); 1651590Srgrimes} 1661590Srgrimes 1671590Srgrimes 16821622Sstevestatic void 1691590Srgrimesgetargs(argc, argv) 1701590Srgrimesint argc; 1711590Srgrimeschar *argv[]; 1721590Srgrimes{ 17387171Smarkm int i; 17487171Smarkm char *s; 1751590Srgrimes 1761590Srgrimes for (i = 1; i < argc; ++i) 1771590Srgrimes { 1781590Srgrimes s = argv[i]; 1791590Srgrimes if (*s != '-') break; 1801590Srgrimes switch (*++s) 1811590Srgrimes { 1821590Srgrimes case '\0': 1831590Srgrimes input_file = stdin; 1841590Srgrimes if (i + 1 < argc) usage(); 1851590Srgrimes return; 1861590Srgrimes 1871590Srgrimes case '-': 1881590Srgrimes ++i; 1891590Srgrimes goto no_more_options; 1901590Srgrimes 1911590Srgrimes case 'b': 1921590Srgrimes if (*++s) 1931590Srgrimes file_prefix = s; 1941590Srgrimes else if (++i < argc) 1951590Srgrimes file_prefix = argv[i]; 1961590Srgrimes else 1971590Srgrimes usage(); 1981590Srgrimes continue; 1991590Srgrimes 2001590Srgrimes case 'd': 2011590Srgrimes dflag = 1; 2021590Srgrimes break; 2031590Srgrimes 2041590Srgrimes case 'l': 2051590Srgrimes lflag = 1; 2061590Srgrimes break; 2071590Srgrimes 20822776Ssteve case 'o': 20922776Ssteve if (*++s) 21022776Ssteve output_file_name = s; 21122776Ssteve else if (++i < argc) 21222776Ssteve output_file_name = argv[i]; 21322776Ssteve else 21422776Ssteve usage(); 21522776Ssteve continue; 21622776Ssteve 2171590Srgrimes case 'p': 2181590Srgrimes if (*++s) 2191590Srgrimes symbol_prefix = s; 2201590Srgrimes else if (++i < argc) 2211590Srgrimes symbol_prefix = argv[i]; 2221590Srgrimes else 2231590Srgrimes usage(); 2241590Srgrimes continue; 2251590Srgrimes 2261590Srgrimes case 'r': 2271590Srgrimes rflag = 1; 2281590Srgrimes break; 2291590Srgrimes 2301590Srgrimes case 't': 2311590Srgrimes tflag = 1; 2321590Srgrimes break; 2331590Srgrimes 2341590Srgrimes case 'v': 2351590Srgrimes vflag = 1; 2361590Srgrimes break; 2371590Srgrimes 2381590Srgrimes default: 2391590Srgrimes usage(); 2401590Srgrimes } 2411590Srgrimes 2421590Srgrimes for (;;) 2431590Srgrimes { 2441590Srgrimes switch (*++s) 2451590Srgrimes { 2461590Srgrimes case '\0': 2471590Srgrimes goto end_of_option; 2481590Srgrimes 2491590Srgrimes case 'd': 2501590Srgrimes dflag = 1; 2511590Srgrimes break; 2521590Srgrimes 2531590Srgrimes case 'l': 2541590Srgrimes lflag = 1; 2551590Srgrimes break; 2561590Srgrimes 2571590Srgrimes case 'r': 2581590Srgrimes rflag = 1; 2591590Srgrimes break; 2601590Srgrimes 2611590Srgrimes case 't': 2621590Srgrimes tflag = 1; 2631590Srgrimes break; 2641590Srgrimes 2651590Srgrimes case 'v': 2661590Srgrimes vflag = 1; 2671590Srgrimes break; 2681590Srgrimes 2691590Srgrimes default: 2701590Srgrimes usage(); 2711590Srgrimes } 2721590Srgrimes } 2731590Srgrimesend_of_option:; 2741590Srgrimes } 2751590Srgrimes 2761590Srgrimesno_more_options:; 2771590Srgrimes if (i + 1 != argc) usage(); 2781590Srgrimes input_file_name = argv[i]; 2791590Srgrimes} 2801590Srgrimes 2811590Srgrimes 2821590Srgrimeschar * 2831590Srgrimesallocate(n) 2841590Srgrimesunsigned n; 2851590Srgrimes{ 28687171Smarkm char *p; 2871590Srgrimes 2881590Srgrimes p = NULL; 2891590Srgrimes if (n) 2901590Srgrimes { 2911590Srgrimes p = CALLOC(1, n); 2921590Srgrimes if (!p) no_space(); 2931590Srgrimes } 2941590Srgrimes return (p); 2951590Srgrimes} 2961590Srgrimes 2971590Srgrimes 29821622Sstevestatic void 2991590Srgrimescreate_file_names() 3001590Srgrimes{ 3011590Srgrimes int i, len; 30287171Smarkm const char *tmpdir; 3031590Srgrimes 30493831Sobrien if (!(tmpdir = getenv("TMPDIR"))) 30593831Sobrien tmpdir = _PATH_TMP; 3061590Srgrimes 3071590Srgrimes len = strlen(tmpdir); 30893831Sobrien i = len + strlen(temp_form) + 1; 3091590Srgrimes if (len && tmpdir[len-1] != '/') 3101590Srgrimes ++i; 3111590Srgrimes 3121590Srgrimes action_file_name = MALLOC(i); 3131590Srgrimes if (action_file_name == 0) no_space(); 3141590Srgrimes text_file_name = MALLOC(i); 3151590Srgrimes if (text_file_name == 0) no_space(); 3161590Srgrimes union_file_name = MALLOC(i); 3171590Srgrimes if (union_file_name == 0) no_space(); 3181590Srgrimes 3191590Srgrimes strcpy(action_file_name, tmpdir); 3201590Srgrimes strcpy(text_file_name, tmpdir); 3211590Srgrimes strcpy(union_file_name, tmpdir); 3221590Srgrimes 3231590Srgrimes if (len && tmpdir[len - 1] != '/') 3241590Srgrimes { 3251590Srgrimes action_file_name[len] = '/'; 3261590Srgrimes text_file_name[len] = '/'; 3271590Srgrimes union_file_name[len] = '/'; 3281590Srgrimes ++len; 3291590Srgrimes } 3301590Srgrimes 3311590Srgrimes strcpy(action_file_name + len, temp_form); 3321590Srgrimes strcpy(text_file_name + len, temp_form); 3331590Srgrimes strcpy(union_file_name + len, temp_form); 3341590Srgrimes 3351590Srgrimes action_file_name[len + 5] = 'a'; 3361590Srgrimes text_file_name[len + 5] = 't'; 3371590Srgrimes union_file_name[len + 5] = 'u'; 3381590Srgrimes 33922776Ssteve if (output_file_name != 0) 34022776Ssteve { 34122776Ssteve file_prefix = output_file_name; 34222776Ssteve len = strlen(file_prefix); 34322776Ssteve } 34422776Ssteve else 34522776Ssteve { 34622776Ssteve len = strlen(file_prefix); 34722776Ssteve output_file_name = MALLOC(len + 7); 34822776Ssteve if (output_file_name == 0) 34922776Ssteve no_space(); 35022776Ssteve strcpy(output_file_name, file_prefix); 35122776Ssteve strcpy(output_file_name + len, OUTPUT_SUFFIX); 35222776Ssteve } 3531590Srgrimes 3541590Srgrimes if (rflag) 3551590Srgrimes { 3561590Srgrimes code_file_name = MALLOC(len + 8); 3571590Srgrimes if (code_file_name == 0) 3581590Srgrimes no_space(); 3591590Srgrimes strcpy(code_file_name, file_prefix); 36022776Ssteve if (file_prefix == output_file_name) 36122776Ssteve { 36222776Ssteve /* 36322776Ssteve * XXX ".tab.c" here is OUTPUT_SUFFIX, but since its length is 36422776Ssteve * in various magic numbers, don't bother using the macro. 36522776Ssteve */ 36622776Ssteve if (len >= 6 && strcmp(code_file_name + len - 6, ".tab.c") == 0) 36722776Ssteve strcpy(code_file_name + len - 6, CODE_SUFFIX); 36822776Ssteve else if (len >= 2 && strcmp(code_file_name + len - 2, ".c") == 0) 36922776Ssteve strcpy(code_file_name + len - 2, CODE_SUFFIX); 37022776Ssteve else 37122776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 37222776Ssteve } 37322776Ssteve else 37422776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 3751590Srgrimes } 3761590Srgrimes else 3771590Srgrimes code_file_name = output_file_name; 3781590Srgrimes 3791590Srgrimes if (dflag) 3801590Srgrimes { 3811590Srgrimes defines_file_name = MALLOC(len + 7); 3821590Srgrimes if (defines_file_name == 0) 3831590Srgrimes no_space(); 3841590Srgrimes strcpy(defines_file_name, file_prefix); 38522776Ssteve if (file_prefix == output_file_name) 38622776Ssteve { 38722776Ssteve#define BISON_DEFINES_SUFFIX ".h" 38822776Ssteve if (len >= 2 && strcmp(defines_file_name + len - 2, ".c") == 0) 38922776Ssteve strcpy(defines_file_name + len - 2, BISON_DEFINES_SUFFIX); 39022776Ssteve else 39122776Ssteve strcpy(defines_file_name + len, BISON_DEFINES_SUFFIX); 39222776Ssteve } 39322776Ssteve else 39422776Ssteve strcpy(defines_file_name + len, DEFINES_SUFFIX); 3951590Srgrimes } 3961590Srgrimes 3971590Srgrimes if (vflag) 3981590Srgrimes { 3991590Srgrimes verbose_file_name = MALLOC(len + 8); 4001590Srgrimes if (verbose_file_name == 0) 4011590Srgrimes no_space(); 4021590Srgrimes strcpy(verbose_file_name, file_prefix); 40322776Ssteve if (file_prefix == output_file_name) 40422776Ssteve { 40522776Ssteve if (len >= 6 && strcmp(verbose_file_name + len - 6, ".tab.c") == 0) 40622776Ssteve strcpy(verbose_file_name + len - 6, VERBOSE_SUFFIX); 40722776Ssteve else if (len >= 2 && strcmp(verbose_file_name + len - 2, ".c") == 0) 40822776Ssteve strcpy(verbose_file_name + len - 2, VERBOSE_SUFFIX); 40922776Ssteve else 41022776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 41122776Ssteve } 41222776Ssteve else 41322776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 4141590Srgrimes } 4151590Srgrimes} 4161590Srgrimes 4171590Srgrimes 41821622Sstevestatic void 4191590Srgrimesopen_files() 4201590Srgrimes{ 42136790Simp int fd; 42236790Simp 4231590Srgrimes create_file_names(); 4241590Srgrimes 4251590Srgrimes if (input_file == 0) 4261590Srgrimes { 4271590Srgrimes input_file = fopen(input_file_name, "r"); 4281590Srgrimes if (input_file == 0) 4291590Srgrimes open_error(input_file_name); 4301590Srgrimes } 4311590Srgrimes 43236790Simp fd = mkstemp(action_file_name); 43336790Simp if (fd < 0 || (action_file = fdopen(fd, "w")) == NULL) { 43436790Simp if (fd >= 0) 43536790Simp close(fd); 4361590Srgrimes open_error(action_file_name); 43736790Simp } 43836790Simp fd = mkstemp(text_file_name); 43936790Simp if (fd < 0 || (text_file = fdopen(fd, "w")) == NULL) { 44036790Simp if (fd >= 0) 44136790Simp close(fd); 44236790Simp open_error(text_file_name); 44336790Simp } 44436790Simp fd = mkstemp(union_file_name); 44536790Simp if (fd < 0 || (union_file = fdopen(fd, "w")) == NULL) { 44636790Simp if (fd >= 0) 44736790Simp close(fd); 44836790Simp open_error(union_file_name); 44936790Simp } 4501590Srgrimes 4511590Srgrimes text_file = fopen(text_file_name, "w"); 4521590Srgrimes if (text_file == 0) 4531590Srgrimes open_error(text_file_name); 4541590Srgrimes 4551590Srgrimes if (vflag) 4561590Srgrimes { 4571590Srgrimes verbose_file = fopen(verbose_file_name, "w"); 4581590Srgrimes if (verbose_file == 0) 4591590Srgrimes open_error(verbose_file_name); 4601590Srgrimes } 4611590Srgrimes 4621590Srgrimes if (dflag) 4631590Srgrimes { 4641590Srgrimes defines_file = fopen(defines_file_name, "w"); 4651590Srgrimes if (defines_file == 0) 4661590Srgrimes open_error(defines_file_name); 4671590Srgrimes union_file = fopen(union_file_name, "w"); 4681590Srgrimes if (union_file == 0) 4691590Srgrimes open_error(union_file_name); 4701590Srgrimes } 4711590Srgrimes 4721590Srgrimes output_file = fopen(output_file_name, "w"); 4731590Srgrimes if (output_file == 0) 4741590Srgrimes open_error(output_file_name); 4751590Srgrimes 4761590Srgrimes if (rflag) 4771590Srgrimes { 4781590Srgrimes code_file = fopen(code_file_name, "w"); 4791590Srgrimes if (code_file == 0) 4801590Srgrimes open_error(code_file_name); 4811590Srgrimes } 4821590Srgrimes else 4831590Srgrimes code_file = output_file; 4841590Srgrimes} 4851590Srgrimes 4861590Srgrimes 4871590Srgrimesint 4881590Srgrimesmain(argc, argv) 4891590Srgrimesint argc; 4901590Srgrimeschar *argv[]; 4911590Srgrimes{ 4921590Srgrimes set_signals(); 4931590Srgrimes getargs(argc, argv); 4941590Srgrimes open_files(); 4951590Srgrimes reader(); 4961590Srgrimes lr0(); 4971590Srgrimes lalr(); 4981590Srgrimes make_parser(); 4991590Srgrimes verbose(); 5001590Srgrimes output(); 5011590Srgrimes done(0); 5021590Srgrimes /*NOTREACHED*/ 50321622Ssteve return (0); 5041590Srgrimes} 505