main.c revision 126623
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> 4487234Smarkm__FBSDID("$FreeBSD: head/usr.bin/yacc/main.c 126623 2004-03-05 01:52:09Z wes $"); 4587234Smarkm 4693831Sobrien#include <paths.h> 471590Srgrimes#include <signal.h> 4821622Ssteve#include <stdlib.h> 4921622Ssteve#include <string.h> 5021622Ssteve#include <unistd.h> 511590Srgrimes#include "defs.h" 521590Srgrimes 531590Srgrimeschar dflag; 541590Srgrimeschar lflag; 551590Srgrimeschar rflag; 561590Srgrimeschar tflag; 571590Srgrimeschar vflag; 581590Srgrimes 5987171Smarkmconst char *symbol_prefix; 6087171Smarkmconst char *file_prefix = "y"; 6187171Smarkmchar temp_form[] = "yacc.XXXXXXXXXXX"; 621590Srgrimes 631590Srgrimesint lineno; 641590Srgrimesint outline; 651590Srgrimes 661590Srgrimeschar *action_file_name; 671590Srgrimeschar *code_file_name; 681590Srgrimeschar *defines_file_name; 6987171Smarkmconst char *input_file_name = ""; 701590Srgrimeschar *output_file_name; 711590Srgrimeschar *text_file_name; 721590Srgrimeschar *union_file_name; 731590Srgrimeschar *verbose_file_name; 741590Srgrimes 751590SrgrimesFILE *action_file; /* a temp file, used to save actions associated */ 761590Srgrimes /* with rules until the parser is written */ 771590SrgrimesFILE *code_file; /* y.code.c (used when the -r option is specified) */ 781590SrgrimesFILE *defines_file; /* y.tab.h */ 791590SrgrimesFILE *input_file; /* the input file */ 801590SrgrimesFILE *output_file; /* y.tab.c */ 811590SrgrimesFILE *text_file; /* a temp file, used to save text until all */ 821590Srgrimes /* symbols have been defined */ 831590SrgrimesFILE *union_file; /* a temp file, used to save the union */ 841590Srgrimes /* definition until all symbol have been */ 851590Srgrimes /* defined */ 861590SrgrimesFILE *verbose_file; /* y.output */ 871590Srgrimes 881590Srgrimesint nitems; 891590Srgrimesint nrules; 901590Srgrimesint nsyms; 911590Srgrimesint ntokens; 921590Srgrimesint nvars; 931590Srgrimes 941590Srgrimesint start_symbol; 951590Srgrimeschar **symbol_name; 961590Srgrimesshort *symbol_value; 971590Srgrimesshort *symbol_prec; 981590Srgrimeschar *symbol_assoc; 991590Srgrimes 1001590Srgrimesshort *ritem; 1011590Srgrimesshort *rlhs; 1021590Srgrimesshort *rrhs; 1031590Srgrimesshort *rprec; 1041590Srgrimeschar *rassoc; 1051590Srgrimesshort **derives; 1061590Srgrimeschar *nullable; 1071590Srgrimes 10892922Simpstatic void create_file_names(void); 10992922Simpstatic void getargs(int, char **); 11092922Simpstatic void onintr(int); 11192922Simpstatic void open_files(void); 11292922Simpstatic void set_signals(void); 11392922Simpstatic void usage(void); 1141590Srgrimes 11593831Sobrienvolatile sig_atomic_t sigdie; 1161590Srgrimes 11793831Sobrien__dead2 void 1181590Srgrimesdone(k) 1191590Srgrimesint k; 1201590Srgrimes{ 1211590Srgrimes if (action_file) { fclose(action_file); unlink(action_file_name); } 1221590Srgrimes if (text_file) { fclose(text_file); unlink(text_file_name); } 1231590Srgrimes if (union_file) { fclose(union_file); unlink(union_file_name); } 12493831Sobrien if (sigdie) { _exit(k); } 1251590Srgrimes exit(k); 1261590Srgrimes} 1271590Srgrimes 1281590Srgrimes 12921622Sstevestatic void 1301590Srgrimesonintr(signo) 13187171Smarkm int signo __unused; 1321590Srgrimes{ 13393831Sobrien sigdie = 1; 1341590Srgrimes done(1); 1351590Srgrimes} 1361590Srgrimes 1371590Srgrimes 13821622Sstevestatic void 1391590Srgrimesset_signals() 1401590Srgrimes{ 1411590Srgrimes#ifdef SIGINT 1421590Srgrimes if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1431590Srgrimes signal(SIGINT, onintr); 1441590Srgrimes#endif 1451590Srgrimes#ifdef SIGTERM 1461590Srgrimes if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 1471590Srgrimes signal(SIGTERM, onintr); 1481590Srgrimes#endif 1491590Srgrimes#ifdef SIGHUP 1501590Srgrimes if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 1511590Srgrimes signal(SIGHUP, onintr); 1521590Srgrimes#endif 1531590Srgrimes} 1541590Srgrimes 1551590Srgrimes 15621622Sstevestatic void 1571590Srgrimesusage() 1581590Srgrimes{ 15928856Scharnier fprintf(stderr, "%s\n%s\n", 16028856Scharnier "usage: yacc [-dlrtv] [-b file_prefix] [-o output_filename]", 16128856Scharnier " [-p symbol_prefix] filename"); 1621590Srgrimes exit(1); 1631590Srgrimes} 1641590Srgrimes 1651590Srgrimes 16621622Sstevestatic void 1671590Srgrimesgetargs(argc, argv) 1681590Srgrimesint argc; 1691590Srgrimeschar *argv[]; 1701590Srgrimes{ 171126623Swes int ch; 1721590Srgrimes 173126623Swes while ((ch = getopt(argc, argv, "b:dlo:p:rtv")) != -1) 1741590Srgrimes { 175126623Swes switch (ch) 1761590Srgrimes { 1771590Srgrimes case 'b': 178126623Swes file_prefix = optarg; 179126623Swes break; 1801590Srgrimes 1811590Srgrimes case 'd': 1821590Srgrimes dflag = 1; 1831590Srgrimes break; 1841590Srgrimes 1851590Srgrimes case 'l': 1861590Srgrimes lflag = 1; 1871590Srgrimes break; 1881590Srgrimes 18922776Ssteve case 'o': 190126623Swes output_file_name = optarg; 191126623Swes break; 19222776Ssteve 1931590Srgrimes case 'p': 194126623Swes symbol_prefix = optarg; 195126623Swes break; 1961590Srgrimes 1971590Srgrimes case 'r': 1981590Srgrimes rflag = 1; 1991590Srgrimes break; 2001590Srgrimes 2011590Srgrimes case 't': 2021590Srgrimes tflag = 1; 2031590Srgrimes break; 2041590Srgrimes 2051590Srgrimes case 'v': 2061590Srgrimes vflag = 1; 2071590Srgrimes break; 2081590Srgrimes 2091590Srgrimes default: 2101590Srgrimes usage(); 2111590Srgrimes } 2121590Srgrimes } 2131590Srgrimes 214126623Swes if (optind + 1 != argc) 215126623Swes usage(); 216126623Swes if (strcmp(argv[optind], "-") == 0) 217126623Swes input_file = stdin; 218126623Swes else 219126623Swes input_file_name = argv[optind]; 2201590Srgrimes} 2211590Srgrimes 2221590Srgrimes 2231590Srgrimeschar * 2241590Srgrimesallocate(n) 2251590Srgrimesunsigned n; 2261590Srgrimes{ 22787171Smarkm char *p; 2281590Srgrimes 2291590Srgrimes p = NULL; 2301590Srgrimes if (n) 2311590Srgrimes { 2321590Srgrimes p = CALLOC(1, n); 2331590Srgrimes if (!p) no_space(); 2341590Srgrimes } 2351590Srgrimes return (p); 2361590Srgrimes} 2371590Srgrimes 2381590Srgrimes 23921622Sstevestatic void 2401590Srgrimescreate_file_names() 2411590Srgrimes{ 2421590Srgrimes int i, len; 24387171Smarkm const char *tmpdir; 2441590Srgrimes 24593831Sobrien if (!(tmpdir = getenv("TMPDIR"))) 24693831Sobrien tmpdir = _PATH_TMP; 2471590Srgrimes 2481590Srgrimes len = strlen(tmpdir); 24993831Sobrien i = len + strlen(temp_form) + 1; 2501590Srgrimes if (len && tmpdir[len-1] != '/') 2511590Srgrimes ++i; 2521590Srgrimes 2531590Srgrimes action_file_name = MALLOC(i); 2541590Srgrimes if (action_file_name == 0) no_space(); 2551590Srgrimes text_file_name = MALLOC(i); 2561590Srgrimes if (text_file_name == 0) no_space(); 2571590Srgrimes union_file_name = MALLOC(i); 2581590Srgrimes if (union_file_name == 0) no_space(); 2591590Srgrimes 2601590Srgrimes strcpy(action_file_name, tmpdir); 2611590Srgrimes strcpy(text_file_name, tmpdir); 2621590Srgrimes strcpy(union_file_name, tmpdir); 2631590Srgrimes 2641590Srgrimes if (len && tmpdir[len - 1] != '/') 2651590Srgrimes { 2661590Srgrimes action_file_name[len] = '/'; 2671590Srgrimes text_file_name[len] = '/'; 2681590Srgrimes union_file_name[len] = '/'; 2691590Srgrimes ++len; 2701590Srgrimes } 2711590Srgrimes 2721590Srgrimes strcpy(action_file_name + len, temp_form); 2731590Srgrimes strcpy(text_file_name + len, temp_form); 2741590Srgrimes strcpy(union_file_name + len, temp_form); 2751590Srgrimes 2761590Srgrimes action_file_name[len + 5] = 'a'; 2771590Srgrimes text_file_name[len + 5] = 't'; 2781590Srgrimes union_file_name[len + 5] = 'u'; 2791590Srgrimes 28022776Ssteve if (output_file_name != 0) 28122776Ssteve { 28222776Ssteve file_prefix = output_file_name; 28322776Ssteve len = strlen(file_prefix); 28422776Ssteve } 28522776Ssteve else 28622776Ssteve { 28722776Ssteve len = strlen(file_prefix); 28822776Ssteve output_file_name = MALLOC(len + 7); 28922776Ssteve if (output_file_name == 0) 29022776Ssteve no_space(); 29122776Ssteve strcpy(output_file_name, file_prefix); 29222776Ssteve strcpy(output_file_name + len, OUTPUT_SUFFIX); 29322776Ssteve } 2941590Srgrimes 2951590Srgrimes if (rflag) 2961590Srgrimes { 2971590Srgrimes code_file_name = MALLOC(len + 8); 2981590Srgrimes if (code_file_name == 0) 2991590Srgrimes no_space(); 3001590Srgrimes strcpy(code_file_name, file_prefix); 30122776Ssteve if (file_prefix == output_file_name) 30222776Ssteve { 30322776Ssteve /* 30422776Ssteve * XXX ".tab.c" here is OUTPUT_SUFFIX, but since its length is 30522776Ssteve * in various magic numbers, don't bother using the macro. 30622776Ssteve */ 30722776Ssteve if (len >= 6 && strcmp(code_file_name + len - 6, ".tab.c") == 0) 30822776Ssteve strcpy(code_file_name + len - 6, CODE_SUFFIX); 30922776Ssteve else if (len >= 2 && strcmp(code_file_name + len - 2, ".c") == 0) 31022776Ssteve strcpy(code_file_name + len - 2, CODE_SUFFIX); 31122776Ssteve else 31222776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 31322776Ssteve } 31422776Ssteve else 31522776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 3161590Srgrimes } 3171590Srgrimes else 3181590Srgrimes code_file_name = output_file_name; 3191590Srgrimes 3201590Srgrimes if (dflag) 3211590Srgrimes { 3221590Srgrimes defines_file_name = MALLOC(len + 7); 3231590Srgrimes if (defines_file_name == 0) 3241590Srgrimes no_space(); 3251590Srgrimes strcpy(defines_file_name, file_prefix); 32622776Ssteve if (file_prefix == output_file_name) 32722776Ssteve { 32822776Ssteve#define BISON_DEFINES_SUFFIX ".h" 32922776Ssteve if (len >= 2 && strcmp(defines_file_name + len - 2, ".c") == 0) 33022776Ssteve strcpy(defines_file_name + len - 2, BISON_DEFINES_SUFFIX); 33122776Ssteve else 33222776Ssteve strcpy(defines_file_name + len, BISON_DEFINES_SUFFIX); 33322776Ssteve } 33422776Ssteve else 33522776Ssteve strcpy(defines_file_name + len, DEFINES_SUFFIX); 3361590Srgrimes } 3371590Srgrimes 3381590Srgrimes if (vflag) 3391590Srgrimes { 3401590Srgrimes verbose_file_name = MALLOC(len + 8); 3411590Srgrimes if (verbose_file_name == 0) 3421590Srgrimes no_space(); 3431590Srgrimes strcpy(verbose_file_name, file_prefix); 34422776Ssteve if (file_prefix == output_file_name) 34522776Ssteve { 34622776Ssteve if (len >= 6 && strcmp(verbose_file_name + len - 6, ".tab.c") == 0) 34722776Ssteve strcpy(verbose_file_name + len - 6, VERBOSE_SUFFIX); 34822776Ssteve else if (len >= 2 && strcmp(verbose_file_name + len - 2, ".c") == 0) 34922776Ssteve strcpy(verbose_file_name + len - 2, VERBOSE_SUFFIX); 35022776Ssteve else 35122776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 35222776Ssteve } 35322776Ssteve else 35422776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 3551590Srgrimes } 3561590Srgrimes} 3571590Srgrimes 3581590Srgrimes 35921622Sstevestatic void 3601590Srgrimesopen_files() 3611590Srgrimes{ 36236790Simp int fd; 36336790Simp 3641590Srgrimes create_file_names(); 3651590Srgrimes 3661590Srgrimes if (input_file == 0) 3671590Srgrimes { 3681590Srgrimes input_file = fopen(input_file_name, "r"); 3691590Srgrimes if (input_file == 0) 3701590Srgrimes open_error(input_file_name); 3711590Srgrimes } 3721590Srgrimes 37336790Simp fd = mkstemp(action_file_name); 37436790Simp if (fd < 0 || (action_file = fdopen(fd, "w")) == NULL) { 37536790Simp if (fd >= 0) 37636790Simp close(fd); 3771590Srgrimes open_error(action_file_name); 37836790Simp } 37936790Simp fd = mkstemp(text_file_name); 38036790Simp if (fd < 0 || (text_file = fdopen(fd, "w")) == NULL) { 38136790Simp if (fd >= 0) 38236790Simp close(fd); 38336790Simp open_error(text_file_name); 38436790Simp } 38536790Simp fd = mkstemp(union_file_name); 38636790Simp if (fd < 0 || (union_file = fdopen(fd, "w")) == NULL) { 38736790Simp if (fd >= 0) 38836790Simp close(fd); 38936790Simp open_error(union_file_name); 39036790Simp } 3911590Srgrimes 3921590Srgrimes text_file = fopen(text_file_name, "w"); 3931590Srgrimes if (text_file == 0) 3941590Srgrimes open_error(text_file_name); 3951590Srgrimes 3961590Srgrimes if (vflag) 3971590Srgrimes { 3981590Srgrimes verbose_file = fopen(verbose_file_name, "w"); 3991590Srgrimes if (verbose_file == 0) 4001590Srgrimes open_error(verbose_file_name); 4011590Srgrimes } 4021590Srgrimes 4031590Srgrimes if (dflag) 4041590Srgrimes { 4051590Srgrimes defines_file = fopen(defines_file_name, "w"); 4061590Srgrimes if (defines_file == 0) 4071590Srgrimes open_error(defines_file_name); 4081590Srgrimes union_file = fopen(union_file_name, "w"); 4091590Srgrimes if (union_file == 0) 4101590Srgrimes open_error(union_file_name); 4111590Srgrimes } 4121590Srgrimes 4131590Srgrimes output_file = fopen(output_file_name, "w"); 4141590Srgrimes if (output_file == 0) 4151590Srgrimes open_error(output_file_name); 4161590Srgrimes 4171590Srgrimes if (rflag) 4181590Srgrimes { 4191590Srgrimes code_file = fopen(code_file_name, "w"); 4201590Srgrimes if (code_file == 0) 4211590Srgrimes open_error(code_file_name); 4221590Srgrimes } 4231590Srgrimes else 4241590Srgrimes code_file = output_file; 4251590Srgrimes} 4261590Srgrimes 4271590Srgrimes 4281590Srgrimesint 42993832Sobrienmain(int argc, char *argv[]) 4301590Srgrimes{ 4311590Srgrimes set_signals(); 4321590Srgrimes getargs(argc, argv); 4331590Srgrimes open_files(); 4341590Srgrimes reader(); 4351590Srgrimes lr0(); 4361590Srgrimes lalr(); 4371590Srgrimes make_parser(); 4381590Srgrimes verbose(); 4391590Srgrimes output(); 4401590Srgrimes done(0); 4411590Srgrimes /*NOTREACHED*/ 44221622Ssteve return (0); 4431590Srgrimes} 444