main.c revision 36790
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 371590Srgrimes#ifndef lint 3821622Sstevestatic char const copyright[] = 391590Srgrimes"@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 401590Srgrimes All rights reserved.\n"; 411590Srgrimes#endif /* not lint */ 421590Srgrimes 431590Srgrimes#ifndef lint 4428856Scharnier#if 0 4521622Sstevestatic char const sccsid[] = "@(#)main.c 5.5 (Berkeley) 5/24/93"; 4628856Scharnier#endif 4728856Scharnierstatic const char rcsid[] = 4836790Simp "$Id: main.c,v 1.8 1997/08/28 06:33:53 charnier Exp $"; 491590Srgrimes#endif /* not lint */ 501590Srgrimes 511590Srgrimes#include <signal.h> 5221622Ssteve#include <stdlib.h> 5321622Ssteve#include <string.h> 5421622Ssteve#include <unistd.h> 551590Srgrimes#include "defs.h" 561590Srgrimes 571590Srgrimeschar dflag; 581590Srgrimeschar lflag; 591590Srgrimeschar rflag; 601590Srgrimeschar tflag; 611590Srgrimeschar vflag; 621590Srgrimes 631590Srgrimeschar *symbol_prefix; 641590Srgrimeschar *file_prefix = "y"; 651590Srgrimeschar *temp_form = "yacc.XXXXXXX"; 661590Srgrimes 671590Srgrimesint lineno; 681590Srgrimesint outline; 691590Srgrimes 701590Srgrimeschar *action_file_name; 711590Srgrimeschar *code_file_name; 721590Srgrimeschar *defines_file_name; 731590Srgrimeschar *input_file_name = ""; 741590Srgrimeschar *output_file_name; 751590Srgrimeschar *text_file_name; 761590Srgrimeschar *union_file_name; 771590Srgrimeschar *verbose_file_name; 781590Srgrimes 791590SrgrimesFILE *action_file; /* a temp file, used to save actions associated */ 801590Srgrimes /* with rules until the parser is written */ 811590SrgrimesFILE *code_file; /* y.code.c (used when the -r option is specified) */ 821590SrgrimesFILE *defines_file; /* y.tab.h */ 831590SrgrimesFILE *input_file; /* the input file */ 841590SrgrimesFILE *output_file; /* y.tab.c */ 851590SrgrimesFILE *text_file; /* a temp file, used to save text until all */ 861590Srgrimes /* symbols have been defined */ 871590SrgrimesFILE *union_file; /* a temp file, used to save the union */ 881590Srgrimes /* definition until all symbol have been */ 891590Srgrimes /* defined */ 901590SrgrimesFILE *verbose_file; /* y.output */ 911590Srgrimes 921590Srgrimesint nitems; 931590Srgrimesint nrules; 941590Srgrimesint nsyms; 951590Srgrimesint ntokens; 961590Srgrimesint nvars; 971590Srgrimes 981590Srgrimesint start_symbol; 991590Srgrimeschar **symbol_name; 1001590Srgrimesshort *symbol_value; 1011590Srgrimesshort *symbol_prec; 1021590Srgrimeschar *symbol_assoc; 1031590Srgrimes 1041590Srgrimesshort *ritem; 1051590Srgrimesshort *rlhs; 1061590Srgrimesshort *rrhs; 1071590Srgrimesshort *rprec; 1081590Srgrimeschar *rassoc; 1091590Srgrimesshort **derives; 1101590Srgrimeschar *nullable; 1111590Srgrimes 11221622Sstevestatic void create_file_names __P((void)); 11321622Sstevestatic void getargs __P((int, char **)); 11421622Sstevestatic void onintr __P((int)); 11521622Sstevestatic void open_files __P((void)); 11621622Sstevestatic void set_signals __P((void)); 11721622Sstevestatic void usage __P((void)); 1181590Srgrimes 1191590Srgrimes 12021622Sstevevoid 1211590Srgrimesdone(k) 1221590Srgrimesint k; 1231590Srgrimes{ 1241590Srgrimes if (action_file) { fclose(action_file); unlink(action_file_name); } 1251590Srgrimes if (text_file) { fclose(text_file); unlink(text_file_name); } 1261590Srgrimes if (union_file) { fclose(union_file); unlink(union_file_name); } 1271590Srgrimes exit(k); 1281590Srgrimes} 1291590Srgrimes 1301590Srgrimes 13121622Sstevestatic void 1321590Srgrimesonintr(signo) 1331590Srgrimes int signo; 1341590Srgrimes{ 1351590Srgrimes done(1); 1361590Srgrimes} 1371590Srgrimes 1381590Srgrimes 13921622Sstevestatic void 1401590Srgrimesset_signals() 1411590Srgrimes{ 1421590Srgrimes#ifdef SIGINT 1431590Srgrimes if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1441590Srgrimes signal(SIGINT, onintr); 1451590Srgrimes#endif 1461590Srgrimes#ifdef SIGTERM 1471590Srgrimes if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 1481590Srgrimes signal(SIGTERM, onintr); 1491590Srgrimes#endif 1501590Srgrimes#ifdef SIGHUP 1511590Srgrimes if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 1521590Srgrimes signal(SIGHUP, onintr); 1531590Srgrimes#endif 1541590Srgrimes} 1551590Srgrimes 1561590Srgrimes 15721622Sstevestatic void 1581590Srgrimesusage() 1591590Srgrimes{ 16028856Scharnier fprintf(stderr, "%s\n%s\n", 16128856Scharnier "usage: yacc [-dlrtv] [-b file_prefix] [-o output_filename]", 16228856Scharnier " [-p symbol_prefix] filename"); 1631590Srgrimes exit(1); 1641590Srgrimes} 1651590Srgrimes 1661590Srgrimes 16721622Sstevestatic void 1681590Srgrimesgetargs(argc, argv) 1691590Srgrimesint argc; 1701590Srgrimeschar *argv[]; 1711590Srgrimes{ 1721590Srgrimes register int i; 1731590Srgrimes register char *s; 1741590Srgrimes 1751590Srgrimes for (i = 1; i < argc; ++i) 1761590Srgrimes { 1771590Srgrimes s = argv[i]; 1781590Srgrimes if (*s != '-') break; 1791590Srgrimes switch (*++s) 1801590Srgrimes { 1811590Srgrimes case '\0': 1821590Srgrimes input_file = stdin; 1831590Srgrimes if (i + 1 < argc) usage(); 1841590Srgrimes return; 1851590Srgrimes 1861590Srgrimes case '-': 1871590Srgrimes ++i; 1881590Srgrimes goto no_more_options; 1891590Srgrimes 1901590Srgrimes case 'b': 1911590Srgrimes if (*++s) 1921590Srgrimes file_prefix = s; 1931590Srgrimes else if (++i < argc) 1941590Srgrimes file_prefix = argv[i]; 1951590Srgrimes else 1961590Srgrimes usage(); 1971590Srgrimes continue; 1981590Srgrimes 1991590Srgrimes case 'd': 2001590Srgrimes dflag = 1; 2011590Srgrimes break; 2021590Srgrimes 2031590Srgrimes case 'l': 2041590Srgrimes lflag = 1; 2051590Srgrimes break; 2061590Srgrimes 20722776Ssteve case 'o': 20822776Ssteve if (*++s) 20922776Ssteve output_file_name = s; 21022776Ssteve else if (++i < argc) 21122776Ssteve output_file_name = argv[i]; 21222776Ssteve else 21322776Ssteve usage(); 21422776Ssteve continue; 21522776Ssteve 2161590Srgrimes case 'p': 2171590Srgrimes if (*++s) 2181590Srgrimes symbol_prefix = s; 2191590Srgrimes else if (++i < argc) 2201590Srgrimes symbol_prefix = argv[i]; 2211590Srgrimes else 2221590Srgrimes usage(); 2231590Srgrimes continue; 2241590Srgrimes 2251590Srgrimes case 'r': 2261590Srgrimes rflag = 1; 2271590Srgrimes break; 2281590Srgrimes 2291590Srgrimes case 't': 2301590Srgrimes tflag = 1; 2311590Srgrimes break; 2321590Srgrimes 2331590Srgrimes case 'v': 2341590Srgrimes vflag = 1; 2351590Srgrimes break; 2361590Srgrimes 2371590Srgrimes default: 2381590Srgrimes usage(); 2391590Srgrimes } 2401590Srgrimes 2411590Srgrimes for (;;) 2421590Srgrimes { 2431590Srgrimes switch (*++s) 2441590Srgrimes { 2451590Srgrimes case '\0': 2461590Srgrimes goto end_of_option; 2471590Srgrimes 2481590Srgrimes case 'd': 2491590Srgrimes dflag = 1; 2501590Srgrimes break; 2511590Srgrimes 2521590Srgrimes case 'l': 2531590Srgrimes lflag = 1; 2541590Srgrimes break; 2551590Srgrimes 2561590Srgrimes case 'r': 2571590Srgrimes rflag = 1; 2581590Srgrimes break; 2591590Srgrimes 2601590Srgrimes case 't': 2611590Srgrimes tflag = 1; 2621590Srgrimes break; 2631590Srgrimes 2641590Srgrimes case 'v': 2651590Srgrimes vflag = 1; 2661590Srgrimes break; 2671590Srgrimes 2681590Srgrimes default: 2691590Srgrimes usage(); 2701590Srgrimes } 2711590Srgrimes } 2721590Srgrimesend_of_option:; 2731590Srgrimes } 2741590Srgrimes 2751590Srgrimesno_more_options:; 2761590Srgrimes if (i + 1 != argc) usage(); 2771590Srgrimes input_file_name = argv[i]; 2781590Srgrimes} 2791590Srgrimes 2801590Srgrimes 2811590Srgrimeschar * 2821590Srgrimesallocate(n) 2831590Srgrimesunsigned n; 2841590Srgrimes{ 2851590Srgrimes register char *p; 2861590Srgrimes 2871590Srgrimes p = NULL; 2881590Srgrimes if (n) 2891590Srgrimes { 2901590Srgrimes p = CALLOC(1, n); 2911590Srgrimes if (!p) no_space(); 2921590Srgrimes } 2931590Srgrimes return (p); 2941590Srgrimes} 2951590Srgrimes 2961590Srgrimes 29721622Sstevestatic void 2981590Srgrimescreate_file_names() 2991590Srgrimes{ 3001590Srgrimes int i, len; 3011590Srgrimes char *tmpdir; 3021590Srgrimes 3031590Srgrimes tmpdir = getenv("TMPDIR"); 3041590Srgrimes if (tmpdir == 0) tmpdir = "/tmp"; 3051590Srgrimes 3061590Srgrimes len = strlen(tmpdir); 3071590Srgrimes i = len + 13; 3081590Srgrimes if (len && tmpdir[len-1] != '/') 3091590Srgrimes ++i; 3101590Srgrimes 3111590Srgrimes action_file_name = MALLOC(i); 3121590Srgrimes if (action_file_name == 0) no_space(); 3131590Srgrimes text_file_name = MALLOC(i); 3141590Srgrimes if (text_file_name == 0) no_space(); 3151590Srgrimes union_file_name = MALLOC(i); 3161590Srgrimes if (union_file_name == 0) no_space(); 3171590Srgrimes 3181590Srgrimes strcpy(action_file_name, tmpdir); 3191590Srgrimes strcpy(text_file_name, tmpdir); 3201590Srgrimes strcpy(union_file_name, tmpdir); 3211590Srgrimes 3221590Srgrimes if (len && tmpdir[len - 1] != '/') 3231590Srgrimes { 3241590Srgrimes action_file_name[len] = '/'; 3251590Srgrimes text_file_name[len] = '/'; 3261590Srgrimes union_file_name[len] = '/'; 3271590Srgrimes ++len; 3281590Srgrimes } 3291590Srgrimes 3301590Srgrimes strcpy(action_file_name + len, temp_form); 3311590Srgrimes strcpy(text_file_name + len, temp_form); 3321590Srgrimes strcpy(union_file_name + len, temp_form); 3331590Srgrimes 3341590Srgrimes action_file_name[len + 5] = 'a'; 3351590Srgrimes text_file_name[len + 5] = 't'; 3361590Srgrimes union_file_name[len + 5] = 'u'; 3371590Srgrimes 33822776Ssteve if (output_file_name != 0) 33922776Ssteve { 34022776Ssteve file_prefix = output_file_name; 34122776Ssteve len = strlen(file_prefix); 34222776Ssteve } 34322776Ssteve else 34422776Ssteve { 34522776Ssteve len = strlen(file_prefix); 34622776Ssteve output_file_name = MALLOC(len + 7); 34722776Ssteve if (output_file_name == 0) 34822776Ssteve no_space(); 34922776Ssteve strcpy(output_file_name, file_prefix); 35022776Ssteve strcpy(output_file_name + len, OUTPUT_SUFFIX); 35122776Ssteve } 3521590Srgrimes 3531590Srgrimes if (rflag) 3541590Srgrimes { 3551590Srgrimes code_file_name = MALLOC(len + 8); 3561590Srgrimes if (code_file_name == 0) 3571590Srgrimes no_space(); 3581590Srgrimes strcpy(code_file_name, file_prefix); 35922776Ssteve if (file_prefix == output_file_name) 36022776Ssteve { 36122776Ssteve /* 36222776Ssteve * XXX ".tab.c" here is OUTPUT_SUFFIX, but since its length is 36322776Ssteve * in various magic numbers, don't bother using the macro. 36422776Ssteve */ 36522776Ssteve if (len >= 6 && strcmp(code_file_name + len - 6, ".tab.c") == 0) 36622776Ssteve strcpy(code_file_name + len - 6, CODE_SUFFIX); 36722776Ssteve else if (len >= 2 && strcmp(code_file_name + len - 2, ".c") == 0) 36822776Ssteve strcpy(code_file_name + len - 2, CODE_SUFFIX); 36922776Ssteve else 37022776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 37122776Ssteve } 37222776Ssteve else 37322776Ssteve strcpy(code_file_name + len, CODE_SUFFIX); 3741590Srgrimes } 3751590Srgrimes else 3761590Srgrimes code_file_name = output_file_name; 3771590Srgrimes 3781590Srgrimes if (dflag) 3791590Srgrimes { 3801590Srgrimes defines_file_name = MALLOC(len + 7); 3811590Srgrimes if (defines_file_name == 0) 3821590Srgrimes no_space(); 3831590Srgrimes strcpy(defines_file_name, file_prefix); 38422776Ssteve if (file_prefix == output_file_name) 38522776Ssteve { 38622776Ssteve#define BISON_DEFINES_SUFFIX ".h" 38722776Ssteve if (len >= 2 && strcmp(defines_file_name + len - 2, ".c") == 0) 38822776Ssteve strcpy(defines_file_name + len - 2, BISON_DEFINES_SUFFIX); 38922776Ssteve else 39022776Ssteve strcpy(defines_file_name + len, BISON_DEFINES_SUFFIX); 39122776Ssteve } 39222776Ssteve else 39322776Ssteve strcpy(defines_file_name + len, DEFINES_SUFFIX); 3941590Srgrimes } 3951590Srgrimes 3961590Srgrimes if (vflag) 3971590Srgrimes { 3981590Srgrimes verbose_file_name = MALLOC(len + 8); 3991590Srgrimes if (verbose_file_name == 0) 4001590Srgrimes no_space(); 4011590Srgrimes strcpy(verbose_file_name, file_prefix); 40222776Ssteve if (file_prefix == output_file_name) 40322776Ssteve { 40422776Ssteve if (len >= 6 && strcmp(verbose_file_name + len - 6, ".tab.c") == 0) 40522776Ssteve strcpy(verbose_file_name + len - 6, VERBOSE_SUFFIX); 40622776Ssteve else if (len >= 2 && strcmp(verbose_file_name + len - 2, ".c") == 0) 40722776Ssteve strcpy(verbose_file_name + len - 2, VERBOSE_SUFFIX); 40822776Ssteve else 40922776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 41022776Ssteve } 41122776Ssteve else 41222776Ssteve strcpy(verbose_file_name + len, VERBOSE_SUFFIX); 4131590Srgrimes } 4141590Srgrimes} 4151590Srgrimes 4161590Srgrimes 41721622Sstevestatic void 4181590Srgrimesopen_files() 4191590Srgrimes{ 42036790Simp int fd; 42136790Simp 4221590Srgrimes create_file_names(); 4231590Srgrimes 4241590Srgrimes if (input_file == 0) 4251590Srgrimes { 4261590Srgrimes input_file = fopen(input_file_name, "r"); 4271590Srgrimes if (input_file == 0) 4281590Srgrimes open_error(input_file_name); 4291590Srgrimes } 4301590Srgrimes 43136790Simp fd = mkstemp(action_file_name); 43236790Simp if (fd < 0 || (action_file = fdopen(fd, "w")) == NULL) { 43336790Simp if (fd >= 0) 43436790Simp close(fd); 4351590Srgrimes open_error(action_file_name); 43636790Simp } 43736790Simp fd = mkstemp(text_file_name); 43836790Simp if (fd < 0 || (text_file = fdopen(fd, "w")) == NULL) { 43936790Simp if (fd >= 0) 44036790Simp close(fd); 44136790Simp open_error(text_file_name); 44236790Simp } 44336790Simp fd = mkstemp(union_file_name); 44436790Simp if (fd < 0 || (union_file = fdopen(fd, "w")) == NULL) { 44536790Simp if (fd >= 0) 44636790Simp close(fd); 44736790Simp open_error(union_file_name); 44836790Simp } 4491590Srgrimes 4501590Srgrimes text_file = fopen(text_file_name, "w"); 4511590Srgrimes if (text_file == 0) 4521590Srgrimes open_error(text_file_name); 4531590Srgrimes 4541590Srgrimes if (vflag) 4551590Srgrimes { 4561590Srgrimes verbose_file = fopen(verbose_file_name, "w"); 4571590Srgrimes if (verbose_file == 0) 4581590Srgrimes open_error(verbose_file_name); 4591590Srgrimes } 4601590Srgrimes 4611590Srgrimes if (dflag) 4621590Srgrimes { 4631590Srgrimes defines_file = fopen(defines_file_name, "w"); 4641590Srgrimes if (defines_file == 0) 4651590Srgrimes open_error(defines_file_name); 4661590Srgrimes union_file = fopen(union_file_name, "w"); 4671590Srgrimes if (union_file == 0) 4681590Srgrimes open_error(union_file_name); 4691590Srgrimes } 4701590Srgrimes 4711590Srgrimes output_file = fopen(output_file_name, "w"); 4721590Srgrimes if (output_file == 0) 4731590Srgrimes open_error(output_file_name); 4741590Srgrimes 4751590Srgrimes if (rflag) 4761590Srgrimes { 4771590Srgrimes code_file = fopen(code_file_name, "w"); 4781590Srgrimes if (code_file == 0) 4791590Srgrimes open_error(code_file_name); 4801590Srgrimes } 4811590Srgrimes else 4821590Srgrimes code_file = output_file; 4831590Srgrimes} 4841590Srgrimes 4851590Srgrimes 4861590Srgrimesint 4871590Srgrimesmain(argc, argv) 4881590Srgrimesint argc; 4891590Srgrimeschar *argv[]; 4901590Srgrimes{ 4911590Srgrimes set_signals(); 4921590Srgrimes getargs(argc, argv); 4931590Srgrimes open_files(); 4941590Srgrimes reader(); 4951590Srgrimes lr0(); 4961590Srgrimes lalr(); 4971590Srgrimes make_parser(); 4981590Srgrimes verbose(); 4991590Srgrimes output(); 5001590Srgrimes done(0); 5011590Srgrimes /*NOTREACHED*/ 50221622Ssteve return (0); 5031590Srgrimes} 504