Initial revision

This commit is contained in:
Richard M. Stallman
1993-04-15 19:37:53 +00:00
parent 1031a641f5
commit 54bd0db436
2 changed files with 534 additions and 0 deletions

394
src/files.c Normal file
View File

@@ -0,0 +1,394 @@
/* Open and close files for bison,
Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
Bison is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Bison is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef VMS
#include <ssdef.h>
#define unlink delete
#ifndef XPFILE
#define XPFILE "GNU_BISON:[000000]BISON.SIMPLE"
#endif
#ifndef XPFILE1
#define XPFILE1 "GNU_BISON:[000000]BISON.HAIRY"
#endif
#endif
#include <stdio.h>
#include "system.h"
#include "files.h"
#include "new.h"
#include "gram.h"
FILE *finput = NULL;
FILE *foutput = NULL;
FILE *fdefines = NULL;
FILE *ftable = NULL;
FILE *fattrs = NULL;
FILE *fguard = NULL;
FILE *faction = NULL;
FILE *fparser = NULL;
/* File name specified with -o for the output file, or 0 if no -o. */
char *spec_outfile;
char *infile;
char *outfile;
char *defsfile;
char *tabfile;
char *attrsfile;
char *guardfile;
char *actfile;
char *tmpattrsfile;
char *tmptabfile;
char *tmpdefsfile;
extern char *mktemp(); /* So the compiler won't complain */
extern char *getenv();
extern void perror();
FILE *tryopen(); /* This might be a good idea */
void done();
extern char *program_name;
extern int verboseflag;
extern int definesflag;
int fixed_outfiles = 0;
char*
stringappend(string1, end1, string2)
char *string1;
int end1;
char *string2;
{
register char *ostring;
register char *cp, *cp1;
register int i;
cp = string2; i = 0;
while (*cp++) i++;
ostring = NEW2(i+end1+1, char);
cp = ostring;
cp1 = string1;
for (i = 0; i < end1; i++)
*cp++ = *cp1++;
cp1 = string2;
while (*cp++ = *cp1++) ;
return ostring;
}
/* JF this has been hacked to death. Nowaday it sets up the file names for
the output files, and opens the tmp files and the parser */
void
openfiles()
{
char *name_base;
register char *cp;
char *filename;
int base_length;
int short_base_length;
#ifdef VMS
char *tmp_base = "sys$scratch:b_";
#else
char *tmp_base = "/tmp/b.";
#endif
int tmp_len;
#ifdef MSDOS
tmp_base = getenv ("TMP");
if (tmp_base == 0)
tmp_base = "";
strlwr (infile);
#endif /* MSDOS */
tmp_len = strlen (tmp_base);
if (spec_outfile)
{
/* -o was specified. The precise -o name will be used for ftable.
For other output files, remove the ".c" or ".tab.c" suffix. */
name_base = spec_outfile;
#ifdef MSDOS
strlwr (name_base);
#endif /* MSDOS */
/* BASE_LENGTH includes ".tab" but not ".c". */
base_length = strlen (name_base);
if (!strcmp (name_base + base_length - 2, ".c"))
base_length -= 2;
/* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
short_base_length = base_length;
if (!strncmp (name_base + short_base_length - 4, ".tab", 4))
short_base_length -= 4;
else if (!strncmp (name_base + short_base_length - 4, "_tab", 4))
short_base_length -= 4;
}
else if (spec_file_prefix)
{
/* -b was specified. Construct names from it. */
/* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
short_base_length = strlen (spec_file_prefix);
/* Count room for `.tab'. */
base_length = short_base_length + 4;
name_base = (char *) mallocate (base_length + 1);
/* Append `.tab'. */
strcpy (name_base, spec_file_prefix);
#ifdef VMS
strcat (name_base, "_tab");
#else
strcat (name_base, ".tab");
#endif
#ifdef MSDOS
strlwr (name_base);
#endif /* MSDOS */
}
else
{
/* -o was not specified; compute output file name from input
or use y.tab.c, etc., if -y was specified. */
name_base = fixed_outfiles ? "y.y" : infile;
/* BASE_LENGTH gets length of NAME_BASE, sans ".y" suffix if any. */
base_length = strlen (name_base);
if (!strcmp (name_base + base_length - 2, ".y"))
base_length -= 2;
short_base_length = base_length;
#ifdef VMS
name_base = stringappend(name_base, short_base_length, "_tab");
#else
#ifdef MSDOS
name_base = stringappend(name_base, short_base_length, "_tab");
#else
name_base = stringappend(name_base, short_base_length, ".tab");
#endif /* not MSDOS */
#endif
base_length = short_base_length + 4;
}
finput = tryopen(infile, "r");
filename = getenv("BISON_SIMPLE");
#ifdef MSDOS
/* File doesn't exist in current directory; try in INIT directory. */
cp = getenv("INIT");
if (filename == 0 && cp != 0)
{
filename = malloc(strlen(cp) + strlen(PFILE) + 2);
strcpy(filename, cp);
cp = filename + strlen(filename);
*cp++ = '/';
strcpy(cp, PFILE);
}
#endif /* MSDOS */
fparser = tryopen(filename ? filename : PFILE, "r");
if (verboseflag)
{
#ifdef MSDOS
outfile = stringappend(name_base, short_base_length, ".out");
#else
/* We used to use just .out if spec_name_prefix (-p) was used,
but that conflicts with Posix. */
outfile = stringappend(name_base, short_base_length, ".output");
#endif
foutput = tryopen(outfile, "w");
}
#ifdef MSDOS
actfile = mktemp(stringappend(tmp_base, tmp_len, "acXXXXXX"));
tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "atXXXXXX"));
tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "taXXXXXX"));
tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "deXXXXXX"));
#else
actfile = mktemp(stringappend(tmp_base, tmp_len, "act.XXXXXX"));
tmpattrsfile = mktemp(stringappend(tmp_base, tmp_len, "attrs.XXXXXX"));
tmptabfile = mktemp(stringappend(tmp_base, tmp_len, "tab.XXXXXX"));
tmpdefsfile = mktemp(stringappend(tmp_base, tmp_len, "defs.XXXXXX"));
#endif /* not MSDOS */
faction = tryopen(actfile, "w+");
fattrs = tryopen(tmpattrsfile,"w+");
ftable = tryopen(tmptabfile, "w+");
if (definesflag)
{
defsfile = stringappend(name_base, base_length, ".h");
fdefines = tryopen(tmpdefsfile, "w+");
}
#ifndef MSDOS
unlink(actfile);
unlink(tmpattrsfile);
unlink(tmptabfile);
unlink(tmpdefsfile);
#endif
/* These are opened by `done' or `open_extra_files', if at all */
if (spec_outfile)
tabfile = spec_outfile;
else
tabfile = stringappend(name_base, base_length, ".c");
#ifdef VMS
attrsfile = stringappend(name_base, short_base_length, "_stype.h");
guardfile = stringappend(name_base, short_base_length, "_guard.c");
#else
#ifdef MSDOS
attrsfile = stringappend(name_base, short_base_length, ".sth");
guardfile = stringappend(name_base, short_base_length, ".guc");
#else
attrsfile = stringappend(name_base, short_base_length, ".stype.h");
guardfile = stringappend(name_base, short_base_length, ".guard.c");
#endif /* not MSDOS */
#endif /* not VMS */
}
/* open the output files needed only for the semantic parser.
This is done when %semantic_parser is seen in the declarations section. */
void
open_extra_files()
{
FILE *ftmp;
int c;
char *filename, *cp;
fclose(fparser);
filename = (char *) getenv ("BISON_HAIRY");
#ifdef MSDOS
/* File doesn't exist in current directory; try in INIT directory. */
cp = getenv("INIT");
if (filename == 0 && cp != 0)
{
filename = malloc(strlen(cp) + strlen(PFILE1) + 2);
strcpy(filename, cp);
cp = filename + strlen(filename);
*cp++ = '/';
strcpy(cp, PFILE1);
}
#endif
fparser= tryopen(filename ? filename : PFILE1, "r");
/* JF change from inline attrs file to separate one */
ftmp = tryopen(attrsfile, "w");
rewind(fattrs);
while((c=getc(fattrs))!=EOF) /* Thank god for buffering */
putc(c,ftmp);
fclose(fattrs);
fattrs=ftmp;
fguard = tryopen(guardfile, "w");
}
/* JF to make file opening easier. This func tries to open file
NAME with mode MODE, and prints an error message if it fails. */
FILE *
tryopen(name, mode)
char *name;
char *mode;
{
FILE *ptr;
ptr = fopen(name, mode);
if (ptr == NULL)
{
fprintf(stderr, "%s: ", program_name);
perror(name);
done(2);
}
return ptr;
}
void
done(k)
int k;
{
if (faction)
fclose(faction);
if (fattrs)
fclose(fattrs);
if (fguard)
fclose(fguard);
if (finput)
fclose(finput);
if (fparser)
fclose(fparser);
if (foutput)
fclose(foutput);
/* JF write out the output file */
if (k == 0 && ftable)
{
FILE *ftmp;
register int c;
ftmp=tryopen(tabfile, "w");
rewind(ftable);
while((c=getc(ftable)) != EOF)
putc(c,ftmp);
fclose(ftmp);
fclose(ftable);
if (definesflag)
{
ftmp = tryopen(defsfile, "w");
fflush(fdefines);
rewind(fdefines);
while((c=getc(fdefines)) != EOF)
putc(c,ftmp);
fclose(ftmp);
fclose(fdefines);
}
}
#ifdef VMS
if (faction)
delete(actfile);
if (fattrs)
delete(tmpattrsfile);
if (ftable)
delete(tmptabfile);
if (k==0) sys$exit(SS$_NORMAL);
sys$exit(SS$_ABORT);
#else
#ifdef MSDOS
if (actfile) unlink(actfile);
if (tmpattrsfile) unlink(tmpattrsfile);
if (tmptabfile) unlink(tmptabfile);
if (tmpdefsfile) unlink(tmpdefsfile);
#endif /* MSDOS */
exit(k);
#endif /* not VMS */
}

140
src/main.c Normal file
View File

@@ -0,0 +1,140 @@
/* Top level entry point of bison,
Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
Bison is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Bison is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "system.h"
#include "machine.h" /* JF for MAXSHORT */
extern int lineno;
extern int verboseflag;
/* Nonzero means failure has been detected; don't write a parser file. */
int failure;
/* The name this program was run with, for messages. */
char *program_name;
extern void getargs(), openfiles(), reader(), reduce_grammar();
extern void set_derives(), set_nullable(), generate_states();
extern void lalr(), initialize_conflicts(), verbose(), terse();
extern void output(), done();
/* VMS complained about using `int'. */
int
main(argc, argv)
int argc;
char *argv[];
{
program_name = argv[0];
failure = 0;
lineno = 0;
getargs(argc, argv);
openfiles();
/* read the input. Copy some parts of it to fguard, faction, ftable and fattrs.
In file reader.c.
The other parts are recorded in the grammar; see gram.h. */
reader();
/* find useless nonterminals and productions and reduce the grammar. In
file reduce.c */
reduce_grammar();
/* record other info about the grammar. In files derives and nullable. */
set_derives();
set_nullable();
/* convert to nondeterministic finite state machine. In file LR0.
See state.h for more info. */
generate_states();
/* make it deterministic. In file lalr. */
lalr();
/* Find and record any conflicts: places where one token of lookahead is not
enough to disambiguate the parsing. In file conflicts.
Currently this does not do anything to resolve them;
the trivial form of conflict resolution that exists is done in output. */
initialize_conflicts();
/* print information about results, if requested. In file print. */
if (verboseflag)
verbose();
else
terse();
/* output the tables and the parser to ftable. In file output. */
output();
done(failure);
}
/* functions to report errors which prevent a parser from being generated */
void
fatal(s)
char *s;
{
extern char *infile;
if (infile == 0)
fprintf(stderr, "fatal error: %s\n", s);
else
fprintf(stderr, "\"%s\", line %d: %s\n", infile, lineno, s);
done(1);
}
/* JF changed to accept/deal with variable args.
DO NOT change this to use varargs. It will appear to work
but will break on systems that don't have the necessary library
functions. This is the ONLY safe way to write such a function. */
/*VARARGS1*/
void
fatals(fmt,x1,x2,x3,x4,x5,x6,x7,x8)
char *fmt;
{
char buffer[200];
sprintf(buffer, fmt, x1,x2,x3,x4,x5,x6,x7,x8);
fatal(buffer);
}
void
toomany(s)
char *s;
{
char buffer[200];
/* JF new msg */
sprintf(buffer, "limit of %d exceeded, too many %s", MAXSHORT, s);
fatal(buffer);
}
void
berror(s)
char *s;
{
fprintf(stderr, "internal error, %s\n", s);
abort();
}