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 * 4. Neither the name of the University nor the names of its contributors 171590Srgrimes * may be used to endorse or promote products derived from this software 181590Srgrimes * without specific prior written permission. 191590Srgrimes * 201590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301590Srgrimes * SUCH DAMAGE. 311590Srgrimes */ 321590Srgrimes 3387628Sdwmalone#if 0 3487628Sdwmalone#ifndef lint 3587628Sdwmalonestatic char sccsid[] = "@(#)main.c 5.5 (Berkeley) 5/24/93"; 3687628Sdwmalone#endif 3787628Sdwmalone#endif 3887628Sdwmalone 3987234Smarkm#include <sys/cdefs.h> 4087234Smarkm__FBSDID("$FreeBSD$"); 4187234Smarkm 4293831Sobrien#include <paths.h> 431590Srgrimes#include <signal.h> 4421622Ssteve#include <stdlib.h> 4521622Ssteve#include <string.h> 4621622Ssteve#include <unistd.h> 471590Srgrimes#include "defs.h" 481590Srgrimes 491590Srgrimeschar dflag; 501590Srgrimeschar lflag; 511590Srgrimeschar rflag; 521590Srgrimeschar tflag; 531590Srgrimeschar vflag; 541590Srgrimes 5587171Smarkmconst char *symbol_prefix; 5687171Smarkmconst char *file_prefix = "y"; 5787171Smarkmchar temp_form[] = "yacc.XXXXXXXXXXX"; 581590Srgrimes 591590Srgrimesint lineno; 601590Srgrimesint outline; 611590Srgrimes 621590Srgrimeschar *action_file_name; 631590Srgrimeschar *code_file_name; 641590Srgrimeschar *defines_file_name; 6587171Smarkmconst char *input_file_name = ""; 661590Srgrimeschar *output_file_name; 671590Srgrimeschar *text_file_name; 681590Srgrimeschar *union_file_name; 691590Srgrimeschar *verbose_file_name; 701590Srgrimes 711590SrgrimesFILE *action_file; /* a temp file, used to save actions associated */ 721590Srgrimes /* with rules until the parser is written */ 731590SrgrimesFILE *code_file; /* y.code.c (used when the -r option is specified) */ 741590SrgrimesFILE *defines_file; /* y.tab.h */ 751590SrgrimesFILE *input_file; /* the input file */ 761590SrgrimesFILE *output_file; /* y.tab.c */ 771590SrgrimesFILE *text_file; /* a temp file, used to save text until all */ 781590Srgrimes /* symbols have been defined */ 791590SrgrimesFILE *union_file; /* a temp file, used to save the union */ 801590Srgrimes /* definition until all symbol have been */ 811590Srgrimes /* defined */ 821590SrgrimesFILE *verbose_file; /* y.output */ 831590Srgrimes 841590Srgrimesint nitems; 851590Srgrimesint nrules; 861590Srgrimesint nsyms; 871590Srgrimesint ntokens; 881590Srgrimesint nvars; 891590Srgrimes 901590Srgrimesint start_symbol; 911590Srgrimeschar **symbol_name; 921590Srgrimesshort *symbol_value; 931590Srgrimesshort *symbol_prec; 941590Srgrimeschar *symbol_assoc; 951590Srgrimes 961590Srgrimesshort *ritem; 971590Srgrimesshort *rlhs; 981590Srgrimesshort *rrhs; 991590Srgrimesshort *rprec; 1001590Srgrimeschar *rassoc; 1011590Srgrimesshort **derives; 1021590Srgrimeschar *nullable; 1031590Srgrimes 10492922Simpstatic void create_file_names(void); 10592922Simpstatic void getargs(int, char **); 10692922Simpstatic void onintr(int); 10792922Simpstatic void open_files(void); 10892922Simpstatic void set_signals(void); 10992922Simpstatic void usage(void); 1101590Srgrimes 11193831Sobrienvolatile sig_atomic_t sigdie; 1121590Srgrimes 11393831Sobrien__dead2 void 114214959Sobriendone(int k) 1151590Srgrimes{ 1161590Srgrimes if (action_file) { fclose(action_file); unlink(action_file_name); } 1171590Srgrimes if (text_file) { fclose(text_file); unlink(text_file_name); } 1181590Srgrimes if (union_file) { fclose(union_file); unlink(union_file_name); } 11993831Sobrien if (sigdie) { _exit(k); } 1201590Srgrimes exit(k); 1211590Srgrimes} 1221590Srgrimes 1231590Srgrimes 12421622Sstevestatic void 125214959Sobrienonintr(int signo __unused) 1261590Srgrimes{ 12793831Sobrien sigdie = 1; 1281590Srgrimes done(1); 1291590Srgrimes} 1301590Srgrimes 1311590Srgrimes 13221622Sstevestatic void 133214959Sobrienset_signals(void) 1341590Srgrimes{ 1351590Srgrimes#ifdef SIGINT 1361590Srgrimes if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1371590Srgrimes signal(SIGINT, onintr); 1381590Srgrimes#endif 1391590Srgrimes#ifdef SIGTERM 1401590Srgrimes if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 1411590Srgrimes signal(SIGTERM, onintr); 1421590Srgrimes#endif 1431590Srgrimes#ifdef SIGHUP 1441590Srgrimes if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 1451590Srgrimes signal(SIGHUP, onintr); 1461590Srgrimes#endif 1471590Srgrimes} 1481590Srgrimes 1491590Srgrimes 15021622Sstevestatic void 151214959Sobrienusage(void) 1521590Srgrimes{ 15328856Scharnier fprintf(stderr, "%s\n%s\n", 15428856Scharnier "usage: yacc [-dlrtv] [-b file_prefix] [-o output_filename]", 15528856Scharnier " [-p symbol_prefix] filename"); 1561590Srgrimes exit(1); 1571590Srgrimes} 1581590Srgrimes 1591590Srgrimes 16021622Sstevestatic void 161214959Sobriengetargs(int argc, char *argv[]) 1621590Srgrimes{ 163126623Swes int ch; 1641590Srgrimes 165214964Sobrien while ((ch = getopt(argc, argv, "b:dlo:p:rtvy")) != -1) 1661590Srgrimes { 167126623Swes switch (ch) 1681590Srgrimes { 1691590Srgrimes case 'b': 170126623Swes file_prefix = optarg; 171126623Swes break; 1721590Srgrimes 1731590Srgrimes case 'd': 1741590Srgrimes dflag = 1; 1751590Srgrimes break; 1761590Srgrimes 1771590Srgrimes case 'l': 1781590Srgrimes lflag = 1; 1791590Srgrimes break; 1801590Srgrimes 18122776Ssteve case 'o': 182126623Swes output_file_name = optarg; 183126623Swes break; 18422776Ssteve 1851590Srgrimes case 'p': 186126623Swes symbol_prefix = optarg; 187126623Swes break; 1881590Srgrimes 1891590Srgrimes case 'r': 1901590Srgrimes rflag = 1; 1911590Srgrimes break; 1921590Srgrimes 1931590Srgrimes case 't': 1941590Srgrimes tflag = 1; 1951590Srgrimes break; 1961590Srgrimes 1971590Srgrimes case 'v': 1981590Srgrimes vflag = 1; 1991590Srgrimes break; 2001590Srgrimes 201214964Sobrien case 'y': 202214964Sobrien /* for bison compatibility -- byacc is already POSIX compatible */ 203214964Sobrien break; 204214964Sobrien 2051590Srgrimes default: 2061590Srgrimes usage(); 2071590Srgrimes } 2081590Srgrimes } 2091590Srgrimes 210126623Swes if (optind + 1 != argc) 211126623Swes usage(); 212126623Swes if (strcmp(argv[optind], "-") == 0) 213126623Swes input_file = stdin; 214126623Swes else 215126623Swes input_file_name = argv[optind]; 2161590Srgrimes} 2171590Srgrimes 2181590Srgrimes 219214961Sobrienvoid * 220214961Sobrienallocate(size_t n) 2211590Srgrimes{ 222214961Sobrien void *p; 2231590Srgrimes 2241590Srgrimes p = NULL; 2251590Srgrimes if (n) 2261590Srgrimes { 227214961Sobrien p = calloc(1, n); 2281590Srgrimes if (!p) no_space(); 2291590Srgrimes } 2301590Srgrimes return (p); 2311590Srgrimes} 2321590Srgrimes 2331590Srgrimes 23421622Sstevestatic void 235214959Sobriencreate_file_names(void) 2361590Srgrimes{ 2371590Srgrimes int i, len; 23887171Smarkm const char *tmpdir; 2391590Srgrimes 24093831Sobrien if (!(tmpdir = getenv("TMPDIR"))) 24193831Sobrien tmpdir = _PATH_TMP; 2421590Srgrimes 2431590Srgrimes len = strlen(tmpdir); 24493831Sobrien i = len + strlen(temp_form) + 1; 2451590Srgrimes if (len && tmpdir[len-1] != '/') 2461590Srgrimes ++i; 2471590Srgrimes 248214961Sobrien action_file_name = malloc(i); 2491590Srgrimes if (action_file_name == 0) no_space(); 250214961Sobrien text_file_name = malloc(i); 2511590Srgrimes if (text_file_name == 0) no_space(); 252214961Sobrien union_file_name = malloc(i); 2531590Srgrimes if (union_file_name == 0) no_space(); 2541590Srgrimes 2551590Srgrimes strcpy(action_file_name, tmpdir); 2561590Srgrimes strcpy(text_file_name, tmpdir); 2571590Srgrimes strcpy(union_file_name, tmpdir); 2581590Srgrimes 2591590Srgrimes if (len && tmpdir[len - 1] != '/') 2601590Srgrimes { 2611590Srgrimes action_file_name[len] = '/'; 2621590Srgrimes text_file_name[len] = '/'; 2631590Srgrimes union_file_name[len] = '/'; 2641590Srgrimes ++len; 2651590Srgrimes } 2661590Srgrimes 2671590Srgrimes strcpy(action_file_name + len, temp_form); 2681590Srgrimes strcpy(text_file_name + len, temp_form); 2691590Srgrimes strcpy(union_file_name + len, temp_form); 2701590Srgrimes 2711590Srgrimes action_file_name[len + 5] = 'a'; 2721590Srgrimes text_file_name[len + 5] = 't'; 2731590Srgrimes union_file_name[len + 5] = 'u'; 2741590Srgrimes 27522776Ssteve if (output_file_name != 0) 27622776Ssteve { 27722776Ssteve file_prefix = output_file_name; 27822776Ssteve len = strlen(file_prefix); 27922776Ssteve } 28022776Ssteve else 28122776Ssteve { 28222776Ssteve len = strlen(file_prefix); 283214961Sobrien output_file_name = malloc(len + 7); 28422776Ssteve if (output_file_name == 0) 28522776Ssteve no_space(); 28622776Ssteve strcpy(output_file_name, file_prefix); 28722776Ssteve strcpy(output_file_name + len, OUTPUT_SUFFIX); 28822776Ssteve } 2891590Srgrimes 2901590Srgrimes if (rflag) 2911590Srgrimes { 292214961Sobrien code_file_name = malloc(len + 8); 2931590Srgrimes if (code_file_name == 0) 2941590Srgrimes no_space(); 2951590Srgrimes strcpy(code_file_name, file_prefix); 29622776Ssteve if (file_prefix == output_file_name) 29722776Ssteve { 29822776Ssteve /* 29922776Ssteve * XXX ".tab.c" here is OUTPUT_SUFFIX, but since its length is 30022776Ssteve * in various magic numbers, don't bother using the macro. 30122776Ssteve */ 30222776Ssteve if (len >= 6 && strcmp(code_file_name + len - 6, ".tab.c") == 0) 30322776Ssteve strcpy(code_file_name + len - 6, CODE_SUFFIX); 30422776Ssteve else if (len >= 2 && strcmp(code_file_name + len - 2, ".c") == 0) 30522776Ssteve strcpy(code_file_name + len - 2, CODE_SUFFIX); 30622776Ssteve else 30722776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 30822776Ssteve } 30922776Ssteve else 31022776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 3111590Srgrimes } 3121590Srgrimes else 3131590Srgrimes code_file_name = output_file_name; 3141590Srgrimes 3151590Srgrimes if (dflag) 3161590Srgrimes { 317214961Sobrien defines_file_name = malloc(len + 7); 3181590Srgrimes if (defines_file_name == 0) 3191590Srgrimes no_space(); 3201590Srgrimes strcpy(defines_file_name, file_prefix); 32122776Ssteve if (file_prefix == output_file_name) 32222776Ssteve { 32322776Ssteve#define BISON_DEFINES_SUFFIX ".h" 32422776Ssteve if (len >= 2 && strcmp(defines_file_name + len - 2, ".c") == 0) 32522776Ssteve strcpy(defines_file_name + len - 2, BISON_DEFINES_SUFFIX); 32622776Ssteve else 32722776Ssteve strcpy(defines_file_name + len, BISON_DEFINES_SUFFIX); 32822776Ssteve } 32922776Ssteve else 33022776Ssteve strcpy(defines_file_name + len, DEFINES_SUFFIX); 3311590Srgrimes } 3321590Srgrimes 3331590Srgrimes if (vflag) 3341590Srgrimes { 335214961Sobrien verbose_file_name = malloc(len + 8); 3361590Srgrimes if (verbose_file_name == 0) 3371590Srgrimes no_space(); 3381590Srgrimes strcpy(verbose_file_name, file_prefix); 33922776Ssteve if (file_prefix == output_file_name) 34022776Ssteve { 34122776Ssteve if (len >= 6 && strcmp(verbose_file_name + len - 6, ".tab.c") == 0) 34222776Ssteve strcpy(verbose_file_name + len - 6, VERBOSE_SUFFIX); 34322776Ssteve else if (len >= 2 && strcmp(verbose_file_name + len - 2, ".c") == 0) 34422776Ssteve strcpy(verbose_file_name + len - 2, VERBOSE_SUFFIX); 34522776Ssteve else 34622776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 34722776Ssteve } 34822776Ssteve else 34922776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 3501590Srgrimes } 3511590Srgrimes} 3521590Srgrimes 3531590Srgrimes 35421622Sstevestatic void 355214959Sobrienopen_files(void) 3561590Srgrimes{ 35736790Simp int fd; 35836790Simp 3591590Srgrimes create_file_names(); 3601590Srgrimes 3611590Srgrimes if (input_file == 0) 3621590Srgrimes { 3631590Srgrimes input_file = fopen(input_file_name, "r"); 3641590Srgrimes if (input_file == 0) 3651590Srgrimes open_error(input_file_name); 3661590Srgrimes } 3671590Srgrimes 36836790Simp fd = mkstemp(action_file_name); 36936790Simp if (fd < 0 || (action_file = fdopen(fd, "w")) == NULL) { 37036790Simp if (fd >= 0) 37136790Simp close(fd); 3721590Srgrimes open_error(action_file_name); 37336790Simp } 37436790Simp fd = mkstemp(text_file_name); 37536790Simp if (fd < 0 || (text_file = fdopen(fd, "w")) == NULL) { 37636790Simp if (fd >= 0) 37736790Simp close(fd); 37836790Simp open_error(text_file_name); 37936790Simp } 38036790Simp fd = mkstemp(union_file_name); 38136790Simp if (fd < 0 || (union_file = fdopen(fd, "w")) == NULL) { 38236790Simp if (fd >= 0) 38336790Simp close(fd); 38436790Simp open_error(union_file_name); 38536790Simp } 3861590Srgrimes 3871590Srgrimes text_file = fopen(text_file_name, "w"); 3881590Srgrimes if (text_file == 0) 3891590Srgrimes open_error(text_file_name); 3901590Srgrimes 3911590Srgrimes if (vflag) 3921590Srgrimes { 3931590Srgrimes verbose_file = fopen(verbose_file_name, "w"); 3941590Srgrimes if (verbose_file == 0) 3951590Srgrimes open_error(verbose_file_name); 3961590Srgrimes } 3971590Srgrimes 3981590Srgrimes if (dflag) 3991590Srgrimes { 4001590Srgrimes defines_file = fopen(defines_file_name, "w"); 4011590Srgrimes if (defines_file == 0) 4021590Srgrimes open_error(defines_file_name); 4031590Srgrimes union_file = fopen(union_file_name, "w"); 4041590Srgrimes if (union_file == 0) 4051590Srgrimes open_error(union_file_name); 4061590Srgrimes } 4071590Srgrimes 4081590Srgrimes output_file = fopen(output_file_name, "w"); 4091590Srgrimes if (output_file == 0) 4101590Srgrimes open_error(output_file_name); 4111590Srgrimes 4121590Srgrimes if (rflag) 4131590Srgrimes { 4141590Srgrimes code_file = fopen(code_file_name, "w"); 4151590Srgrimes if (code_file == 0) 4161590Srgrimes open_error(code_file_name); 4171590Srgrimes } 4181590Srgrimes else 4191590Srgrimes code_file = output_file; 4201590Srgrimes} 4211590Srgrimes 4221590Srgrimes 4231590Srgrimesint 42493832Sobrienmain(int argc, char *argv[]) 4251590Srgrimes{ 4261590Srgrimes set_signals(); 4271590Srgrimes getargs(argc, argv); 4281590Srgrimes open_files(); 4291590Srgrimes reader(); 4301590Srgrimes lr0(); 4311590Srgrimes lalr(); 4321590Srgrimes make_parser(); 4331590Srgrimes verbose(); 4341590Srgrimes output(); 4351590Srgrimes done(0); 4361590Srgrimes /*NOTREACHED*/ 43721622Ssteve return (0); 4381590Srgrimes} 439