1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-04 12:52:15 +00:00

This commit was generated by cvs2svn to compensate for changes in r18210,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Peter Wemm 1996-09-10 13:12:03 +00:00
commit ca1e085bd0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18211
53 changed files with 22598 additions and 0 deletions

339
contrib/bison/COPYING Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program 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 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

1290
contrib/bison/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

181
contrib/bison/INSTALL Normal file
View File

@ -0,0 +1,181 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

704
contrib/bison/LR0.c Normal file
View File

@ -0,0 +1,704 @@
/* Generate the nondeterministic finite state machine 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. */
/* See comments in state.h for the data structures that represent it.
The entry point is generate_states. */
#include <stdio.h>
#include "system.h"
#include "machine.h"
#include "new.h"
#include "gram.h"
#include "state.h"
extern char *nullable;
extern short *itemset;
extern short *itemsetend;
int nstates;
int final_state;
core *first_state;
shifts *first_shift;
reductions *first_reduction;
int get_state();
core *new_state();
void new_itemsets();
void append_states();
void initialize_states();
void save_shifts();
void save_reductions();
void augment_automaton();
void insert_start_shift();
extern void initialize_closure();
extern void closure();
extern void finalize_closure();
extern void toomany();
static core *this_state;
static core *last_state;
static shifts *last_shift;
static reductions *last_reduction;
static int nshifts;
static short *shift_symbol;
static short *redset;
static short *shiftset;
static short **kernel_base;
static short **kernel_end;
static short *kernel_items;
/* hash table for states, to recognize equivalent ones. */
#define STATE_TABLE_SIZE 1009
static core **state_table;
void
allocate_itemsets()
{
register short *itemp;
register int symbol;
register int i;
register int count;
register short *symbol_count;
count = 0;
symbol_count = NEW2(nsyms, short);
itemp = ritem;
symbol = *itemp++;
while (symbol)
{
if (symbol > 0)
{
count++;
symbol_count[symbol]++;
}
symbol = *itemp++;
}
/* see comments before new_itemsets. All the vectors of items
live inside kernel_items. The number of active items after
some symbol cannot be more than the number of times that symbol
appears as an item, which is symbol_count[symbol].
We allocate that much space for each symbol. */
kernel_base = NEW2(nsyms, short *);
kernel_items = NEW2(count, short);
count = 0;
for (i = 0; i < nsyms; i++)
{
kernel_base[i] = kernel_items + count;
count += symbol_count[i];
}
shift_symbol = symbol_count;
kernel_end = NEW2(nsyms, short *);
}
void
allocate_storage()
{
allocate_itemsets();
shiftset = NEW2(nsyms, short);
redset = NEW2(nrules + 1, short);
state_table = NEW2(STATE_TABLE_SIZE, core *);
}
void
free_storage()
{
FREE(shift_symbol);
FREE(redset);
FREE(shiftset);
FREE(kernel_base);
FREE(kernel_end);
FREE(kernel_items);
FREE(state_table);
}
/* compute the nondeterministic finite state machine (see state.h for details)
from the grammar. */
void
generate_states()
{
allocate_storage();
initialize_closure(nitems);
initialize_states();
while (this_state)
{
/* Set up ruleset and itemset for the transitions out of this state.
ruleset gets a 1 bit for each rule that could reduce now.
itemset gets a vector of all the items that could be accepted next. */
closure(this_state->items, this_state->nitems);
/* record the reductions allowed out of this state */
save_reductions();
/* find the itemsets of the states that shifts can reach */
new_itemsets();
/* find or create the core structures for those states */
append_states();
/* create the shifts structures for the shifts to those states,
now that the state numbers transitioning to are known */
if (nshifts > 0)
save_shifts();
/* states are queued when they are created; process them all */
this_state = this_state->next;
}
/* discard various storage */
finalize_closure();
free_storage();
/* set up initial and final states as parser wants them */
augment_automaton();
}
/* Find which symbols can be shifted in the current state,
and for each one record which items would be active after that shift.
Uses the contents of itemset.
shift_symbol is set to a vector of the symbols that can be shifted.
For each symbol in the grammar, kernel_base[symbol] points to
a vector of item numbers activated if that symbol is shifted,
and kernel_end[symbol] points after the end of that vector. */
void
new_itemsets()
{
register int i;
register int shiftcount;
register short *isp;
register short *ksp;
register int symbol;
#ifdef TRACE
fprintf(stderr, "Entering new_itemsets\n");
#endif
for (i = 0; i < nsyms; i++)
kernel_end[i] = NULL;
shiftcount = 0;
isp = itemset;
while (isp < itemsetend)
{
i = *isp++;
symbol = ritem[i];
if (symbol > 0)
{
ksp = kernel_end[symbol];
if (!ksp)
{
shift_symbol[shiftcount++] = symbol;
ksp = kernel_base[symbol];
}
*ksp++ = i + 1;
kernel_end[symbol] = ksp;
}
}
nshifts = shiftcount;
}
/* Use the information computed by new_itemsets to find the state numbers
reached by each shift transition from the current state.
shiftset is set up as a vector of state numbers of those states. */
void
append_states()
{
register int i;
register int j;
register int symbol;
#ifdef TRACE
fprintf(stderr, "Entering append_states\n");
#endif
/* first sort shift_symbol into increasing order */
for (i = 1; i < nshifts; i++)
{
symbol = shift_symbol[i];
j = i;
while (j > 0 && shift_symbol[j - 1] > symbol)
{
shift_symbol[j] = shift_symbol[j - 1];
j--;
}
shift_symbol[j] = symbol;
}
for (i = 0; i < nshifts; i++)
{
symbol = shift_symbol[i];
shiftset[i] = get_state(symbol);
}
}
/* find the state number for the state we would get to
(from the current state) by shifting symbol.
Create a new state if no equivalent one exists already.
Used by append_states */
int
get_state(symbol)
int symbol;
{
register int key;
register short *isp1;
register short *isp2;
register short *iend;
register core *sp;
register int found;
int n;
#ifdef TRACE
fprintf(stderr, "Entering get_state, symbol = %d\n", symbol);
#endif
isp1 = kernel_base[symbol];
iend = kernel_end[symbol];
n = iend - isp1;
/* add up the target state's active item numbers to get a hash key */
key = 0;
while (isp1 < iend)
key += *isp1++;
key = key % STATE_TABLE_SIZE;
sp = state_table[key];
if (sp)
{
found = 0;
while (!found)
{
if (sp->nitems == n)
{
found = 1;
isp1 = kernel_base[symbol];
isp2 = sp->items;
while (found && isp1 < iend)
{
if (*isp1++ != *isp2++)
found = 0;
}
}
if (!found)
{
if (sp->link)
{
sp = sp->link;
}
else /* bucket exhausted and no match */
{
sp = sp->link = new_state(symbol);
found = 1;
}
}
}
}
else /* bucket is empty */
{
state_table[key] = sp = new_state(symbol);
}
return (sp->number);
}
/* subroutine of get_state. create a new state for those items, if necessary. */
core *
new_state(symbol)
int symbol;
{
register int n;
register core *p;
register short *isp1;
register short *isp2;
register short *iend;
#ifdef TRACE
fprintf(stderr, "Entering new_state, symbol = %d\n", symbol);
#endif
if (nstates >= MAXSHORT)
toomany("states");
isp1 = kernel_base[symbol];
iend = kernel_end[symbol];
n = iend - isp1;
p = (core *) xmalloc((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
p->accessing_symbol = symbol;
p->number = nstates;
p->nitems = n;
isp2 = p->items;
while (isp1 < iend)
*isp2++ = *isp1++;
last_state->next = p;
last_state = p;
nstates++;
return (p);
}
void
initialize_states()
{
register core *p;
/* register unsigned *rp1; JF unused */
/* register unsigned *rp2; JF unused */
/* register unsigned *rend; JF unused */
p = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
first_state = last_state = this_state = p;
nstates = 1;
}
void
save_shifts()
{
register shifts *p;
register short *sp1;
register short *sp2;
register short *send;
p = (shifts *) xmalloc((unsigned) (sizeof(shifts) +
(nshifts - 1) * sizeof(short)));
p->number = this_state->number;
p->nshifts = nshifts;
sp1 = shiftset;
sp2 = p->shifts;
send = shiftset + nshifts;
while (sp1 < send)
*sp2++ = *sp1++;
if (last_shift)
{
last_shift->next = p;
last_shift = p;
}
else
{
first_shift = p;
last_shift = p;
}
}
/* find which rules can be used for reduction transitions from the current state
and make a reductions structure for the state to record their rule numbers. */
void
save_reductions()
{
register short *isp;
register short *rp1;
register short *rp2;
register int item;
register int count;
register reductions *p;
short *rend;
/* find and count the active items that represent ends of rules */
count = 0;
for (isp = itemset; isp < itemsetend; isp++)
{
item = ritem[*isp];
if (item < 0)
{
redset[count++] = -item;
}
}
/* make a reductions structure and copy the data into it. */
if (count)
{
p = (reductions *) xmalloc((unsigned) (sizeof(reductions) +
(count - 1) * sizeof(short)));
p->number = this_state->number;
p->nreds = count;
rp1 = redset;
rp2 = p->rules;
rend = rp1 + count;
while (rp1 < rend)
*rp2++ = *rp1++;
if (last_reduction)
{
last_reduction->next = p;
last_reduction = p;
}
else
{
first_reduction = p;
last_reduction = p;
}
}
}
/* Make sure that the initial state has a shift that accepts the
grammar's start symbol and goes to the next-to-final state,
which has a shift going to the final state, which has a shift
to the termination state.
Create such states and shifts if they don't happen to exist already. */
void
augment_automaton()
{
register int i;
register int k;
/* register int found; JF unused */
register core *statep;
register shifts *sp;
register shifts *sp2;
register shifts *sp1;
sp = first_shift;
if (sp)
{
if (sp->number == 0)
{
k = sp->nshifts;
statep = first_state->next;
/* The states reached by shifts from first_state are numbered 1...K.
Look for one reached by start_symbol. */
while (statep->accessing_symbol < start_symbol
&& statep->number < k)
statep = statep->next;
if (statep->accessing_symbol == start_symbol)
{
/* We already have a next-to-final state.
Make sure it has a shift to what will be the final state. */
k = statep->number;
while (sp && sp->number < k)
{
sp1 = sp;
sp = sp->next;
}
if (sp && sp->number == k)
{
sp2 = (shifts *) xmalloc((unsigned) (sizeof(shifts)
+ sp->nshifts * sizeof(short)));
sp2->number = k;
sp2->nshifts = sp->nshifts + 1;
sp2->shifts[0] = nstates;
for (i = sp->nshifts; i > 0; i--)
sp2->shifts[i] = sp->shifts[i - 1];
/* Patch sp2 into the chain of shifts in place of sp,
following sp1. */
sp2->next = sp->next;
sp1->next = sp2;
if (sp == last_shift)
last_shift = sp2;
FREE(sp);
}
else
{
sp2 = NEW(shifts);
sp2->number = k;
sp2->nshifts = 1;
sp2->shifts[0] = nstates;
/* Patch sp2 into the chain of shifts between sp1 and sp. */
sp2->next = sp;
sp1->next = sp2;
if (sp == 0)
last_shift = sp2;
}
}
else
{
/* There is no next-to-final state as yet. */
/* Add one more shift in first_shift,
going to the next-to-final state (yet to be made). */
sp = first_shift;
sp2 = (shifts *) xmalloc(sizeof(shifts)
+ sp->nshifts * sizeof(short));
sp2->nshifts = sp->nshifts + 1;
/* Stick this shift into the vector at the proper place. */
statep = first_state->next;
for (k = 0, i = 0; i < sp->nshifts; k++, i++)
{
if (statep->accessing_symbol > start_symbol && i == k)
sp2->shifts[k++] = nstates;
sp2->shifts[k] = sp->shifts[i];
statep = statep->next;
}
if (i == k)
sp2->shifts[k++] = nstates;
/* Patch sp2 into the chain of shifts
in place of sp, at the beginning. */
sp2->next = sp->next;
first_shift = sp2;
if (last_shift == sp)
last_shift = sp2;
FREE(sp);
/* Create the next-to-final state, with shift to
what will be the final state. */
insert_start_shift();
}
}
else
{
/* The initial state didn't even have any shifts.
Give it one shift, to the next-to-final state. */
sp = NEW(shifts);
sp->nshifts = 1;
sp->shifts[0] = nstates;
/* Patch sp into the chain of shifts at the beginning. */
sp->next = first_shift;
first_shift = sp;
/* Create the next-to-final state, with shift to
what will be the final state. */
insert_start_shift();
}
}
else
{
/* There are no shifts for any state.
Make one shift, from the initial state to the next-to-final state. */
sp = NEW(shifts);
sp->nshifts = 1;
sp->shifts[0] = nstates;
/* Initialize the chain of shifts with sp. */
first_shift = sp;
last_shift = sp;
/* Create the next-to-final state, with shift to
what will be the final state. */
insert_start_shift();
}
/* Make the final state--the one that follows a shift from the
next-to-final state.
The symbol for that shift is 0 (end-of-file). */
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
statep->number = nstates;
last_state->next = statep;
last_state = statep;
/* Make the shift from the final state to the termination state. */
sp = NEW(shifts);
sp->number = nstates++;
sp->nshifts = 1;
sp->shifts[0] = nstates;
last_shift->next = sp;
last_shift = sp;
/* Note that the variable `final_state' refers to what we sometimes call
the termination state. */
final_state = nstates;
/* Make the termination state. */
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
statep->number = nstates++;
last_state->next = statep;
last_state = statep;
}
/* subroutine of augment_automaton.
Create the next-to-final state, to which a shift has already been made in
the initial state. */
void
insert_start_shift()
{
register core *statep;
register shifts *sp;
statep = (core *) xmalloc((unsigned) (sizeof(core) - sizeof(short)));
statep->number = nstates;
statep->accessing_symbol = start_symbol;
last_state->next = statep;
last_state = statep;
/* Make a shift from this state to (what will be) the final state. */
sp = NEW(shifts);
sp->number = nstates++;
sp->nshifts = 1;
sp->shifts[0] = nstates;
last_shift->next = sp;
last_shift = sp;
}

191
contrib/bison/Makefile.in Normal file
View File

@ -0,0 +1,191 @@
# Makefile for bison
# Copyright (C) 1988, 1989, 1991, 1993 Bob Corbett and 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.
#### Start of system configuration section. ####
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
MAKEINFO = makeinfo
# Things you might add to DEFS:
# -DSTDC_HEADERS If you have ANSI C headers and libraries.
# -DHAVE_STRING_H If you don't have ANSI C headers but have string.h.
# -DHAVE_MEMORY_H If you don't have ANSI C headers and have memory.h.
# -DHAVE_STRERROR If you have strerror function.
DEFS = @DEFS@
CFLAGS = -g
LDFLAGS =
LIBS = @LIBS@
# Some System V machines do not come with libPW. If this is true, use
# the GNU alloca.o here.
ALLOCA = @ALLOCA@
prefix = @prefix@
exec_prefix = @exec_prefix@
# where the installed binary goes
bindir = $(exec_prefix)/bin
# where the parsers go
datadir = $(prefix)/share
# where the info files go
infodir = $(prefix)/info
# where manual pages go and what their extensions should be
mandir = $(prefix)/man/man$(manext)
manext = 1
#### End of system configuration section. ####
DISTFILES = COPYING ChangeLog Makefile.in configure configure.in \
REFERENCES bison.1 bison.rnh configure.bat \
bison.simple bison.hairy \
LR0.c allocate.c closure.c conflicts.c derives.c \
files.c getargs.c gram.c lalr.c lex.c main.c nullable.c \
output.c print.c reader.c reduce.c symtab.c version.c \
warshall.c files.h gram.h lex.h machine.h new.h state.h \
symtab.h system.h types.h bison.cld build.com vmsgetargs.c \
vmshlp.mar README INSTALL NEWS bison.texinfo bison.info* texinfo.tex \
getopt.c getopt.h getopt1.c alloca.c mkinstalldirs install-sh
SHELL = /bin/sh
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.o:
$(CC) -c $(DEFS) -I$(srcdir)/../include $(CPPFLAGS) $(CFLAGS) $<
# names of parser files
PFILE = bison.simple
PFILE1 = bison.hairy
PFILES = -DXPFILE=\"$(datadir)/$(PFILE)\" \
-DXPFILE1=\"$(datadir)/$(PFILE1)\"
OBJECTS = LR0.o allocate.o closure.o conflicts.o derives.o files.o \
getargs.o gram.o lalr.o lex.o \
main.o nullable.o output.o print.o reader.o reduce.o symtab.o \
warshall.o version.o \
getopt.o getopt1.o $(ALLOCA)
all: bison bison.info bison.s1
Makefile: Makefile.in config.status
./config.status
config.status: configure
./config.status --recheck
configure: configure.in
cd $(srcdir); autoconf
# Copy bison.simple, inserting directory name into the #line commands.
bison.s1: bison.simple
-rm -f bison.s1
sed -e "/^#line/ s|bison|$(datadir)/bison|" < $(srcdir)/$(PFILE) > bison.s1
clean:
rm -f *.o core bison bison.s1
mostlyclean: clean
distclean: clean
rm -f Makefile config.status
realclean: distclean
rm -f TAGS *.info*
# Most of these deps are in case using RCS.
install: all bison.1 $(srcdir)/$(PFILE) $(srcdir)/$(PFILE1) installdirs uninstall
$(INSTALL_PROGRAM) bison $(bindir)/bison
$(INSTALL_DATA) bison.s1 $(datadir)/$(PFILE)
$(INSTALL_DATA) $(srcdir)/$(PFILE1) $(datadir)/$(PFILE1)
cd $(srcdir); for f in bison.info*; \
do $(INSTALL_DATA) $$f $(infodir)/$$f; done
-$(INSTALL_DATA) $(srcdir)/bison.1 $(mandir)/bison.$(manext)
# Make sure all installation directories, e.g. $(bindir) actually exist by
# making them if necessary.
installdirs:
-sh $(srcdir)/mkinstalldirs $(bindir) $(datadir) $(libdir) $(infodir) $(mandir)
uninstall:
rm -f $(bindir)/bison
-cd $(datadir); rm -f $(PFILE) $(PFILE1)
rm -f $(mandir)/bison.$(manext) $(infodir)/bison.info*
check:
@echo "No checks implemented (yet)."
bison: $(OBJECTS)
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJECTS) $(LIBS)
# We don't use $(srcdir) in this rule
# because it is normally used in the master source dir
# in which configure has not been run.
dist: bison.info
echo bison-`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q version.c` > .fname
-rm -rf `cat .fname`
mkdir `cat .fname`
dst=`cat .fname`; for f in $(DISTFILES); do \
ln $$f $$dst/$$f || { echo copying $$f; cp -p $$f $$dst/$$f ; } \
done
tar --gzip -chf `cat .fname`.tar.gz `cat .fname`
-rm -rf `cat .fname` .fname
bison.info: bison.texinfo
$(MAKEINFO) $(srcdir)/bison.texinfo
TAGS: *.c *.h
etags *.c *.h
# This file is different to pass the parser file names to the compiler.
files.o: files.c
$(CC) -c $(PFILES) $(DEFS) $(CPPFLAGS) $(CFLAGS) \
$(srcdir)/files.c $(OUTPUT_OPTION)
LR0.o: system.h machine.h new.h gram.h state.h
closure.o: system.h machine.h new.h gram.h
conflicts.o: system.h machine.h new.h files.h gram.h state.h
derives.o: system.h new.h types.h gram.h
files.o: system.h files.h new.h gram.h
getargs.o: system.h files.h
lalr.o: system.h machine.h types.h state.h new.h gram.h
lex.o: system.h files.h symtab.h lex.h
main.o: system.h machine.h
nullable.o: system.h types.h gram.h new.h
output.o: system.h machine.h new.h files.h gram.h state.h
print.o: system.h machine.h new.h files.h gram.h state.h
reader.o: system.h files.h new.h symtab.h lex.h gram.h
reduce.o: system.h machine.h files.h new.h gram.h
symtab.o: system.h new.h symtab.h gram.h
warshall.o: system.h machine.h
# Prevent GNU make v3 from overflowing arg limit on SysV.
.NOEXPORT:

44
contrib/bison/NEWS Normal file
View File

@ -0,0 +1,44 @@
Bison News
----------
Change in version 1.25:
* Errors in the input grammar are not fatal; Bison keeps reading
the grammar file, and reports all the errors found in it.
* Tokens can now be specified as multiple-character strings: for
example, you could use "<=" for a token which looks like <=, instead
of chosing a name like LESSEQ.
* The %token_table declaration says to write a table of tokens (names
and numbers) into the parser file. The yylex function can use this
table to recognize multiple-character string tokens, or for other
purposes.
* The %no_lines declaration says not to generate any #line preprocessor
directives in the parser file.
* The %raw declaration says to use internal Bison token numbers, not
Yacc-compatible token numbers, when token names are defined as macros.
* The --no-parser option produces the parser tables without including
the parser engine; a project can now use its own parser engine.
The actions go into a separate file called NAME.act, in the form of
a switch statement body.
Changes in version 1.23:
The user can define YYPARSE_PARAM as the name of an argument to be
passed into yyparse. The argument should have type void *. It should
actually point to an object. Grammar actions can access the variable
by casting it to the proper pointer type.
Line numbers in output file corrected.
Changes in version 1.22:
--help option added.
Changes in version 1.20:
Output file does not redefine const for C++.

15
contrib/bison/README Normal file
View File

@ -0,0 +1,15 @@
This directory contains the Bison parser generator.
See the file INSTALL for compilation and installation instructions.
It was once true that, when installing Bison on Sequent (or Pyramid?)
systems, you had to be in the Berkeley universe. This may no longer
be true; we have no way to tell.
On VMS, you will probably have to create Makefile from Makefile.in by
hand. Remember to do `SET COMMAND BISON' to install the data in
`BISON.CLD'.
Send bug reports to bug-gnu-utils@prep.ai.mit.edu. Please include the
version number from `bison --version', and a complete, self-contained
test case in each bug report.

30
contrib/bison/REFERENCES Normal file
View File

@ -0,0 +1,30 @@
From phr Tue Jul 8 10:36:19 1986
Date: Tue, 8 Jul 86 00:52:24 EDT
From: phr (Paul Rubin)
To: riferguson%watmath.waterloo.edu@CSNET-RELAY.ARPA, tower
Subject: Re: Bison documentation?
The main difference between Bison and Yacc that I know of is that
Bison supports the @N construction, which gives you access to
the starting and ending line number and character number associated
with any of the symbols in the current rule.
Also, Bison supports the command `%expect N' which says not to mention
the conflicts if there are N shift/reduce conflicts and no reduce/reduce
conflicts.
The differences in the algorithms stem mainly from the horrible
kludges that Johnson had to perpetrate to make Yacc fit in a PDP-11.
Also, Bison uses a faster but less space-efficient encoding for the
parse tables (see Corbett's PhD thesis from Berkeley, "Static
Semantics in Compiler Error Recovery", June 1985, Report No. UCB/CSD
85/251), and more modern technique for generating the lookahead sets.
(See "Efficient Construction of LALR(1) Lookahead Sets" by F. DeRemer
and A. Pennello, in ACM TOPLS Vol 4 No 4, October 1982. Their
technique is the standard one now.)
paul rubin
free software foundation

504
contrib/bison/alloca.c Normal file
View File

@ -0,0 +1,504 @@
/* alloca.c -- allocate automatically reclaimed memory
(Mostly) portable public-domain implementation -- D A Gwyn
This implementation of the PWB library alloca function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
J.Otto Tennant <jot@cray.com> contributed the Cray support.
There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef emacs
#include "blockinput.h"
#endif
/* If compiling with GCC 2, this file's not needed. */
#if !defined (__GNUC__) || __GNUC__ < 2
/* If someone has defined alloca as a macro,
there must be some other way alloca is supposed to work. */
#ifndef alloca
#ifdef emacs
#ifdef static
/* actually, only want this if static is defined as ""
-- this is for usg, in which emacs must undefine static
in order to make unexec workable
*/
#ifndef STACK_DIRECTION
you
lose
-- must know STACK_DIRECTION at compile-time
#endif /* STACK_DIRECTION undefined */
#endif /* static */
#endif /* emacs */
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
long i00afunc ();
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
#else
#define ADDRESS_FUNCTION(arg) &(arg)
#endif
#if __STDC__
typedef void *pointer;
#else
typedef char *pointer;
#endif
#ifndef NULL
#define NULL 0
#endif
/* Different portions of Emacs need to call different versions of
malloc. The Emacs executable needs alloca to call xmalloc, because
ordinary malloc isn't protected from input signals. On the other
hand, the utilities in lib-src need alloca to call malloc; some of
them are very simple, and don't have an xmalloc routine.
Non-Emacs programs expect this to call use xmalloc.
Callers below should use malloc. */
#ifndef emacs
#define malloc xmalloc
#endif
extern pointer malloc ();
/* Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* Direction unknown. */
#endif
#if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
#else /* STACK_DIRECTION == 0; need run-time code. */
static int stack_dir; /* 1 or -1 once known. */
#define STACK_DIR stack_dir
static void
find_stack_direction ()
{
static char *addr = NULL; /* Address of first `dummy', once known. */
auto char dummy; /* To get stack address. */
if (addr == NULL)
{ /* Initial entry. */
addr = ADDRESS_FUNCTION (dummy);
find_stack_direction (); /* Recurse once. */
}
else
{
/* Second entry. */
if (ADDRESS_FUNCTION (dummy) > addr)
stack_dir = 1; /* Stack grew upward. */
else
stack_dir = -1; /* Stack grew downward. */
}
}
#endif /* STACK_DIRECTION == 0 */
/* An "alloca header" is used to:
(a) chain together all alloca'ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc
alignment chunk size. The following default should work okay. */
#ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double)
#endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* To force sizeof(header). */
struct
{
union hdr *next; /* For chaining headers. */
char *deep; /* For stack depth measure. */
} h;
} header;
static header *last_alloca_header = NULL; /* -> last alloca header. */
/* Return a pointer to at least SIZE bytes of storage,
which will be automatically reclaimed upon exit from
the procedure that called alloca. Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32. */
pointer
alloca (size)
unsigned size;
{
auto char probe; /* Probes stack depth: */
register char *depth = ADDRESS_FUNCTION (probe);
#if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* Unknown growth direction. */
find_stack_direction ();
#endif
/* Reclaim garbage, defined as all alloca'd storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* Traverses linked list. */
#ifdef emacs
BLOCK_INPUT;
#endif
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
{
register header *np = hp->h.next;
free ((pointer) hp); /* Collect garbage. */
hp = np; /* -> next header. */
}
else
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
#ifdef emacs
UNBLOCK_INPUT;
#endif
}
if (size == 0)
return NULL; /* No allocation required. */
/* Allocate combined header + user data storage. */
{
register pointer new = malloc (sizeof (header) + size);
/* Address of header. */
if (new == 0)
abort();
((header *) new)->h.next = last_alloca_header;
((header *) new)->h.deep = depth;
last_alloca_header = (header *) new;
/* User storage begins just after header. */
return (pointer) ((char *) new + sizeof (header));
}
}
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
#ifdef DEBUG_I00AFUNC
#include <stdio.h>
#endif
#ifndef CRAY_STACK
#define CRAY_STACK
#ifndef CRAY2
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header
{
long shgrow:32; /* Number of times stack has grown. */
long shaseg:32; /* Size of increments to stack. */
long shhwm:32; /* High water mark of stack. */
long shsize:32; /* Current size of stack (all segments). */
};
/* The stack segment linkage control information occurs at
the high-address end of a stack segment. (The stack
grows from low addresses to high addresses.) The initial
part of the stack segment linkage control information is
0200 (octal) words. This provides for register storage
for the routine which overflows the stack. */
struct stack_segment_linkage
{
long ss[0200]; /* 0200 overflow words. */
long sssize:32; /* Number of words in this segment. */
long ssbase:32; /* Offset to stack base. */
long:32;
long sspseg:32; /* Offset to linkage control of previous
segment of stack. */
long:32;
long sstcpt:32; /* Pointer to task common address block. */
long sscsnm; /* Private control structure number for
microtasking. */
long ssusr1; /* Reserved for user. */
long ssusr2; /* Reserved for user. */
long sstpid; /* Process ID for pid based multi-tasking. */
long ssgvup; /* Pointer to multitasking thread giveup. */
long sscray[7]; /* Reserved for Cray Research. */
long ssa0;
long ssa1;
long ssa2;
long ssa3;
long ssa4;
long ssa5;
long ssa6;
long ssa7;
long sss0;
long sss1;
long sss2;
long sss3;
long sss4;
long sss5;
long sss6;
long sss7;
};
#else /* CRAY2 */
/* The following structure defines the vector of words
returned by the STKSTAT library routine. */
struct stk_stat
{
long now; /* Current total stack size. */
long maxc; /* Amount of contiguous space which would
be required to satisfy the maximum
stack demand to date. */
long high_water; /* Stack high-water mark. */
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
long hits; /* Number of internal buffer hits. */
long extends; /* Number of block extensions. */
long stko_mallocs; /* Block allocations by $STKOFEN. */
long underflows; /* Number of stack underflow calls ($STKRETN). */
long stko_free; /* Number of deallocations by $STKRETN. */
long stkm_free; /* Number of deallocations by $STKMRET. */
long segments; /* Current number of stack segments. */
long maxs; /* Maximum number of stack segments so far. */
long pad_size; /* Stack pad size. */
long current_address; /* Current stack segment address. */
long current_size; /* Current stack segment size. This
number is actually corrupted by STKSTAT to
include the fifteen word trailer area. */
long initial_address; /* Address of initial segment. */
long initial_size; /* Size of initial segment. */
};
/* The following structure describes the data structure which trails
any stack segment. I think that the description in 'asdef' is
out of date. I only describe the parts that I am sure about. */
struct stk_trailer
{
long this_address; /* Address of this block. */
long this_size; /* Size of this block (does not include
this trailer). */
long unknown2;
long unknown3;
long link; /* Address of trailer block of previous
segment. */
long unknown5;
long unknown6;
long unknown7;
long unknown8;
long unknown9;
long unknown10;
long unknown11;
long unknown12;
long unknown13;
long unknown14;
};
#endif /* CRAY2 */
#endif /* not CRAY_STACK */
#ifdef CRAY2
/* Determine a "stack measure" for an arbitrary ADDRESS.
I doubt that "lint" will like this much. */
static long
i00afunc (long *address)
{
struct stk_stat status;
struct stk_trailer *trailer;
long *block, size;
long result = 0;
/* We want to iterate through all of the segments. The first
step is to get the stack status structure. We could do this
more quickly and more directly, perhaps, by referencing the
$LM00 common block, but I know that this works. */
STKSTAT (&status);
/* Set up the iteration. */
trailer = (struct stk_trailer *) (status.current_address
+ status.current_size
- 15);
/* There must be at least one stack segment. Therefore it is
a fatal error if "trailer" is null. */
if (trailer == 0)
abort ();
/* Discard segments that do not contain our argument address. */
while (trailer != 0)
{
block = (long *) trailer->this_address;
size = trailer->this_size;
if (block == 0 || size == 0)
abort ();
trailer = (struct stk_trailer *) trailer->link;
if ((block <= address) && (address < (block + size)))
break;
}
/* Set the result to the offset in this segment and add the sizes
of all predecessor segments. */
result = address - block;
if (trailer == 0)
{
return result;
}
do
{
if (trailer->this_size <= 0)
abort ();
result += trailer->this_size;
trailer = (struct stk_trailer *) trailer->link;
}
while (trailer != 0);
/* We are done. Note that if you present a bogus address (one
not in any segment), you will get a different number back, formed
from subtracting the address of the first block. This is probably
not what you want. */
return (result);
}
#else /* not CRAY2 */
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
Determine the number of the cell within the stack,
given the address of the cell. The purpose of this
routine is to linearize, in some sense, stack addresses
for alloca. */
static long
i00afunc (long address)
{
long stkl = 0;
long size, pseg, this_segment, stack;
long result = 0;
struct stack_segment_linkage *ssptr;
/* Register B67 contains the address of the end of the
current stack segment. If you (as a subprogram) store
your registers on the stack and find that you are past
the contents of B67, you have overflowed the segment.
B67 also points to the stack segment linkage control
area, which is what we are really interested in. */
stkl = CRAY_STACKSEG_END ();
ssptr = (struct stack_segment_linkage *) stkl;
/* If one subtracts 'size' from the end of the segment,
one has the address of the first word of the segment.
If this is not the first segment, 'pseg' will be
nonzero. */
pseg = ssptr->sspseg;
size = ssptr->sssize;
this_segment = stkl - size;
/* It is possible that calling this routine itself caused
a stack overflow. Discard stack segments which do not
contain the target address. */
while (!(this_segment <= address && address <= stkl))
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
#endif
if (pseg == 0)
break;
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
this_segment = stkl - size;
}
result = address - this_segment;
/* If you subtract pseg from the current end of the stack,
you get the address of the previous stack segment's end.
This seems a little convoluted to me, but I'll bet you save
a cycle somewhere. */
while (pseg != 0)
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o\n", pseg, size);
#endif
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
result += size;
}
return (result);
}
#endif /* not CRAY2 */
#endif /* CRAY */
#endif /* no alloca */
#endif /* not GCC version 2 */

64
contrib/bison/allocate.c Normal file
View File

@ -0,0 +1,64 @@
/* Allocate and clear storage for bison,
Copyright (C) 1984, 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>
extern char *calloc ();
extern char *realloc ();
extern void done ();
extern char *program_name;
char *
xmalloc (n)
register unsigned n;
{
register char *block;
/* Avoid uncertainty about what an arg of 0 will do. */
if (n == 0)
n = 1;
block = calloc (n, 1);
if (block == NULL)
{
fprintf (stderr, "%s: memory exhausted\n", program_name);
done (1);
}
return (block);
}
char *
xrealloc (block, n)
register char *block;
register unsigned n;
{
/* Avoid uncertainty about what an arg of 0 will do. */
if (n == 0)
n = 1;
block = realloc (block, n);
if (block == NULL)
{
fprintf (stderr, "%s: memory exhausted\n", program_name);
done (1);
}
return (block);
}

342
contrib/bison/bison.1 Normal file
View File

@ -0,0 +1,342 @@
.TH BISON 1 local
.SH NAME
bison \- GNU Project parser generator (yacc replacement)
.SH SYNOPSIS
.B bison
[
.BI \-b " file-prefix"
] [
.BI \-\-file-prefix= file-prefix
] [
.B \-d
] [
.B \-\-defines
] [
.B \-k
] [
.B \-\-token-table
] [
.B \-l
] [
.B \-\-no-lines
] [
.B \-n
] [
.B \-\-no-parser
] [
.BI \-o " outfile"
] [
.BI \-\-output-file= outfile
] [
.BI \-p " prefix"
] [
.BI \-\-name-prefix= prefix
] [
.B \-r
] [
.B \-\-raw
] [
.B \-t
] [
.B \-\-debug
] [
.B \-v
] [
.B \-\-verbose
] [
.B \-V
] [
.B \-\-version
] [
.B \-y
] [
.B \-\-yacc
] [
.B \-h
] [
.B \-\-help
] [
.B \-\-fixed-output-files
]
file
.SH DESCRIPTION
.I Bison
is a parser generator in the style of
.IR yacc (1).
It should be upwardly compatible with input files designed
for
.IR yacc .
.PP
Input files should follow the
.I yacc
convention of ending in
.BR .y .
Unlike
.IR yacc ,
the generated files do not have fixed names, but instead use the prefix
of the input file.
For instance, a grammar description file named
.B parse.y
would produce the generated parser in a file named
.BR parse.tab.c ,
instead of
.IR yacc 's
.BR y.tab.c .
.PP
This description of the options that can be given to
.I bison
is adapted from the node
.B Invocation
in the
.B bison.texinfo
manual, which should be taken as authoritative.
.PP
.I Bison
supports both traditional single-letter options and mnemonic long
option names. Long option names are indicated with
.B \-\-
instead of
.BR \- .
Abbreviations for option names are allowed as long as they
are unique. When a long option takes an argument, like
.BR \-\-file-prefix ,
connect the option name and the argument with
.BR = .
.SS OPTIONS
.TP
.BI \-b " file-prefix"
.br
.ns
.TP
.BI \-\-file-prefix= file-prefix
Specify a prefix to use for all
.I bison
output file names. The names are
chosen as if the input file were named
\fIfile-prefix\fB.c\fR.
.TP
.B \-d
.br
.ns
.TP
.B \-\-defines
Write an extra output file containing macro definitions for the token
type names defined in the grammar and the semantic value type
.BR YYSTYPE ,
as well as a few
.B extern
variable declarations.
.sp
If the parser output file is named
\fIname\fB.c\fR
then this file
is named
\fIname\fB.h\fR.
.sp
This output file is essential if you wish to put the definition of
.B yylex
in a separate source file, because
.B yylex
needs to be able to refer to token type codes and the variable
.BR yylval .
.TP
.B \-r
.br
.ns
.TP
.B \-\-raw
The token numbers in the \fIname\fB.h\fR file are usually the Yacc compatible
translations. If this switch is specified, Bison token numbers
are output instead. (Yacc numbers start at 257 except for single character
tokens; Bison assigns token numbers sequentially for all tokens
starting at 3.)
.TP
.B \-k
.br
.ns
.TP
.B \-\-token-table
This switch causes the \fIname\fB.tab.c\fR output to include a list of
token names in order by their token numbers; this is defined in the array
.IR yytname .
Also generated
are #defines for
.IR YYNTOKENS ,
.IR YYNNTS ,
.IR YYNRULES ,
and
.IR YYNSTATES .
.TP
.B \-l
.br
.ns
.TP
.B \-\-no-lines
Don't put any
.B #line
preprocessor commands in the parser file.
Ordinarily
.I bison
puts them in the parser file so that the C compiler
and debuggers will associate errors with your source file, the
grammar file. This option causes them to associate errors with the
parser file, treating it an independent source file in its own right.
.TP
.B \-n
.br
.ns
.TP
.B \-\-no-parser
Do not generate the parser code into the output; generate only
declarations. The generated \fIname\fB.tab.c\fR file will have only
constant declarations. In addition, a \fIname\fB.act\fR file is
generated containing a switch statement body containing all the
translated actions.
.TP
.BI \-o " outfile"
.br
.ns
.TP
.BI \-\-output-file= outfile
Specify the name
.I outfile
for the parser file.
.sp
The other output files' names are constructed from
.I outfile
as described under the
.B \-v
and
.B \-d
switches.
.TP
.BI \-p " prefix"
.br
.ns
.TP
.BI \-\-name-prefix= prefix
Rename the external symbols used in the parser so that they start with
.I prefix
instead of
.BR yy .
The precise list of symbols renamed is
.BR yyparse ,
.BR yylex ,
.BR yyerror ,
.BR yylval ,
.BR yychar ,
and
.BR yydebug .
.sp
For example, if you use
.BR "\-p c" ,
the names become
.BR cparse ,
.BR clex ,
and so on.
.TP
.B \-t
.br
.ns
.TP
.B \-\-debug
Output a definition of the macro
.B YYDEBUG
into the parser file,
so that the debugging facilities are compiled.
.TP
.B \-v
.br
.ns
.TP
.B \-\-verbose
Write an extra output file containing verbose descriptions of the
parser states and what is done for each type of look-ahead token in
that state.
.sp
This file also describes all the conflicts, both those resolved by
operator precedence and the unresolved ones.
.sp
The file's name is made by removing
.B .tab.c
or
.B .c
from the parser output file name, and adding
.B .output
instead.
.sp
Therefore, if the input file is
.BR foo.y ,
then the parser file is called
.B foo.tab.c
by default. As a consequence, the verbose
output file is called
.BR foo.output .
.TP
.B \-V
.br
.ns
.TP
.B \-\-version
Print the version number of
.I bison
and exit.
.TP
.B \-h
.br
.ns
.TP
.B \-\-help
Print a summary of the options to
.I bison
and exit.
.TP
.B \-y
.br
.ns
.TP
.B \-\-yacc
.br
.ns
.TP
.B \-\-fixed-output-files
Equivalent to
.BR "\-o y.tab.c" ;
the parser output file is called
.BR y.tab.c ,
and the other outputs are called
.B y.output
and
.BR y.tab.h .
The purpose of this switch is to imitate
.IR yacc 's
output file name conventions.
Thus, the following shell script can substitute for
.IR yacc :
.sp
.RS
.ft B
bison \-y $*
.ft R
.sp
.RE
.PP
The long-named options can be introduced with `+' as well as `\-\-',
for compatibility with previous releases. Eventually support for `+'
will be removed, because it is incompatible with the POSIX.2 standard.
.SH FILES
/usr/local/lib/bison.simple simple parser
.br
/usr/local/lib/bison.hairy complicated parser
.SH SEE ALSO
.IR yacc (1)
.br
The
.IR "Bison Reference Manual" ,
included as the file
.B bison.texinfo
in the
.I bison
source distribution.
.SH DIAGNOSTICS
Self explanatory.

21
contrib/bison/bison.cld Normal file
View File

@ -0,0 +1,21 @@
!
! VMS BISON command definition file
!
DEFINE VERB BISON
IMAGE GNU_BISON:[000000]BISON
PARAMETER P1,Label=BISON$INFILE,Prompt="File"
value(required,type=$infile)
QUALIFIER VERBOSE,Label=BISON$VERBOSE
QUALIFIER DEFINES,Label=BISON$DEFINES
QUALIFIER FIXED_OUTFILES,Label=BISON$FIXED_OUTFILES
QUALIFIER NOPARSER,Label=BISON$NOPARSER
QUALIFIER RAW,LABEL=BISON$RAW
QUALIFIER TOKEN_TABLE,LABEL=BISON$TOKEN_TABLE
qualifier nolines,Label=BISON$NOLINES
qualifier debug,Label=BISON$DEBUG
qualifier output,value(type=$outfile),Label=BISON$OUTPUT
qualifier version,label=BISON$VERSION
qualifier yacc,label=BISON$YACC
qualifier file_prefix,value(type=$outfile),label=BISON$FILE_PREFIX
qualifier name_prefix,value(type=$outfile),LABEL=BISON$NAME_PREFIX

334
contrib/bison/bison.hairy Normal file
View File

@ -0,0 +1,334 @@
extern int timeclock;
int yyerror; /* Yyerror and yycost are set by guards. */
int yycost; /* If yyerror is set to a nonzero value by a */
/* guard, the reduction with which the guard */
/* is associated is not performed, and the */
/* error recovery mechanism is invoked. */
/* Yycost indicates the cost of performing */
/* the reduction given the attributes of the */
/* symbols. */
/* YYMAXDEPTH indicates the size of the parser's state and value */
/* stacks. */
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 500
#endif
/* YYMAXRULES must be at least as large as the number of rules that */
/* could be placed in the rule queue. That number could be determined */
/* from the grammar and the size of the stack, but, as yet, it is not. */
#ifndef YYMAXRULES
#define YYMAXRULES 100
#endif
#ifndef YYMAXBACKUP
#define YYMAXBACKUP 100
#endif
short yyss[YYMAXDEPTH]; /* the state stack */
YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
short yyrq[YYMAXRULES]; /* the rule queue */
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
YYSTYPE yytval; /* the semantic value for the state */
/* at the top of the state stack. */
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
YYLTYPE yytloc; /* location data for the state at the */
/* top of the state stack */
int yynunlexed;
short yyunchar[YYMAXBACKUP];
YYSTYPE yyunval[YYMAXBACKUP];
YYLTYPE yyunloc[YYMAXBACKUP];
short *yygssp; /* a pointer to the top of the state */
/* stack; only set during error */
/* recovery. */
YYSTYPE *yygvsp; /* a pointer to the top of the value */
/* stack; only set during error */
/* recovery. */
YYLTYPE *yyglsp; /* a pointer to the top of the */
/* location stack; only set during */
/* error recovery. */
/* Yyget is an interface between the parser and the lexical analyzer. */
/* It is costly to provide such an interface, but it avoids requiring */
/* the lexical analyzer to be able to back up the scan. */
yyget()
{
if (yynunlexed > 0)
{
yynunlexed--;
yychar = yyunchar[yynunlexed];
yylval = yyunval[yynunlexed];
yylloc = yyunloc[yynunlexed];
}
else if (yychar <= 0)
yychar = 0;
else
{
yychar = yylex();
if (yychar < 0)
yychar = 0;
else yychar = YYTRANSLATE(yychar);
}
}
yyunlex(chr, val, loc)
int chr;
YYSTYPE val;
YYLTYPE loc;
{
yyunchar[yynunlexed] = chr;
yyunval[yynunlexed] = val;
yyunloc[yynunlexed] = loc;
yynunlexed++;
}
yyrestore(first, last)
register short *first;
register short *last;
{
register short *ssp;
register short *rp;
register int symbol;
register int state;
register int tvalsaved;
ssp = yygssp;
yyunlex(yychar, yylval, yylloc);
tvalsaved = 0;
while (first != last)
{
symbol = yystos[*ssp];
if (symbol < YYNTBASE)
{
yyunlex(symbol, yytval, yytloc);
tvalsaved = 1;
ssp--;
}
ssp--;
if (first == yyrq)
first = yyrq + YYMAXRULES;
first--;
for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
{
if (symbol < YYNTBASE)
state = yytable[yypact[*ssp] + symbol];
else
{
state = yypgoto[symbol - YYNTBASE] + *ssp;
if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
state = yytable[state];
else
state = yydefgoto[symbol - YYNTBASE];
}
*++ssp = state;
}
}
if ( ! tvalsaved && ssp > yyss)
{
yyunlex(yystos[*ssp], yytval, yytloc);
ssp--;
}
yygssp = ssp;
}
int
yyparse()
{
register int yystate;
register int yyn;
register short *yyssp;
register short *yyrq0;
register short *yyptr;
register YYSTYPE *yyvsp;
int yylen;
YYLTYPE *yylsp;
short *yyrq1;
short *yyrq2;
yystate = 0;
yyssp = yyss - 1;
yyvsp = yyvs - 1;
yylsp = yyls - 1;
yyrq0 = yyrq;
yyrq1 = yyrq0;
yyrq2 = yyrq0;
yychar = yylex();
if (yychar < 0)
yychar = 0;
else yychar = YYTRANSLATE(yychar);
yynewstate:
if (yyssp >= yyss + YYMAXDEPTH - 1)
{
yyabort("Parser Stack Overflow");
YYABORT;
}
*++yyssp = yystate;
yyresume:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
yyn += yychar;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
goto yydefault;
yyn = yytable[yyn];
if (yyn < 0)
{
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
yystate = yyn;
yyptr = yyrq2;
while (yyptr != yyrq1)
{
yyn = *yyptr++;
yylen = yyr2[yyn];
yyvsp -= yylen;
yylsp -= yylen;
yyguard(yyn, yyvsp, yylsp);
if (yyerror)
goto yysemerr;
yyaction(yyn, yyvsp, yylsp);
*++yyvsp = yyval;
yylsp++;
if (yylen == 0)
{
yylsp->timestamp = timeclock;
yylsp->first_line = yytloc.first_line;
yylsp->first_column = yytloc.first_column;
yylsp->last_line = (yylsp-1)->last_line;
yylsp->last_column = (yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line = (yylsp+yylen-1)->last_line;
yylsp->last_column = (yylsp+yylen-1)->last_column;
}
if (yyptr == yyrq + YYMAXRULES)
yyptr = yyrq;
}
if (yystate == YYFINAL)
YYACCEPT;
yyrq2 = yyptr;
yyrq1 = yyrq0;
*++yyvsp = yytval;
*++yylsp = yytloc;
yytval = yylval;
yytloc = yylloc;
yyget();
goto yynewstate;
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
yyreduce:
*yyrq0++ = yyn;
if (yyrq0 == yyrq + YYMAXRULES)
yyrq0 = yyrq;
if (yyrq0 == yyrq2)
{
yyabort("Parser Rule Queue Overflow");
YYABORT;
}
yyssp -= yyr2[yyn];
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yysemerr:
*--yyptr = yyn;
yyrq2 = yyptr;
yyvsp += yyr2[yyn];
yyerrlab:
yygssp = yyssp;
yygvsp = yyvsp;
yyglsp = yylsp;
yyrestore(yyrq0, yyrq2);
yyrecover();
yystate = *yygssp;
yyssp = yygssp;
yyvsp = yygvsp;
yyrq0 = yyrq;
yyrq1 = yyrq0;
yyrq2 = yyrq0;
goto yyresume;
}
$

191
contrib/bison/bison.rnh Normal file
View File

@ -0,0 +1,191 @@
.!
.! RUNOFF source file for BISON.HLP
.!
.! This is a RUNOFF input file which will produce a VMS help file
.! for the VMS HELP library.
.!
.! Eric Youngdale and Wilfred J. Hansen (wjh+@cmu.edu).
.!
.literal
.end literal
.no paging
.no flags all
.right margin 70
.left margin 1
.indent -1
1 BISON
.skip
The BISON command invokes the GNU BISON parser generator.
.skip
.literal
BISON file-spec
.end literal
.skip
.indent -1
2 Parameters
.skip
file-spec
.skip
Here file-spec is the grammar file name, which usually ends in
.y. The parser file's name is made by replacing the .y
with _tab.c. Thus, the command bison foo.y yields
foo_tab.c.
.skip
.indent -1
2 Qualifiers
.skip
The following is the list of available qualifiers for BISON:
.literal
/DEBUG
/DEFINES
/FILE_PREFIX=prefix
/FIXED_OUTFILES
/NAME_PREFIX=prefix
/NOLINES
/NOPARSER
/OUTPUT=outfilefile
/RAW
/TOKEN_TABLE
/VERBOSE
/VERSION
/YACC
.end literal
.skip
.indent -1
2 /DEBUG
.skip
Output a definition of the macro YYDEBUG into the parser file,
so that the debugging facilities are compiled.
.skip
.indent -1
2 /DEFINES
.skip
Write an extra output file containing macro definitions for the token
type names defined in the grammar and the semantic value type
YYSTYPE, as well as a extern variable declarations.
.skip
If the parser output file is named "name.c" then this file
is named "name.h".
.skip
This output file is essential if you wish to put the definition of
yylex in a separate source file, because yylex needs to
be able to refer to token type codes and the variable
yylval.
.skip
.indent -1
2 /FILE_PREFIX
.skip
.literal
/FILIE_PREFIX=prefix
.end literal
.skip
Specify a prefix to use for all Bison output file names. The names are
chosen as if the input file were named prefix.c
.skip
.indent -1
2 /FIXED_OUTFILES
.skip
Equivalent to /OUTPUT=y_tab.c; the parser output file is called
y_tab.c, and the other outputs are called y.output and
y_tab.h. The purpose of this switch is to imitate Yacc's output
file name conventions. The /YACC qualifier is functionally equivalent
to /FIXED_OUTFILES. The following command definition will
work as a substitute for Yacc:
.literal
$YACC:==BISON/FIXED_OUTFILES
.end literal
.skip
.indent -1
2 /NAME_PREFIX
.skip
.literal
/NAME_PREFIX=prefix
.end literal
.skip
Rename the external symbols used in the parser so that they start with
"prefix" instead of "yy". The precise list of symbols renamed
is yyparse, yylex, yyerror, yylval, yychar and yydebug.
For example, if you use /NAME_PREFIX="c", the names become cparse,
clex, and so on.
.skip
.indent -1
2 /NOLINES
.skip
Don't put any "#line" preprocessor commands in the parser file.
Ordinarily Bison puts them in the parser file so that the C compiler
and debuggers will associate errors with your source file, the
grammar file. This option causes them to associate errors with the
parser file, treating it an independent source file in its own right.
.skip
.indent -1
2 /NOPARSER
.skip
Do not generate the parser code into the output; generate only
declarations. The generated name_tab.c file will have only
constant declarations. In addition, a name.act file is
generated containing a switch statement body containing all the
translated actions.
.skip
.indent -1
2 /OUTPUT
.skip
.literal
/OUTPUT=outfile
.end literal
.skip
Specify the name "outfile" for the parser file.
.skip
.indent -1
2 /RAW
.skip
When this switch is specified, the .tab.h file defines the tokens to
have the bison token numbers rather than the yacc compatible numbers.
To employ this switch you would have to have your own parser.
.skip
.indent -1
2 /TOKEN_TABLE
.skip
This switch causes the name_tab.c output to include a list of
token names in order by their token numbers; this is defined in the array
yytname. Also generated are #defines for YYNTOKENS, YYNNTS, YYNRULES,
and YYNSTATES.
.skip
.indent -1
2 /VERBOSE
.skip
Write an extra output file containing verbose descriptions of the
parser states and what is done for each type of look-ahead token in
that state.
.skip
This file also describes all the conflicts, both those resolved by
operator precedence and the unresolved ones.
.skip
The file's name is made by removing _tab.c or .c from
the parser output file name, and adding .output instead.
.skip
Therefore, if the input file is foo.y, then the parser file is
called foo_tab.c by default. As a consequence, the verbose
output file is called foo.output.
.skip
.indent -1
2 /VERSION
.skip
Print the version number of Bison.
.skip
.indent -1
2 /YACC
.skip
See /FIXED_OUTFILES.
.skip
.indent -1

692
contrib/bison/bison.simple Normal file
View File

@ -0,0 +1,692 @@
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
#ifndef alloca
#ifdef __GNUC__
#define alloca __builtin_alloca
#else /* not GNU C. */
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
#include <alloca.h>
#else /* not sparc */
#if defined (MSDOS) && !defined (__TURBOC__)
#include <malloc.h>
#else /* not MSDOS, or __TURBOC__ */
#if defined(_AIX)
#include <malloc.h>
#pragma alloca
#else /* not MSDOS, __TURBOC__, or _AIX */
#ifdef __hpux
#ifdef __cplusplus
extern "C" {
void *alloca (unsigned int);
};
#else /* not __cplusplus */
void *alloca ();
#endif /* not __cplusplus */
#endif /* __hpux */
#endif /* not _AIX */
#endif /* not MSDOS, or __TURBOC__ */
#endif /* not sparc. */
#endif /* not GNU C. */
#endif /* alloca not defined. */
/* This is the parser code that is written into each bison parser
when the %semantic_parser declaration is not specified in the grammar.
It was written by Richard Stallman by simplifying the hairy parser
used when %semantic_parser is specified. */
/* Note: there must be only one dollar sign in this file.
It is replaced by the list of actions, each action
as one case of the switch. */
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYERROR goto yyerrlab1
/* Like YYERROR except do call yyerror.
This remains here temporarily to ease the
transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(token, value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ yychar = (token), yylval = (value); \
yychar1 = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{ yyerror ("syntax error: cannot back up"); YYERROR; } \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
#ifndef YYPURE
#define YYLEX yylex()
#endif
#ifdef YYPURE
#ifdef YYLSP_NEEDED
#ifdef YYLEX_PARAM
#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
#else
#define YYLEX yylex(&yylval, &yylloc)
#endif
#else /* not YYLSP_NEEDED */
#ifdef YYLEX_PARAM
#define YYLEX yylex(&yylval, YYLEX_PARAM)
#else
#define YYLEX yylex(&yylval)
#endif
#endif /* not YYLSP_NEEDED */
#endif
/* If nonreentrant, generate the variables here */
#ifndef YYPURE
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
#ifdef YYLSP_NEEDED
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
#endif
int yynerrs; /* number of parse errors so far */
#endif /* not YYPURE */
#if YYDEBUG != 0
int yydebug; /* nonzero means print parse trace */
/* Since this is uninitialized, it does not stop multiple parsers
from coexisting. */
#endif
/* YYINITDEPTH indicates the initial size of the parser's stacks */
#ifndef YYINITDEPTH
#define YYINITDEPTH 200
#endif
/* YYMAXDEPTH is the maximum size the stacks can grow to
(effective only if the built-in stack extension method is used). */
#if YYMAXDEPTH == 0
#undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif
/* Prevent warning if -Wstrict-prototypes. */
#ifdef __GNUC__
int yyparse (void);
#endif
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or C++ */
#ifndef __cplusplus
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
__yy_memcpy (to, from, count)
char *to;
char *from;
int count;
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
#else /* __cplusplus */
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
__yy_memcpy (char *to, char *from, int count)
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
#endif
#endif
#line 196 "bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
It should actually point to an object.
Grammar actions can access the variable by casting it
to the proper pointer type. */
#ifdef YYPARSE_PARAM
#ifdef __cplusplus
#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
#define YYPARSE_PARAM_DECL
#else /* not __cplusplus */
#define YYPARSE_PARAM_ARG YYPARSE_PARAM
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
#endif /* not __cplusplus */
#else /* not YYPARSE_PARAM */
#define YYPARSE_PARAM_ARG
#define YYPARSE_PARAM_DECL
#endif /* not YYPARSE_PARAM */
int
yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
{
register int yystate;
register int yyn;
register short *yyssp;
register YYSTYPE *yyvsp;
int yyerrstatus; /* number of tokens to shift before error messages enabled */
int yychar1 = 0; /* lookahead token as an internal (translated) token number */
short yyssa[YYINITDEPTH]; /* the state stack */
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
#ifdef YYLSP_NEEDED
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
#else
#define YYPOPSTACK (yyvsp--, yyssp--)
#endif
int yystacksize = YYINITDEPTH;
#ifdef YYPURE
int yychar;
YYSTYPE yylval;
int yynerrs;
#ifdef YYLSP_NEEDED
YYLTYPE yylloc;
#endif
#endif
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int yylen;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Starting parse\n");
#endif
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
yyssp = yyss - 1;
yyvsp = yyvs;
#ifdef YYLSP_NEEDED
yylsp = yyls;
#endif
/* Push a new state, which is found in yystate . */
/* In all cases, when you get here, the value and location stacks
have just been pushed. so pushing a state here evens the stacks. */
yynewstate:
*++yyssp = yystate;
if (yyssp >= yyss + yystacksize - 1)
{
/* Give user a chance to reallocate the stack */
/* Use copies of these so that the &'s don't force the real ones into memory. */
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
#ifdef YYLSP_NEEDED
YYLTYPE *yyls1 = yyls;
#endif
/* Get the current used size of the three stacks, in elements. */
int size = yyssp - yyss + 1;
#ifdef yyoverflow
/* Each stack pointer address is followed by the size of
the data in use in that stack, in bytes. */
#ifdef YYLSP_NEEDED
/* This used to be a conditional around just the two extra args,
but that might be undefined if yyoverflow is a macro. */
yyoverflow("parser stack overflow",
&yyss1, size * sizeof (*yyssp),
&yyvs1, size * sizeof (*yyvsp),
&yyls1, size * sizeof (*yylsp),
&yystacksize);
#else
yyoverflow("parser stack overflow",
&yyss1, size * sizeof (*yyssp),
&yyvs1, size * sizeof (*yyvsp),
&yystacksize);
#endif
yyss = yyss1; yyvs = yyvs1;
#ifdef YYLSP_NEEDED
yyls = yyls1;
#endif
#else /* no yyoverflow */
/* Extend the stack our own way. */
if (yystacksize >= YYMAXDEPTH)
{
yyerror("parser stack overflow");
return 2;
}
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
__yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
__yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
__yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
yyssp = yyss + size - 1;
yyvsp = yyvs + size - 1;
#ifdef YYLSP_NEEDED
yylsp = yyls + size - 1;
#endif
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Stack size increased to %d\n", yystacksize);
#endif
if (yyssp >= yyss + yystacksize - 1)
YYABORT;
}
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Entering state %d\n", yystate);
#endif
goto yybackup;
yybackup:
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
/* yyresume: */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* yychar is either YYEMPTY or YYEOF
or a valid token in external form. */
if (yychar == YYEMPTY)
{
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Reading a token: ");
#endif
yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Now at end of input.\n");
#endif
}
else
{
yychar1 = YYTRANSLATE(yychar);
#if YYDEBUG != 0
if (yydebug)
{
fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
/* Give the individual parser a way to print the precise meaning
of a token, for further debugging info. */
#ifdef YYPRINT
YYPRINT (stderr, yychar, yylval);
#endif
fprintf (stderr, ")\n");
}
#endif
}
yyn += yychar1;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
goto yydefault;
yyn = yytable[yyn];
/* yyn is what to do for this token type in this state.
Negative => reduce, -yyn is rule number.
Positive => shift, yyn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
#endif
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
/* count tokens shifted since error; after three, turn off error status. */
if (yyerrstatus) yyerrstatus--;
yystate = yyn;
goto yynewstate;
/* Do the default action for the current state. */
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
/* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce:
yylen = yyr2[yyn];
if (yylen > 0)
yyval = yyvsp[1-yylen]; /* implement default value of the action */
#if YYDEBUG != 0
if (yydebug)
{
int i;
fprintf (stderr, "Reducing via rule %d (line %d), ",
yyn, yyrline[yyn]);
/* Print the symbols being reduced, and their result. */
for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
fprintf (stderr, "%s ", yytname[yyrhs[i]]);
fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
}
#endif
$ /* the action file gets copied in in place of this dollarsign */
#line 498 "bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
#ifdef YYLSP_NEEDED
yylsp -= yylen;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
*++yyvsp = yyval;
#ifdef YYLSP_NEEDED
yylsp++;
if (yylen == 0)
{
yylsp->first_line = yylloc.first_line;
yylsp->first_column = yylloc.first_column;
yylsp->last_line = (yylsp-1)->last_line;
yylsp->last_column = (yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line = (yylsp+yylen-1)->last_line;
yylsp->last_column = (yylsp+yylen-1)->last_column;
}
#endif
/* Now "shift" the result of the reduction.
Determine what state that goes to,
based on the state we popped back to
and the rule number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yyerrlab: /* here on detecting error */
if (! yyerrstatus)
/* If not already recovering from an error, report this error. */
{
++yynerrs;
#ifdef YYERROR_VERBOSE
yyn = yypact[yystate];
if (yyn > YYFLAG && yyn < YYLAST)
{
int size = 0;
char *msg;
int x, count;
count = 0;
/* Start X at -yyn if nec to avoid negative indexes in yycheck. */
for (x = (yyn < 0 ? -yyn : 0);
x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
size += strlen(yytname[x]) + 15, count++;
msg = (char *) malloc(size + 15);
if (msg != 0)
{
strcpy(msg, "parse error");
if (count < 5)
{
count = 0;
for (x = (yyn < 0 ? -yyn : 0);
x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
{
strcat(msg, count == 0 ? ", expecting `" : " or `");
strcat(msg, yytname[x]);
strcat(msg, "'");
count++;
}
}
yyerror(msg);
free(msg);
}
else
yyerror ("parse error; also virtual memory exceeded");
}
else
#endif /* YYERROR_VERBOSE */
yyerror("parse error");
}
goto yyerrlab1;
yyerrlab1: /* here on error raised explicitly by an action */
if (yyerrstatus == 3)
{
/* if just tried and failed to reuse lookahead token after an error, discard it. */
/* return failure if at end of input */
if (yychar == YYEOF)
YYABORT;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
#endif
yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token
after shifting the error token. */
yyerrstatus = 3; /* Each real token shifted decrements this */
goto yyerrhandle;
yyerrdefault: /* current state does not do anything special for the error token. */
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
if (yyn) goto yydefault;
#endif
yyerrpop: /* pop the current state because it cannot handle the error token */
if (yyssp == yyss) YYABORT;
yyvsp--;
yystate = *--yyssp;
#ifdef YYLSP_NEEDED
yylsp--;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "Error: state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Shifting error token, ");
#endif
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
yystate = yyn;
goto yynewstate;
}

5435
contrib/bison/bison.texinfo Normal file

File diff suppressed because it is too large Load Diff

83
contrib/bison/build.com Normal file
View File

@ -0,0 +1,83 @@
$! Set the def dir to proper place for use in batch. Works for interactive too.
$flnm = f$enviroment("PROCEDURE") ! get current procedure name
$set default 'f$parse(flnm,,,"DEVICE")''f$parse(flnm,,,"DIRECTORY")'
$!
$! This command procedure compiles and links BISON for VMS.
$! BISON has been tested with VAXC version 2.3 and VMS version 4.5
$! and on VMS 4.5 with GCC 1.12.
$!
$! Bj|rn Larsen blarsen@ifi.uio.no
$! With some contributions by Gabor Karsai,
$! KARSAIG1%VUENGVAX.BITNET@jade.berkeley.edu
$! All merged and cleaned by RMS.
$!
$! Adapted for both VAX-11 "C" and VMS/GCC compilation by
$! David L. Kashtan kashtan.iu.ai.sri.com
$!
$! First we try to sense which C compiler we have available. Sensing logic
$! borrowed from Emacs.
$!
$set noon !do not bomb if an error occurs.
$assign nla0: sys$output
$assign nla0: sys$error !so we do not get an error message about this.
$cc nla0:compiler_check.c
$if $status.eq.%x38090 then goto try_gcc
$ CC :== CC
$ cc_options:="/NOLIST/define=(""index=strchr"",""rindex=strrchr"")"
$ extra_linker_files:="VMSHLP,"
$goto have_compiler
$!
$try_gcc:
$gcc nla0:compiler_check.c
$if $status.eq.%x38090 then goto whoops
$ CC :== GCC
$ cc_options:="/DEBUG"
$ extra_linker_files:="GNU_CC:[000000]GCCLIB/LIB,"
$goto have_compiler
$!
$whoops:
$write sys$output "You must have a C compiler to build BISON. Sorry."
$deassign sys$output
$deassign sys$error
$exit %x38090
$!
$!
$have_compiler:
$deassign sys$output
$deassign sys$error
$set on
$if f$search("compiler_check.obj").nes."" then dele/nolog compiler_check.obj;
$write sys$output "Building BISON with the ''cc' compiler."
$!
$! Do the compilation (compiler type is all set up)
$!
$ Compile:
$ if "''p1'" .eqs. "LINK" then goto Link
$ 'CC' 'cc_options' files.c
$ 'CC' 'cc_options' LR0.C
$ 'CC' 'cc_options' ALLOCATE.C
$ 'CC' 'cc_options' CLOSURE.C
$ 'CC' 'cc_options' CONFLICTS.C
$ 'CC' 'cc_options' DERIVES.C
$ 'CC' 'cc_options' VMSGETARGS.C
$ 'CC' 'cc_options' GRAM.C
$ 'CC' 'cc_options' LALR.C
$ 'CC' 'cc_options' LEX.C
$ 'CC' 'cc_options' MAIN.C
$ 'CC' 'cc_options' NULLABLE.C
$ 'CC' 'cc_options' OUTPUT.C
$ 'CC' 'cc_options' PRINT.C
$ 'CC' 'cc_options' READER.C
$ 'CC' 'cc_options' REDUCE.C
$ 'CC' 'cc_options' SYMTAB.C
$ 'CC' 'cc_options' WARSHALL.C
$ 'CC' 'cc_options' VERSION.C
$ if "''CC'" .eqs. "CC" then macro vmshlp.mar
$ Link:
$ link/exec=bison main,LR0,allocate,closure,conflicts,derives,files,-
vmsgetargs,gram,lalr,lex,nullable,output,print,reader,reduce,symtab,warshall,-
version,'extra_linker_files'sys$library:vaxcrtl/lib
$!
$! Generate bison.hlp (for online help).
$!
$runoff bison.rnh

351
contrib/bison/closure.c Normal file
View File

@ -0,0 +1,351 @@
/* Subroutines for bison
Copyright (C) 1984, 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. */
/* subroutines of file LR0.c.
Entry points:
closure (items, n)
Given a vector of item numbers items, of length n,
set up ruleset and itemset to indicate what rules could be run
and which items could be accepted when those items are the active ones.
ruleset contains a bit for each rule. closure sets the bits
for all rules which could potentially describe the next input to be read.
itemset is a vector of item numbers; itemsetend points to just beyond the end
of the part of it that is significant.
closure places there the indices of all items which represent units of
input that could arrive next.
initialize_closure (n)
Allocates the itemset and ruleset vectors,
and precomputes useful data so that closure can be called.
n is the number of elements to allocate for itemset.
finalize_closure ()
Frees itemset, ruleset and internal data.
*/
#include <stdio.h>
#include "system.h"
#include "machine.h"
#include "new.h"
#include "gram.h"
extern short **derives;
extern char **tags;
void set_fderives();
void set_firsts();
extern void RTC();
short *itemset;
short *itemsetend;
static unsigned *ruleset;
/* internal data. See comments before set_fderives and set_firsts. */
static unsigned *fderives;
static unsigned *firsts;
/* number of words required to hold a bit for each rule */
static int rulesetsize;
/* number of words required to hold a bit for each variable */
static int varsetsize;
void
initialize_closure(n)
int n;
{
itemset = NEW2(n, short);
rulesetsize = WORDSIZE(nrules + 1);
ruleset = NEW2(rulesetsize, unsigned);
set_fderives();
}
/* set fderives to an nvars by nrules matrix of bits
indicating which rules can help derive the beginning of the data
for each nonterminal. For example, if symbol 5 can be derived as
the sequence of symbols 8 3 20, and one of the rules for deriving
symbol 8 is rule 4, then the [5 - ntokens, 4] bit in fderives is set. */
void
set_fderives()
{
register unsigned *rrow;
register unsigned *vrow;
register int j;
register unsigned cword;
register short *rp;
register int b;
int ruleno;
int i;
fderives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
set_firsts();
rrow = fderives + ntokens * rulesetsize;
for (i = ntokens; i < nsyms; i++)
{
vrow = firsts + ((i - ntokens) * varsetsize);
cword = *vrow++;
b = 0;
for (j = ntokens; j < nsyms; j++)
{
if (cword & (1 << b))
{
rp = derives[j];
while ((ruleno = *rp++) > 0)
{
SETBIT(rrow, ruleno);
}
}
b++;
if (b >= BITS_PER_WORD && j + 1 < nsyms)
{
cword = *vrow++;
b = 0;
}
}
rrow += rulesetsize;
}
#ifdef DEBUG
print_fderives();
#endif
FREE(firsts);
}
/* set firsts to be an nvars by nvars bit matrix indicating which items
can represent the beginning of the input corresponding to which other items.
For example, if some rule expands symbol 5 into the sequence of symbols 8 3 20,
the symbol 8 can be the beginning of the data for symbol 5,
so the bit [8 - ntokens, 5 - ntokens] in firsts is set. */
void
set_firsts()
{
register unsigned *row;
/* register int done; JF unused */
register int symbol;
register short *sp;
register int rowsize;
int i;
varsetsize = rowsize = WORDSIZE(nvars);
firsts = NEW2(nvars * rowsize, unsigned);
row = firsts;
for (i = ntokens; i < nsyms; i++)
{
sp = derives[i];
while (*sp >= 0)
{
symbol = ritem[rrhs[*sp++]];
if (ISVAR(symbol))
{
symbol -= ntokens;
SETBIT(row, symbol);
}
}
row += rowsize;
}
RTC(firsts, nvars);
#ifdef DEBUG
print_firsts();
#endif
}
void
closure(core, n)
short *core;
int n;
{
register int ruleno;
register unsigned word;
register short *csp;
register unsigned *dsp;
register unsigned *rsp;
short *csend;
unsigned *rsend;
int symbol;
int itemno;
rsp = ruleset;
rsend = ruleset + rulesetsize;
csend = core + n;
if (n == 0)
{
dsp = fderives + start_symbol * rulesetsize;
while (rsp < rsend)
*rsp++ = *dsp++;
}
else
{
while (rsp < rsend)
*rsp++ = 0;
csp = core;
while (csp < csend)
{
symbol = ritem[*csp++];
if (ISVAR(symbol))
{
dsp = fderives + symbol * rulesetsize;
rsp = ruleset;
while (rsp < rsend)
*rsp++ |= *dsp++;
}
}
}
ruleno = 0;
itemsetend = itemset;
csp = core;
rsp = ruleset;
while (rsp < rsend)
{
word = *rsp++;
if (word == 0)
{
ruleno += BITS_PER_WORD;
}
else
{
register int b;
for (b = 0; b < BITS_PER_WORD; b++)
{
if (word & (1 << b))
{
itemno = rrhs[ruleno];
while (csp < csend && *csp < itemno)
*itemsetend++ = *csp++;
*itemsetend++ = itemno;
}
ruleno++;
}
}
}
while (csp < csend)
*itemsetend++ = *csp++;
#ifdef DEBUG
print_closure(n);
#endif
}
void
finalize_closure()
{
FREE(itemset);
FREE(ruleset);
FREE(fderives + ntokens * rulesetsize);
}
#ifdef DEBUG
print_closure(n)
int n;
{
register short *isp;
printf("\n\nn = %d\n\n", n);
for (isp = itemset; isp < itemsetend; isp++)
printf(" %d\n", *isp);
}
print_firsts()
{
register int i;
register int j;
register unsigned *rowp;
printf("\n\n\nFIRSTS\n\n");
for (i = ntokens; i < nsyms; i++)
{
printf("\n\n%s firsts\n\n", tags[i]);
rowp = firsts + ((i - ntokens) * varsetsize);
for (j = 0; j < nvars; j++)
if (BITISSET (rowp, j))
printf(" %s\n", tags[j + ntokens]);
}
}
print_fderives()
{
register int i;
register int j;
register unsigned *rp;
printf("\n\n\nFDERIVES\n");
for (i = ntokens; i < nsyms; i++)
{
printf("\n\n%s derives\n\n", tags[i]);
rp = fderives + i * rulesetsize;
for (j = 0; j <= nrules; j++)
if (BITISSET (rp, j))
printf(" %d\n", j);
}
fflush(stdout);
}
#endif

1498
contrib/bison/configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
@echo off
echo Configuring bison for go32
rem This batch file assumes a unix-type "sed" program
echo # Makefile generated by "configure.bat"> Makefile
echo all.dos : bison >> Makefile
if exist config.sed del config.sed
echo "s/@srcdir@/./g ">> config.sed
echo "s/@CC@/gcc/g ">> config.sed
echo "s/@INSTALL@//g ">> config.sed
echo "s/@INSTALL_PROGRAM@//g ">> config.sed
echo "s/@INSTALL_DATA@//g ">> config.sed
echo "s/@DEFS@/-DHAVE_STRERROR/g ">> config.sed
echo "s/@LIBS@//g ">> config.sed
echo "s/@ALLOCA@//g ">> config.sed
echo "/^bison[ ]*:/,/-o/ { ">> config.sed
echo " s/ \$(CC)/ >bison.rf/ ">> config.sed
echo " /-o/ a\ ">> config.sed
echo " $(CC) @bison.rf ">> config.sed
echo "} ">> config.sed
sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
sed -f config2.sed Makefile.in >> Makefile
del config.sed
del config2.sed

View File

@ -0,0 +1,22 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(reduce.c)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_MINIX
AC_ISC_POSIX
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(string.h stdlib.h memory.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
dnl Checks for library functions.
AC_FUNC_ALLOCA
AC_CHECK_FUNCS(strerror)
AC_OUTPUT(Makefile)

753
contrib/bison/conflicts.c Normal file
View File

@ -0,0 +1,753 @@
/* Find and resolve or report look-ahead conflicts for bison,
Copyright (C) 1984, 1989, 1992 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"
#include "new.h"
#include "files.h"
#include "gram.h"
#include "state.h"
extern char **tags;
extern int tokensetsize;
extern char *consistent;
extern short *accessing_symbol;
extern shifts **shift_table;
extern unsigned *LA;
extern short *LAruleno;
extern short *lookaheads;
extern int verboseflag;
void set_conflicts();
void resolve_sr_conflict();
void flush_shift();
void log_resolution();
void total_conflicts();
void count_sr_conflicts();
void count_rr_conflicts();
char any_conflicts;
char *conflicts;
errs **err_table;
int expected_conflicts;
static unsigned *shiftset;
static unsigned *lookaheadset;
static int src_total;
static int rrc_total;
static int src_count;
static int rrc_count;
void
initialize_conflicts()
{
register int i;
/* register errs *sp; JF unused */
conflicts = NEW2(nstates, char);
shiftset = NEW2(tokensetsize, unsigned);
lookaheadset = NEW2(tokensetsize, unsigned);
err_table = NEW2(nstates, errs *);
any_conflicts = 0;
for (i = 0; i < nstates; i++)
set_conflicts(i);
}
void
set_conflicts(state)
int state;
{
register int i;
register int k;
register shifts *shiftp;
register unsigned *fp2;
register unsigned *fp3;
register unsigned *fp4;
register unsigned *fp1;
register int symbol;
if (consistent[state]) return;
for (i = 0; i < tokensetsize; i++)
lookaheadset[i] = 0;
shiftp = shift_table[state];
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
SETBIT(lookaheadset, symbol);
}
}
k = lookaheads[state + 1];
fp4 = lookaheadset + tokensetsize;
/* loop over all rules which require lookahead in this state */
/* first check for shift-reduce conflict, and try to resolve using precedence */
for (i = lookaheads[state]; i < k; i++)
if (rprec[LAruleno[i]])
{
fp1 = LA + i * tokensetsize;
fp2 = fp1;
fp3 = lookaheadset;
while (fp3 < fp4)
{
if (*fp2++ & *fp3++)
{
resolve_sr_conflict(state, i);
break;
}
}
}
/* loop over all rules which require lookahead in this state */
/* Check for conflicts not resolved above. */
for (i = lookaheads[state]; i < k; i++)
{
fp1 = LA + i * tokensetsize;
fp2 = fp1;
fp3 = lookaheadset;
while (fp3 < fp4)
{
if (*fp2++ & *fp3++)
{
conflicts[state] = 1;
any_conflicts = 1;
}
}
fp2 = fp1;
fp3 = lookaheadset;
while (fp3 < fp4)
*fp3++ |= *fp2++;
}
}
/* Attempt to resolve shift-reduce conflict for one rule
by means of precedence declarations.
It has already been checked that the rule has a precedence.
A conflict is resolved by modifying the shift or reduce tables
so that there is no longer a conflict. */
void
resolve_sr_conflict(state, lookaheadnum)
int state;
int lookaheadnum;
{
register int i;
register int mask;
register unsigned *fp1;
register unsigned *fp2;
register int redprec;
errs *errp = (errs *) xmalloc (sizeof(errs) + ntokens * sizeof(short));
short *errtokens = errp->errs;
/* find the rule to reduce by to get precedence of reduction */
redprec = rprec[LAruleno[lookaheadnum]];
mask = 1;
fp1 = LA + lookaheadnum * tokensetsize;
fp2 = lookaheadset;
for (i = 0; i < ntokens; i++)
{
if ((mask & *fp2 & *fp1) && sprec[i])
/* Shift-reduce conflict occurs for token number i
and it has a precedence.
The precedence of shifting is that of token i. */
{
if (sprec[i] < redprec)
{
if (verboseflag) log_resolution(state, lookaheadnum, i, "reduce");
*fp2 &= ~mask; /* flush the shift for this token */
flush_shift(state, i);
}
else if (sprec[i] > redprec)
{
if (verboseflag) log_resolution(state, lookaheadnum, i, "shift");
*fp1 &= ~mask; /* flush the reduce for this token */
}
else
{
/* Matching precedence levels.
For left association, keep only the reduction.
For right association, keep only the shift.
For nonassociation, keep neither. */
switch (sassoc[i])
{
case RIGHT_ASSOC:
if (verboseflag) log_resolution(state, lookaheadnum, i, "shift");
break;
case LEFT_ASSOC:
if (verboseflag) log_resolution(state, lookaheadnum, i, "reduce");
break;
case NON_ASSOC:
if (verboseflag) log_resolution(state, lookaheadnum, i, "an error");
break;
}
if (sassoc[i] != RIGHT_ASSOC)
{
*fp2 &= ~mask; /* flush the shift for this token */
flush_shift(state, i);
}
if (sassoc[i] != LEFT_ASSOC)
{
*fp1 &= ~mask; /* flush the reduce for this token */
}
if (sassoc[i] == NON_ASSOC)
{
/* Record an explicit error for this token. */
*errtokens++ = i;
}
}
}
mask <<= 1;
if (mask == 0)
{
mask = 1;
fp2++; fp1++;
}
}
errp->nerrs = errtokens - errp->errs;
if (errp->nerrs)
{
/* Some tokens have been explicitly made errors. Allocate
a permanent errs structure for this state, to record them. */
i = (char *) errtokens - (char *) errp;
err_table[state] = (errs *) xmalloc ((unsigned int)i);
bcopy (errp, err_table[state], i);
}
else
err_table[state] = 0;
free(errp);
}
/* turn off the shift recorded for the specified token in the specified state.
Used when we resolve a shift-reduce conflict in favor of the reduction. */
void
flush_shift(state, token)
int state;
int token;
{
register shifts *shiftp;
register int k, i;
/* register unsigned symbol; JF unused */
shiftp = shift_table[state];
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (shiftp->shifts[i] && token == accessing_symbol[shiftp->shifts[i]])
(shiftp->shifts[i]) = 0;
}
}
}
void
log_resolution(state, LAno, token, resolution)
int state, LAno, token;
char *resolution;
{
fprintf(foutput,
"Conflict in state %d between rule %d and token %s resolved as %s.\n",
state, LAruleno[LAno], tags[token], resolution);
}
void
conflict_log()
{
register int i;
src_total = 0;
rrc_total = 0;
for (i = 0; i < nstates; i++)
{
if (conflicts[i])
{
count_sr_conflicts(i);
count_rr_conflicts(i);
src_total += src_count;
rrc_total += rrc_count;
}
}
total_conflicts();
}
void
verbose_conflict_log()
{
register int i;
src_total = 0;
rrc_total = 0;
for (i = 0; i < nstates; i++)
{
if (conflicts[i])
{
count_sr_conflicts(i);
count_rr_conflicts(i);
src_total += src_count;
rrc_total += rrc_count;
fprintf(foutput, "State %d contains", i);
if (src_count == 1)
fprintf(foutput, " 1 shift/reduce conflict");
else if (src_count > 1)
fprintf(foutput, " %d shift/reduce conflicts", src_count);
if (src_count > 0 && rrc_count > 0)
fprintf(foutput, " and");
if (rrc_count == 1)
fprintf(foutput, " 1 reduce/reduce conflict");
else if (rrc_count > 1)
fprintf(foutput, " %d reduce/reduce conflicts", rrc_count);
putc('.', foutput);
putc('\n', foutput);
}
}
total_conflicts();
}
void
total_conflicts()
{
extern int fixed_outfiles;
if (src_total == expected_conflicts && rrc_total == 0)
return;
if (fixed_outfiles)
{
/* If invoked under the name `yacc', use the output format
specified by POSIX. */
fprintf(stderr, "conflicts: ");
if (src_total > 0)
fprintf(stderr, " %d shift/reduce", src_total);
if (src_total > 0 && rrc_total > 0)
fprintf(stderr, ",");
if (rrc_total > 0)
fprintf(stderr, " %d reduce/reduce", rrc_total);
putc('\n', stderr);
}
else
{
fprintf(stderr, "%s contains", infile);
if (src_total == 1)
fprintf(stderr, " 1 shift/reduce conflict");
else if (src_total > 1)
fprintf(stderr, " %d shift/reduce conflicts", src_total);
if (src_total > 0 && rrc_total > 0)
fprintf(stderr, " and");
if (rrc_total == 1)
fprintf(stderr, " 1 reduce/reduce conflict");
else if (rrc_total > 1)
fprintf(stderr, " %d reduce/reduce conflicts", rrc_total);
putc('.', stderr);
putc('\n', stderr);
}
}
void
count_sr_conflicts(state)
int state;
{
register int i;
register int k;
register int mask;
register shifts *shiftp;
register unsigned *fp1;
register unsigned *fp2;
register unsigned *fp3;
register int symbol;
src_count = 0;
shiftp = shift_table[state];
if (!shiftp) return;
for (i = 0; i < tokensetsize; i++)
{
shiftset[i] = 0;
lookaheadset[i] = 0;
}
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
SETBIT(shiftset, symbol);
}
k = lookaheads[state + 1];
fp3 = lookaheadset + tokensetsize;
for (i = lookaheads[state]; i < k; i++)
{
fp1 = LA + i * tokensetsize;
fp2 = lookaheadset;
while (fp2 < fp3)
*fp2++ |= *fp1++;
}
fp1 = shiftset;
fp2 = lookaheadset;
while (fp2 < fp3)
*fp2++ &= *fp1++;
mask = 1;
fp2 = lookaheadset;
for (i = 0; i < ntokens; i++)
{
if (mask & *fp2)
src_count++;
mask <<= 1;
if (mask == 0)
{
mask = 1;
fp2++;
}
}
}
void
count_rr_conflicts(state)
int state;
{
register int i;
register int j;
register int count;
register unsigned mask;
register unsigned *baseword;
register unsigned *wordp;
register int m;
register int n;
rrc_count = 0;
m = lookaheads[state];
n = lookaheads[state + 1];
if (n - m < 2) return;
mask = 1;
baseword = LA + m * tokensetsize;
for (i = 0; i < ntokens; i++)
{
wordp = baseword;
count = 0;
for (j = m; j < n; j++)
{
if (mask & *wordp)
count++;
wordp += tokensetsize;
}
if (count >= 2) rrc_count++;
mask <<= 1;
if (mask == 0)
{
mask = 1;
baseword++;
}
}
}
void
print_reductions(state)
int state;
{
register int i;
register int j;
register int k;
register unsigned *fp1;
register unsigned *fp2;
register unsigned *fp3;
register unsigned *fp4;
register int rule;
register int symbol;
register unsigned mask;
register int m;
register int n;
register int default_LA;
register int default_rule;
register int cmax;
register int count;
register shifts *shiftp;
register errs *errp;
int nodefault = 0;
for (i = 0; i < tokensetsize; i++)
shiftset[i] = 0;
shiftp = shift_table[state];
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
/* if this state has a shift for the error token,
don't use a default rule. */
if (symbol == error_token_number) nodefault = 1;
SETBIT(shiftset, symbol);
}
}
errp = err_table[state];
if (errp)
{
k = errp->nerrs;
for (i = 0; i < k; i++)
{
if (! errp->errs[i]) continue;
symbol = errp->errs[i];
SETBIT(shiftset, symbol);
}
}
m = lookaheads[state];
n = lookaheads[state + 1];
if (n - m == 1 && ! nodefault)
{
default_rule = LAruleno[m];
fp1 = LA + m * tokensetsize;
fp2 = shiftset;
fp3 = lookaheadset;
fp4 = lookaheadset + tokensetsize;
while (fp3 < fp4)
*fp3++ = *fp1++ & *fp2++;
mask = 1;
fp3 = lookaheadset;
for (i = 0; i < ntokens; i++)
{
if (mask & *fp3)
fprintf(foutput, " %-4s\t[reduce using rule %d (%s)]\n",
tags[i], default_rule, tags[rlhs[default_rule]]);
mask <<= 1;
if (mask == 0)
{
mask = 1;
fp3++;
}
}
fprintf(foutput, " $default\treduce using rule %d (%s)\n\n",
default_rule, tags[rlhs[default_rule]]);
}
else if (n - m >= 1)
{
cmax = 0;
default_LA = -1;
fp4 = lookaheadset + tokensetsize;
if (! nodefault)
for (i = m; i < n; i++)
{
fp1 = LA + i * tokensetsize;
fp2 = shiftset;
fp3 = lookaheadset;
while (fp3 < fp4)
*fp3++ = *fp1++ & (~(*fp2++));
count = 0;
mask = 1;
fp3 = lookaheadset;
for (j = 0; j < ntokens; j++)
{
if (mask & *fp3)
count++;
mask <<= 1;
if (mask == 0)
{
mask = 1;
fp3++;
}
}
if (count > cmax)
{
cmax = count;
default_LA = i;
default_rule = LAruleno[i];
}
fp2 = shiftset;
fp3 = lookaheadset;
while (fp3 < fp4)
*fp2++ |= *fp3++;
}
for (i = 0; i < tokensetsize; i++)
shiftset[i] = 0;
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
symbol = accessing_symbol[shiftp->shifts[i]];
if (ISVAR(symbol)) break;
SETBIT(shiftset, symbol);
}
}
mask = 1;
fp1 = LA + m * tokensetsize;
fp2 = shiftset;
for (i = 0; i < ntokens; i++)
{
int defaulted = 0;
if (mask & *fp2)
count = 1;
else
count = 0;
fp3 = fp1;
for (j = m; j < n; j++)
{
if (mask & *fp3)
{
if (count == 0)
{
if (j != default_LA)
{
rule = LAruleno[j];
fprintf(foutput, " %-4s\treduce using rule %d (%s)\n",
tags[i], rule, tags[rlhs[rule]]);
}
else defaulted = 1;
count++;
}
else
{
if (defaulted)
{
rule = LAruleno[default_LA];
fprintf(foutput, " %-4s\treduce using rule %d (%s)\n",
tags[i], rule, tags[rlhs[rule]]);
defaulted = 0;
}
rule = LAruleno[j];
fprintf(foutput, " %-4s\t[reduce using rule %d (%s)]\n",
tags[i], rule, tags[rlhs[rule]]);
}
}
fp3 += tokensetsize;
}
mask <<= 1;
if (mask == 0)
{
mask = 1;
/* We tried incrementing just fp1, and just fp2; both seem wrong.
It seems necessary to increment both in sync. */
fp1++;
fp2++;
}
}
if (default_LA >= 0)
{
fprintf(foutput, " $default\treduce using rule %d (%s)\n",
default_rule, tags[rlhs[default_rule]]);
}
putc('\n', foutput);
}
}
void
finalize_conflicts()
{
FREE(conflicts);
FREE(shiftset);
FREE(lookaheadset);
}

118
contrib/bison/derives.c Normal file
View File

@ -0,0 +1,118 @@
/* Match rules with nonterminals for bison,
Copyright (C) 1984, 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. */
/* set_derives finds, for each variable (nonterminal), which rules can derive it.
It sets up the value of derives so that
derives[i - ntokens] points to a vector of rule numbers,
terminated with -1. */
#include <stdio.h>
#include "system.h"
#include "new.h"
#include "types.h"
#include "gram.h"
short **derives;
void
set_derives()
{
register int i;
register int lhs;
register shorts *p;
register short *q;
register shorts **dset;
register shorts *delts;
dset = NEW2(nvars, shorts *) - ntokens;
delts = NEW2(nrules + 1, shorts);
p = delts;
for (i = nrules; i > 0; i--)
{
lhs = rlhs[i];
if (lhs >= 0)
{
p->next = dset[lhs];
p->value = i;
dset[lhs] = p;
p++;
}
}
derives = NEW2(nvars, short *) - ntokens;
q = NEW2(nvars + nrules, short);
for (i = ntokens; i < nsyms; i++)
{
derives[i] = q;
p = dset[i];
while (p)
{
*q++ = p->value;
p = p->next;
}
*q++ = -1;
}
#ifdef DEBUG
print_derives();
#endif
FREE(dset + ntokens);
FREE(delts);
}
void
free_derives()
{
FREE(derives[ntokens]);
FREE(derives + ntokens);
}
#ifdef DEBUG
print_derives()
{
register int i;
register short *sp;
extern char **tags;
printf("\n\n\nDERIVES\n\n");
for (i = ntokens; i < nsyms; i++)
{
printf("%s derives", tags[i]);
for (sp = derives[i]; *sp > 0; sp++)
{
printf(" %d", *sp);
}
putchar('\n');
}
putchar('\n');
}
#endif

414
contrib/bison/files.c Normal file
View File

@ -0,0 +1,414 @@
/* Open and close files for bison,
Copyright (C) 1984, 1986, 1989, 1992 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. */
#if defined (VMS) & !defined (__VMS_POSIX)
#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 int noparserflag;
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;
#if defined (VMS) & !defined (__VMS_POSIX)
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 *) xmalloc (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");
if (! noparserflag)
{
filename = getenv("BISON_SIMPLE");
#ifdef MSDOS
/* File doesn't exist in current directory; try in INIT directory. */
cp = getenv("INIT");
if (filename == 0 && cp != NULL)
{
filename = xmalloc(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");
}
if (noparserflag)
{
/* use permanent name for actions file */
actfile = stringappend(name_base, short_base_length, ".act");
faction = tryopen(actfile, "w");
}
#ifdef MSDOS
if (! noparserflag)
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
if (! noparserflag)
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 */
if (! noparserflag)
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
if (! noparserflag)
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;
if (fparser)
fclose(fparser);
if (! noparserflag)
{
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 != NULL)
{
filename = xmalloc(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);
}
}
#if defined (VMS) & !defined (__VMS_POSIX)
if (faction && ! noparserflag)
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 && ! noparserflag) unlink(actfile);
if (tmpattrsfile) unlink(tmpattrsfile);
if (tmptabfile) unlink(tmptabfile);
if (tmpdefsfile) unlink(tmpdefsfile);
#endif /* MSDOS */
exit(k);
#endif /* not VMS, or __VMS_POSIX */
}

52
contrib/bison/files.h Normal file
View File

@ -0,0 +1,52 @@
/* File names and variables for bison,
Copyright (C) 1984, 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. */
/* These two should be pathnames for opening the sample parser files.
When bison is installed, they should be absolute pathnames.
XPFILE1 and XPFILE2 normally come from the Makefile. */
#define PFILE XPFILE /* Simple parser */
#define PFILE1 XPFILE1 /* Semantic parser */
extern FILE *finput; /* read grammar specifications */
extern FILE *foutput; /* optionally output messages describing the actions taken */
extern FILE *fdefines; /* optionally output #define's for token numbers. */
extern FILE *ftable; /* output the tables and the parser */
extern FILE *fattrs; /* if semantic parser, output a .h file that defines YYSTYPE */
/* and also contains all the %{ ... %} definitions. */
extern FILE *fguard; /* if semantic parser, output yyguard, containing all the guard code */
extern FILE *faction; /* output all the action code; precise form depends on which parser */
extern FILE *fparser; /* read the parser to copy into ftable */
/* File name specified with -o for the output file, or 0 if no -o. */
extern char *spec_outfile;
extern char *spec_name_prefix; /* for -a, from getargs.c */
/* File name pfx specified with -b, or 0 if no -b. */
extern char *spec_file_prefix;
extern char *infile;
extern char *outfile;
extern char *defsfile;
extern char *tabfile;
extern char *attrsfile;
extern char *guardfile;
extern char *actfile;

168
contrib/bison/getargs.c Normal file
View File

@ -0,0 +1,168 @@
/* Parse command line arguments for bison,
Copyright (C) 1984, 1986, 1989, 1992 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 "getopt.h"
#include "system.h"
#include "files.h"
int verboseflag;
int definesflag;
int debugflag;
int nolinesflag;
int noparserflag = 0;
int toknumflag = 0;
int rawtoknumflag = 0;
char *spec_name_prefix; /* for -p. */
char *spec_file_prefix; /* for -b. */
extern int fixed_outfiles;/* for -y */
extern char *program_name;
extern char *version_string;
extern void warns(); /* main.c */
struct option longopts[] =
{
{"debug", 0, &debugflag, 1},
{"defines", 0, &definesflag, 1},
{"file-prefix", 1, 0, 'b'},
{"fixed-output-files", 0, &fixed_outfiles, 1},
{"help", 0, 0, 'h'},
{"name-prefix", 1, 0, 'p'}, /* was 'a'; apparently unused -wjh */
{"no-lines", 0, &nolinesflag, 1},
{"no-parser", 0, &noparserflag, 1},
{"output", 1, 0, 'o'},
{"output-file", 1, 0, 'o'},
{"raw", 0, &rawtoknumflag, 1},
{"token-table", 0, &toknumflag, 1},
{"verbose", 0, &verboseflag, 1},
{"version", 0, 0, 'V'},
{"yacc", 0, &fixed_outfiles, 1},
{0, 0, 0, 0}
};
void
usage (stream)
FILE *stream;
{
fprintf (stream, "\
Usage: %s [-dhklntvyV] [-b file-prefix] [-o outfile] [-p name-prefix]\n\
[--debug] [--defines] [--fixed-output-files] [--no-lines]\n\
[--verbose] [--version] [--help] [--yacc]\n\
[--no-parser] [--token-table]\n\
[--file-prefix=prefix] [--name-prefix=prefix]\n\
[--output=outfile] grammar-file\n",
program_name);
}
void
getargs(argc, argv)
int argc;
char *argv[];
{
register int c;
verboseflag = 0;
definesflag = 0;
debugflag = 0;
noparserflag = 0;
rawtoknumflag = 0;
toknumflag = 0;
fixed_outfiles = 0;
while ((c = getopt_long (argc, argv, "yvdhrltknVo:b:p:", longopts, (int *)0))
!= EOF)
{
switch (c)
{
case 0:
/* Certain long options cause getopt_long to return 0. */
break;
case 'y':
fixed_outfiles = 1;
break;
case 'h':
usage (stdout);
exit (0);
case 'V':
printf ("%s", version_string);
exit (0);
case 'v':
verboseflag = 1;
break;
case 'd':
definesflag = 1;
break;
case 'l':
nolinesflag = 1;
break;
case 'k':
toknumflag = 1;
break;
case 'r':
rawtoknumflag = 1;
break;
case 'n':
noparserflag = 1;
break;
case 't':
debugflag = 1;
break;
case 'o':
spec_outfile = optarg;
break;
case 'b':
spec_file_prefix = optarg;
break;
case 'p':
spec_name_prefix = optarg;
break;
default:
usage (stderr);
exit (1);
}
}
if (optind == argc)
{
fprintf(stderr, "%s: no grammar file given\n", program_name);
exit(1);
}
if (optind < argc - 1)
fprintf(stderr, "%s: extra arguments ignored after '%s'\n",
program_name, argv[optind]);
infile = argv[optind];
}

813
contrib/bison/getopt.c Normal file
View File

@ -0,0 +1,813 @@
/* Getopt for GNU.
NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 1996
Free Software Foundation, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
#define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if !defined (__STDC__) || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
#include <stdlib.h>
#include <unistd.h>
#endif /* GNU C library. */
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
#ifdef HAVE_LIBINTL_H
# include <libintl.h>
# define _(msgid) gettext (msgid)
#else
# define _(msgid) (msgid)
#endif
#endif
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
As `getopt' works, it permutes the elements of ARGV so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
Setting the environment variable POSIXLY_CORRECT disables permutation.
Then the behavior is completely standard.
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
#include "getopt.h"
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
char *optarg = NULL;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
/* XXX 1003.2 says this must be 1 before any call. */
int optind = 0;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
static char *nextchar;
/* Callers store zero here to inhibit the error message
for unrecognized options. */
int opterr = 1;
/* Set to an option character which was unrecognized.
This must be initialized on some systems to avoid linking in the
system's own getopt implementation. */
int optopt = '?';
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
/* Value of POSIXLY_CORRECT environment variable. */
static char *posixly_correct;
#ifdef __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
#include <string.h>
#define my_index strchr
#else
/* Avoid depending on library functions or files
whose names are inconsistent. */
char *getenv ();
static char *
my_index (str, chr)
const char *str;
int chr;
{
while (*str)
{
if (*str == chr)
return (char *) str;
str++;
}
return 0;
}
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
#if !defined (__STDC__) || !__STDC__
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
#endif /* not __STDC__ */
#endif /* __GNUC__ */
#endif /* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
static int first_nonopt;
static int last_nonopt;
/* Bash 2.0 gives us an environment variable containing flags
indicating ARGV elements that should not be considered arguments. */
static const char *nonoption_flags;
static int nonoption_flags_len;
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
#if defined (__STDC__) && __STDC__
static void exchange (char **);
#endif
static void
exchange (argv)
char **argv;
{
int bottom = first_nonopt;
int middle = last_nonopt;
int top = optind;
char *tem;
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
}
else
{
/* Top segment is the short one. */
int len = top - middle;
register int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
/* Update records for the slots the non-options now occupy. */
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
/* Initialize the internal data when the first call is made. */
#if defined (__STDC__) && __STDC__
static const char *_getopt_initialize (const char *);
#endif
static const char *
_getopt_initialize (optstring)
const char *optstring;
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
first_nonopt = last_nonopt = optind = 1;
nextchar = NULL;
posixly_correct = getenv ("POSIXLY_CORRECT");
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (posixly_correct != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
if (posixly_correct == NULL)
{
/* Bash 2.0 puts a special variable in the environment for each
command it runs, specifying which ARGV elements are the results of
file name wildcard expansion and therefore should not be
considered as options. */
char var[100];
sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ());
nonoption_flags = getenv (var);
if (nonoption_flags == NULL)
nonoption_flags_len = 0;
else
nonoption_flags_len = strlen (nonoption_flags);
}
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
If there are no more option characters, `getopt' returns `EOF'.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg', otherwise `optarg' is set to zero.
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
Long-named options begin with `--' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
if the `flag' field is zero.
The elements of ARGV aren't really const, because we permute them.
But we pretend they're const in the prototype to be compatible
with other systems.
LONGOPTS is a vector of `struct option' terminated by an
element containing a name which is zero.
LONGIND returns the index in LONGOPT of the long-named option found.
It is only valid when a long-named option has been found by the most
recent call.
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
int
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int argc;
char *const *argv;
const char *optstring;
const struct option *longopts;
int *longind;
int long_only;
{
optarg = NULL;
if (optind == 0)
{
optstring = _getopt_initialize (optstring);
optind = 1; /* Don't scan ARGV[0], the program name. */
}
/* Test whether ARGV[optind] points to a non-option argument.
Either it does not have option syntax, or there is an environment flag
from the shell indicating it is not an option. */
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|| (optind < nonoption_flags_len \
&& nonoption_flags[optind] == '1'))
if (nextchar == NULL || *nextchar == '\0')
{
/* Advance to the next ARGV-element. */
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
moved back by the user (who may also have changed the arguments). */
if (last_nonopt > optind)
last_nonopt = optind;
if (first_nonopt > optind)
first_nonopt = optind;
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (last_nonopt != optind)
first_nonopt = optind;
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
while (optind < argc && NONOPTION_P)
optind++;
last_nonopt = optind;
}
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
optind = argc;
}
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return EOF;
}
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
if (NONOPTION_P)
{
if (ordering == REQUIRE_ORDER)
return EOF;
optarg = argv[optind++];
return 1;
}
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
nextchar = (argv[optind] + 1
+ (longopts != NULL && argv[optind][1] == '-'));
}
/* Decode the current option-ARGV-element. */
/* Check whether the ARGV-element is a long option.
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
This distinction seems to be the most useful approach. */
if (longopts != NULL
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound;
int option_index;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if (nameend - nextchar == strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (opterr)
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
optopt = 0;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
optind++;
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (opterr)
if (argv[optind - 1][1] == '-')
/* --option */
fprintf (stderr,
_("%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
else
/* +option or -option */
fprintf (stderr,
_("%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[optind - 1][0], pfound->name);
nextchar += strlen (nextchar);
optopt = pfound->val;
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
if (opterr)
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (opterr)
{
if (argv[optind][1] == '-')
/* --option */
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0], nextchar);
}
nextchar = (char *) "";
optind++;
optopt = 0;
return '?';
}
}
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
/* Increment `optind' when we start to process its last character. */
if (*nextchar == '\0')
++optind;
if (temp == NULL || c == ':')
{
if (opterr)
{
if (posixly_correct)
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c);
else
fprintf (stderr, _("%s: invalid option -- %c\n"),
argv[0], c);
}
optopt = c;
return '?';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != '\0')
{
optarg = nextchar;
optind++;
}
else
optarg = NULL;
nextchar = NULL;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr)
{
/* 1003.2 specifies the format of this message. */
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = NULL;
}
}
return c;
}
}
int
getopt (argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
{
return _getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
#ifdef TEST
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
c = getopt (argc, argv, "abc:d:0123456789");
if (c == EOF)
break;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

130
contrib/bison/getopt.h Normal file
View File

@ -0,0 +1,130 @@
/* Declarations for getopt.
Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if defined (__STDC__) && __STDC__
#ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt ();
#endif /* __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* _GETOPT_H */

181
contrib/bison/getopt1.c Normal file
View File

@ -0,0 +1,181 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
Free Software Foundation, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "getopt.h"
#if !defined (__STDC__) || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#else
char *getenv ();
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == EOF)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

58
contrib/bison/gram.c Normal file
View File

@ -0,0 +1,58 @@
/* Allocate input grammar variables 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. */
/* comments for these variables are in gram.h */
int nitems;
int nrules;
int nsyms;
int ntokens;
int nvars;
short *ritem;
short *rlhs;
short *rrhs;
short *rprec;
short *rprecsym;
short *sprec;
short *rassoc;
short *sassoc;
short *token_translations;
short *rline;
int start_symbol;
int translations;
int max_user_token_number;
int semantic_parser;
int pure_parser;
int error_token_number;
/* This is to avoid linker problems which occur on VMS when using GCC,
when the file in question contains data definitions only. */
void
dummy()
{
}

125
contrib/bison/gram.h Normal file
View File

@ -0,0 +1,125 @@
/* Data definitions for internal representation of bison's input,
Copyright (C) 1984, 1986, 1989, 1992 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. */
/* representation of the grammar rules:
ntokens is the number of tokens, and nvars is the number of variables
(nonterminals). nsyms is the total number, ntokens + nvars.
(the true number of token values assigned is ntokens
reduced by one for each alias declaration)
Each symbol (either token or variable) receives a symbol number.
Numbers 0 to ntokens-1 are for tokens, and ntokens to nsyms-1 are for
variables. Symbol number zero is the end-of-input token. This token
is counted in ntokens.
The rules receive rule numbers 1 to nrules in the order they are written.
Actions and guards are accessed via the rule number.
The rules themselves are described by three arrays: rrhs, rlhs and
ritem. rlhs[R] is the symbol number of the left hand side of rule R.
The right hand side is stored as symbol numbers in a portion of
ritem. rrhs[R] contains the index in ritem of the beginning of the
portion for rule R.
If rlhs[R] is -1, the rule has been thrown out by reduce.c
and should be ignored.
The length of the portion is one greater
than the number of symbols in the rule's right hand side.
The last element in the portion contains minus R, which
identifies it as the end of a portion and says which rule it is for.
The portions of ritem come in order of increasing rule number and are
followed by an element which is zero to mark the end. nitems is the
total length of ritem, not counting the final zero. Each element of
ritem is called an "item" and its index in ritem is an item number.
Item numbers are used in the finite state machine to represent
places that parsing can get to.
Precedence levels are recorded in the vectors sprec and rprec.
sprec records the precedence level of each symbol,
rprec the precedence level of each rule.
rprecsym is the symbol-number of the symbol in %prec for this rule (if any).
Precedence levels are assigned in increasing order starting with 1 so
that numerically higher precedence values mean tighter binding as they
ought to. Zero as a symbol or rule's precedence means none is
assigned.
Associativities are recorded similarly in rassoc and sassoc. */
#define ISTOKEN(s) ((s) < ntokens)
#define ISVAR(s) ((s) >= ntokens)
extern int nitems;
extern int nrules;
extern int nsyms;
extern int ntokens;
extern int nvars;
extern short *ritem;
extern short *rlhs;
extern short *rrhs;
extern short *rprec;
extern short *rprecsym;
extern short *sprec;
extern short *rassoc;
extern short *sassoc;
extern short *rline; /* Source line number of each rule */
extern int start_symbol;
/* associativity values in elements of rassoc, sassoc. */
#define RIGHT_ASSOC 1
#define LEFT_ASSOC 2
#define NON_ASSOC 3
/* token translation table:
indexed by a token number as returned by the user's yylex routine,
it yields the internal token number used by the parser and throughout bison.
If translations is zero, the translation table is not used because
the two kinds of token numbers are the same.
(It is noted in reader.c that "Nowadays translations is always set to 1...")
*/
extern short *token_translations;
extern int translations;
extern int max_user_token_number;
/* semantic_parser is nonzero if the input file says to use the hairy parser
that provides for semantic error recovery. If it is zero, the yacc-compatible
simplified parser is used. */
extern int semantic_parser;
/* pure_parser is nonzero if should generate a parser that is all pure and reentrant. */
extern int pure_parser;
/* error_token_number is the token number of the error token. */
extern int error_token_number;

238
contrib/bison/install-sh Executable file
View File

@ -0,0 +1,238 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

770
contrib/bison/lalr.c Normal file
View File

@ -0,0 +1,770 @@
/* Compute look-ahead criteria 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. */
/* Compute how to make the finite state machine deterministic;
find which rules need lookahead in each state, and which lookahead tokens they accept.
lalr(), the entry point, builds these data structures:
goto_map, from_state and to_state
record each shift transition which accepts a variable (a nonterminal).
ngotos is the number of such transitions.
from_state[t] is the state number which a transition leads from
and to_state[t] is the state number it leads to.
All the transitions that accept a particular variable are grouped together and
goto_map[i - ntokens] is the index in from_state and to_state of the first of them.
consistent[s] is nonzero if no lookahead is needed to decide what to do in state s.
LAruleno is a vector which records the rules that need lookahead in various states.
The elements of LAruleno that apply to state s are those from
lookaheads[s] through lookaheads[s+1]-1.
Each element of LAruleno is a rule number.
If lr is the length of LAruleno, then a number from 0 to lr-1
can specify both a rule and a state where the rule might be applied.
LA is a lr by ntokens matrix of bits.
LA[l, i] is 1 if the rule LAruleno[l] is applicable in the appropriate state
when the next token is symbol i.
If LA[l, i] and LA[l, j] are both 1 for i != j, it is a conflict.
*/
#include <stdio.h>
#include "system.h"
#include "machine.h"
#include "types.h"
#include "state.h"
#include "new.h"
#include "gram.h"
extern short **derives;
extern char *nullable;
int tokensetsize;
short *lookaheads;
short *LAruleno;
unsigned *LA;
short *accessing_symbol;
char *consistent;
core **state_table;
shifts **shift_table;
reductions **reduction_table;
short *goto_map;
short *from_state;
short *to_state;
short **transpose();
void set_state_table();
void set_accessing_symbol();
void set_shift_table();
void set_reduction_table();
void set_maxrhs();
void initialize_LA();
void set_goto_map();
void initialize_F();
void build_relations();
void add_lookback_edge();
void compute_FOLLOWS();
void compute_lookaheads();
void digraph();
void traverse();
extern void toomany();
extern void berror();
static int infinity;
static int maxrhs;
static int ngotos;
static unsigned *F;
static short **includes;
static shorts **lookback;
static short **R;
static short *INDEX;
static short *VERTICES;
static int top;
void
lalr()
{
tokensetsize = WORDSIZE(ntokens);
set_state_table();
set_accessing_symbol();
set_shift_table();
set_reduction_table();
set_maxrhs();
initialize_LA();
set_goto_map();
initialize_F();
build_relations();
compute_FOLLOWS();
compute_lookaheads();
}
void
set_state_table()
{
register core *sp;
state_table = NEW2(nstates, core *);
for (sp = first_state; sp; sp = sp->next)
state_table[sp->number] = sp;
}
void
set_accessing_symbol()
{
register core *sp;
accessing_symbol = NEW2(nstates, short);
for (sp = first_state; sp; sp = sp->next)
accessing_symbol[sp->number] = sp->accessing_symbol;
}
void
set_shift_table()
{
register shifts *sp;
shift_table = NEW2(nstates, shifts *);
for (sp = first_shift; sp; sp = sp->next)
shift_table[sp->number] = sp;
}
void
set_reduction_table()
{
register reductions *rp;
reduction_table = NEW2(nstates, reductions *);
for (rp = first_reduction; rp; rp = rp->next)
reduction_table[rp->number] = rp;
}
void
set_maxrhs()
{
register short *itemp;
register int length;
register int max;
length = 0;
max = 0;
for (itemp = ritem; *itemp; itemp++)
{
if (*itemp > 0)
{
length++;
}
else
{
if (length > max) max = length;
length = 0;
}
}
maxrhs = max;
}
void
initialize_LA()
{
register int i;
register int j;
register int count;
register reductions *rp;
register shifts *sp;
register short *np;
consistent = NEW2(nstates, char);
lookaheads = NEW2(nstates + 1, short);
count = 0;
for (i = 0; i < nstates; i++)
{
register int k;
lookaheads[i] = count;
rp = reduction_table[i];
sp = shift_table[i];
if (rp && (rp->nreds > 1
|| (sp && ! ISVAR(accessing_symbol[sp->shifts[0]]))))
count += rp->nreds;
else
consistent[i] = 1;
if (sp)
for (k = 0; k < sp->nshifts; k++)
{
if (accessing_symbol[sp->shifts[k]] == error_token_number)
{
consistent[i] = 0;
break;
}
}
}
lookaheads[nstates] = count;
if (count == 0)
{
LA = NEW2(1 * tokensetsize, unsigned);
LAruleno = NEW2(1, short);
lookback = NEW2(1, shorts *);
}
else
{
LA = NEW2(count * tokensetsize, unsigned);
LAruleno = NEW2(count, short);
lookback = NEW2(count, shorts *);
}
np = LAruleno;
for (i = 0; i < nstates; i++)
{
if (!consistent[i])
{
if (rp = reduction_table[i])
for (j = 0; j < rp->nreds; j++)
*np++ = rp->rules[j];
}
}
}
void
set_goto_map()
{
register shifts *sp;
register int i;
register int symbol;
register int k;
register short *temp_map;
register int state2;
register int state1;
goto_map = NEW2(nvars + 1, short) - ntokens;
temp_map = NEW2(nvars + 1, short) - ntokens;
ngotos = 0;
for (sp = first_shift; sp; sp = sp->next)
{
for (i = sp->nshifts - 1; i >= 0; i--)
{
symbol = accessing_symbol[sp->shifts[i]];
if (ISTOKEN(symbol)) break;
if (ngotos == MAXSHORT)
toomany("gotos");
ngotos++;
goto_map[symbol]++;
}
}
k = 0;
for (i = ntokens; i < nsyms; i++)
{
temp_map[i] = k;
k += goto_map[i];
}
for (i = ntokens; i < nsyms; i++)
goto_map[i] = temp_map[i];
goto_map[nsyms] = ngotos;
temp_map[nsyms] = ngotos;
from_state = NEW2(ngotos, short);
to_state = NEW2(ngotos, short);
for (sp = first_shift; sp; sp = sp->next)
{
state1 = sp->number;
for (i = sp->nshifts - 1; i >= 0; i--)
{
state2 = sp->shifts[i];
symbol = accessing_symbol[state2];
if (ISTOKEN(symbol)) break;
k = temp_map[symbol]++;
from_state[k] = state1;
to_state[k] = state2;
}
}
FREE(temp_map + ntokens);
}
/* Map_goto maps a state/symbol pair into its numeric representation. */
int
map_goto(state, symbol)
int state;
int symbol;
{
register int high;
register int low;
register int middle;
register int s;
low = goto_map[symbol];
high = goto_map[symbol + 1] - 1;
while (low <= high)
{
middle = (low + high) / 2;
s = from_state[middle];
if (s == state)
return (middle);
else if (s < state)
low = middle + 1;
else
high = middle - 1;
}
berror("map_goto");
/* NOTREACHED */
return 0;
}
void
initialize_F()
{
register int i;
register int j;
register int k;
register shifts *sp;
register short *edge;
register unsigned *rowp;
register short *rp;
register short **reads;
register int nedges;
register int stateno;
register int symbol;
register int nwords;
nwords = ngotos * tokensetsize;
F = NEW2(nwords, unsigned);
reads = NEW2(ngotos, short *);
edge = NEW2(ngotos + 1, short);
nedges = 0;
rowp = F;
for (i = 0; i < ngotos; i++)
{
stateno = to_state[i];
sp = shift_table[stateno];
if (sp)
{
k = sp->nshifts;
for (j = 0; j < k; j++)
{
symbol = accessing_symbol[sp->shifts[j]];
if (ISVAR(symbol))
break;
SETBIT(rowp, symbol);
}
for (; j < k; j++)
{
symbol = accessing_symbol[sp->shifts[j]];
if (nullable[symbol])
edge[nedges++] = map_goto(stateno, symbol);
}
if (nedges)
{
reads[i] = rp = NEW2(nedges + 1, short);
for (j = 0; j < nedges; j++)
rp[j] = edge[j];
rp[nedges] = -1;
nedges = 0;
}
}
rowp += tokensetsize;
}
digraph(reads);
for (i = 0; i < ngotos; i++)
{
if (reads[i])
FREE(reads[i]);
}
FREE(reads);
FREE(edge);
}
void
build_relations()
{
register int i;
register int j;
register int k;
register short *rulep;
register short *rp;
register shifts *sp;
register int length;
register int nedges;
register int done;
register int state1;
register int stateno;
register int symbol1;
register int symbol2;
register short *shortp;
register short *edge;
register short *states;
register short **new_includes;
includes = NEW2(ngotos, short *);
edge = NEW2(ngotos + 1, short);
states = NEW2(maxrhs + 1, short);
for (i = 0; i < ngotos; i++)
{
nedges = 0;
state1 = from_state[i];
symbol1 = accessing_symbol[to_state[i]];
for (rulep = derives[symbol1]; *rulep > 0; rulep++)
{
length = 1;
states[0] = state1;
stateno = state1;
for (rp = ritem + rrhs[*rulep]; *rp > 0; rp++)
{
symbol2 = *rp;
sp = shift_table[stateno];
k = sp->nshifts;
for (j = 0; j < k; j++)
{
stateno = sp->shifts[j];
if (accessing_symbol[stateno] == symbol2) break;
}
states[length++] = stateno;
}
if (!consistent[stateno])
add_lookback_edge(stateno, *rulep, i);
length--;
done = 0;
while (!done)
{
done = 1;
rp--;
/* JF added rp>=ritem && I hope to god its right! */
if (rp>=ritem && ISVAR(*rp))
{
stateno = states[--length];
edge[nedges++] = map_goto(stateno, *rp);
if (nullable[*rp]) done = 0;
}
}
}
if (nedges)
{
includes[i] = shortp = NEW2(nedges + 1, short);
for (j = 0; j < nedges; j++)
shortp[j] = edge[j];
shortp[nedges] = -1;
}
}
new_includes = transpose(includes, ngotos);
for (i = 0; i < ngotos; i++)
if (includes[i])
FREE(includes[i]);
FREE(includes);
includes = new_includes;
FREE(edge);
FREE(states);
}
void
add_lookback_edge(stateno, ruleno, gotono)
int stateno;
int ruleno;
int gotono;
{
register int i;
register int k;
register int found;
register shorts *sp;
i = lookaheads[stateno];
k = lookaheads[stateno + 1];
found = 0;
while (!found && i < k)
{
if (LAruleno[i] == ruleno)
found = 1;
else
i++;
}
if (found == 0)
berror("add_lookback_edge");
sp = NEW(shorts);
sp->next = lookback[i];
sp->value = gotono;
lookback[i] = sp;
}
short **
transpose(R_arg, n)
short **R_arg;
int n;
{
register short **new_R;
register short **temp_R;
register short *nedges;
register short *sp;
register int i;
register int k;
nedges = NEW2(n, short);
for (i = 0; i < n; i++)
{
sp = R_arg[i];
if (sp)
{
while (*sp >= 0)
nedges[*sp++]++;
}
}
new_R = NEW2(n, short *);
temp_R = NEW2(n, short *);
for (i = 0; i < n; i++)
{
k = nedges[i];
if (k > 0)
{
sp = NEW2(k + 1, short);
new_R[i] = sp;
temp_R[i] = sp;
sp[k] = -1;
}
}
FREE(nedges);
for (i = 0; i < n; i++)
{
sp = R_arg[i];
if (sp)
{
while (*sp >= 0)
*temp_R[*sp++]++ = i;
}
}
FREE(temp_R);
return (new_R);
}
void
compute_FOLLOWS()
{
register int i;
digraph(includes);
for (i = 0; i < ngotos; i++)
{
if (includes[i]) FREE(includes[i]);
}
FREE(includes);
}
void
compute_lookaheads()
{
register int i;
register int n;
register unsigned *fp1;
register unsigned *fp2;
register unsigned *fp3;
register shorts *sp;
register unsigned *rowp;
/* register short *rulep; JF unused */
/* register int count; JF unused */
register shorts *sptmp;/* JF */
rowp = LA;
n = lookaheads[nstates];
for (i = 0; i < n; i++)
{
fp3 = rowp + tokensetsize;
for (sp = lookback[i]; sp; sp = sp->next)
{
fp1 = rowp;
fp2 = F + tokensetsize * sp->value;
while (fp1 < fp3)
*fp1++ |= *fp2++;
}
rowp = fp3;
}
for (i = 0; i < n; i++)
{/* JF removed ref to freed storage */
for (sp = lookback[i]; sp; sp = sptmp) {
sptmp=sp->next;
FREE(sp);
}
}
FREE(lookback);
FREE(F);
}
void
digraph(relation)
short **relation;
{
register int i;
infinity = ngotos + 2;
INDEX = NEW2(ngotos + 1, short);
VERTICES = NEW2(ngotos + 1, short);
top = 0;
R = relation;
for (i = 0; i < ngotos; i++)
INDEX[i] = 0;
for (i = 0; i < ngotos; i++)
{
if (INDEX[i] == 0 && R[i])
traverse(i);
}
FREE(INDEX);
FREE(VERTICES);
}
void
traverse(i)
register int i;
{
register unsigned *fp1;
register unsigned *fp2;
register unsigned *fp3;
register int j;
register short *rp;
int height;
unsigned *base;
VERTICES[++top] = i;
INDEX[i] = height = top;
base = F + i * tokensetsize;
fp3 = base + tokensetsize;
rp = R[i];
if (rp)
{
while ((j = *rp++) >= 0)
{
if (INDEX[j] == 0)
traverse(j);
if (INDEX[i] > INDEX[j])
INDEX[i] = INDEX[j];
fp1 = base;
fp2 = F + j * tokensetsize;
while (fp1 < fp3)
*fp1++ |= *fp2++;
}
}
if (INDEX[i] == height)
{
for (;;)
{
j = VERTICES[top--];
INDEX[j] = infinity;
if (i == j)
break;
fp1 = base;
fp2 = F + j * tokensetsize;
while (fp1 < fp3)
*fp2++ = *fp1++;
}
}
}

620
contrib/bison/lex.c Normal file
View File

@ -0,0 +1,620 @@
/* Token-reader for Bison's input parser,
Copyright (C) 1984, 1986, 1989, 1992 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. */
/*
lex is the entry point. It is called from reader.c.
It returns one of the token-type codes defined in lex.h.
When an identifier is seen, the code IDENTIFIER is returned
and the name is looked up in the symbol table using symtab.c;
symval is set to a pointer to the entry found. */
#include <stdio.h>
#include <ctype.h>
#include "system.h"
#include "files.h"
#include "getopt.h" /* for optarg */
#include "symtab.h"
#include "lex.h"
#include "new.h"
/* flags set by % directives */
extern int definesflag; /* for -d */
extern int toknumflag; /* for -k */
extern int noparserflag; /* for -n */
extern int fixed_outfiles; /* for -y */
extern int nolinesflag; /* for -l */
extern int rawtoknumflag; /* for -r */
extern int verboseflag; /* for -v */
extern int debugflag; /* for -t */
extern char *spec_name_prefix; /* for -p */
extern char *spec_file_prefix; /* for -b */
/*spec_outfile is declared in files.h, for -o */
extern int lineno;
extern int translations;
int parse_percent_token();
/* functions from main.c */
extern char *printable_version();
extern void fatal();
extern void warni();
extern void warn();
/* Buffer for storing the current token. */
char *token_buffer;
/* Allocated size of token_buffer, not including space for terminator. */
static int maxtoken;
bucket *symval;
int numval;
static int unlexed; /* these two describe a token to be reread */
static bucket *unlexed_symval; /* by the next call to lex */
void
init_lex()
{
maxtoken = 100;
token_buffer = NEW2 (maxtoken + 1, char);
unlexed = -1;
}
static char *
grow_token_buffer (p)
char *p;
{
int offset = p - token_buffer;
maxtoken *= 2;
token_buffer = (char *) xrealloc(token_buffer, maxtoken + 1);
return token_buffer + offset;
}
int
skip_white_space()
{
register int c;
register int inside;
c = getc(finput);
for (;;)
{
int cplus_comment;
switch (c)
{
case '/':
c = getc(finput);
if (c != '*' && c != '/')
{
warn("unexpected `/' found and ignored");
break;
}
cplus_comment = (c == '/');
c = getc(finput);
inside = 1;
while (inside)
{
if (!cplus_comment && c == '*')
{
while (c == '*')
c = getc(finput);
if (c == '/')
{
inside = 0;
c = getc(finput);
}
}
else if (c == '\n')
{
lineno++;
if (cplus_comment)
inside = 0;
c = getc(finput);
}
else if (c == EOF)
fatal("unterminated comment");
else
c = getc(finput);
}
break;
case '\n':
lineno++;
case ' ':
case '\t':
case '\f':
c = getc(finput);
break;
default:
return (c);
}
}
}
/* do a getc, but give error message if EOF encountered */
int
safegetc(f)
FILE *f;
{
register int c = getc(f);
if (c == EOF)
fatal("Unexpected end of file");
return c;
}
/* read one literal character from finput. process \ escapes.
append the normalized string version of the char to *pp.
assign the character code to *pcode
return 1 unless the character is an unescaped `term' or \n
report error for \n
*/
int
literalchar(pp, pcode, term)
char **pp;
int *pcode;
char term;
{
register int c;
register char *p;
register int code;
int wasquote = 0;
c = safegetc(finput);
if (c == '\n')
{
warn("unescaped newline in constant");
ungetc(c, finput);
code = '?';
wasquote = 1;
}
else if (c != '\\')
{
code = c;
if (c == term)
wasquote = 1;
}
else
{
c = safegetc(finput);
if (c == 't') code = '\t';
else if (c == 'n') code = '\n';
else if (c == 'a') code = '\007';
else if (c == 'r') code = '\r';
else if (c == 'f') code = '\f';
else if (c == 'b') code = '\b';
else if (c == 'v') code = 013;
else if (c == '\\') code = '\\';
else if (c == '\'') code = '\'';
else if (c == '\"') code = '\"';
else if (c <= '7' && c >= '0')
{
code = 0;
while (c <= '7' && c >= '0')
{
code = (code * 8) + (c - '0');
if (code >= 256 || code < 0)
{
warni("octal value outside range 0...255: `\\%o'", code);
code &= 0xFF;
break;
}
c = safegetc(finput);
}
ungetc(c, finput);
}
else if (c == 'x')
{
c = safegetc(finput);
code = 0;
while (1)
{
if (c >= '0' && c <= '9')
code *= 16, code += c - '0';
else if (c >= 'a' && c <= 'f')
code *= 16, code += c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
code *= 16, code += c - 'A' + 10;
else
break;
if (code >= 256 || code<0)
{
warni("hexadecimal value above 255: `\\x%x'", code);
code &= 0xFF;
break;
}
c = safegetc(finput);
}
ungetc(c, finput);
}
else
{
warni ("unknown escape sequence: `\\' followed by `%s'",
printable_version(c));
code = '?';
}
} /* has \ */
/* now fill token_buffer with the canonical name for this character
as a literal token. Do not use what the user typed,
so that `\012' and `\n' can be interchangeable. */
p = *pp;
if (code >= 040 && code < 0177)
*p++ = code;
else if (code == '\\') {*p++ = '\\'; *p++ = '\\';}
else if (code == '\'') {*p++ = '\\'; *p++ = '\'';}
else if (code == '\"') {*p++ = '\\'; *p++ = '\"';}
else if (code == '\t') {*p++ = '\\'; *p++ = 't';}
else if (code == '\n') {*p++ = '\\'; *p++ = 'n';}
else if (code == '\r') {*p++ = '\\'; *p++ = 'r';}
else if (code == '\v') {*p++ = '\\'; *p++ = 'v';}
else if (code == '\b') {*p++ = '\\'; *p++ = 'b';}
else if (code == '\f') {*p++ = '\\'; *p++ = 'f';}
else
{
*p++ = '\\';
*p++ = code / 0100 + '0';
*p++ = ((code / 010) & 07) + '0';
*p++ = (code & 07) + '0';
}
*pp = p;
*pcode = code;
return ! wasquote;
}
void
unlex(token)
int token;
{
unlexed = token;
unlexed_symval = symval;
}
int
lex()
{
register int c;
char *p;
if (unlexed >= 0)
{
symval = unlexed_symval;
c = unlexed;
unlexed = -1;
return (c);
}
c = skip_white_space();
*token_buffer = c; /* for error messages (token buffer always valid) */
token_buffer[1] = 0;
switch (c)
{
case EOF:
strcpy(token_buffer, "EOF");
return (ENDFILE);
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '.': case '_':
p = token_buffer;
while (isalnum(c) || c == '_' || c == '.')
{
if (p == token_buffer + maxtoken)
p = grow_token_buffer(p);
*p++ = c;
c = getc(finput);
}
*p = 0;
ungetc(c, finput);
symval = getsym(token_buffer);
return (IDENTIFIER);
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
numval = 0;
p = token_buffer;
while (isdigit(c))
{
if (p == token_buffer + maxtoken)
p = grow_token_buffer(p);
*p++ = c;
numval = numval*10 + c - '0';
c = getc(finput);
}
*p = 0;
ungetc(c, finput);
return (NUMBER);
}
case '\'':
/* parse the literal token and compute character code in code */
translations = -1;
{
int code, discode;
char discard[10], *dp;
p = token_buffer;
*p++ = '\'';
literalchar(&p, &code, '\'');
c = getc(finput);
if (c != '\'')
{
warn("use \"...\" for multi-character literal tokens");
dp = discard;
while (literalchar(&dp, &discode, '\'')) {}
}
*p++ = '\'';
*p = 0;
symval = getsym(token_buffer);
symval->class = STOKEN;
if (! symval->user_token_number)
symval->user_token_number = code;
return (IDENTIFIER);
}
case '\"':
/* parse the literal string token and treat as an identifier */
translations = -1;
{
int code; /* ignored here */
p = token_buffer;
*p++ = '\"';
while (literalchar(&p, &code, '\"')) /* read up to and including " */
{
if (p >= token_buffer + maxtoken - 4)
p = grow_token_buffer(p);
}
*p = 0;
symval = getsym(token_buffer);
symval->class = STOKEN;
return (IDENTIFIER);
}
case ',':
return (COMMA);
case ':':
return (COLON);
case ';':
return (SEMICOLON);
case '|':
return (BAR);
case '{':
return (LEFT_CURLY);
case '=':
do
{
c = getc(finput);
if (c == '\n') lineno++;
}
while(c==' ' || c=='\n' || c=='\t');
if (c == '{')
{
strcpy(token_buffer, "={");
return(LEFT_CURLY);
}
else
{
ungetc(c, finput);
return(ILLEGAL);
}
case '<':
p = token_buffer;
c = getc(finput);
while (c != '>')
{
if (c == EOF)
fatal("unterminated type name at end of file");
if (c == '\n')
{
warn("unterminated type name");
ungetc(c, finput);
break;
}
if (p == token_buffer + maxtoken)
p = grow_token_buffer(p);
*p++ = c;
c = getc(finput);
}
*p = 0;
return (TYPENAME);
case '%':
return (parse_percent_token());
default:
return (ILLEGAL);
}
}
/* the following table dictates the action taken for the various
% directives. A setflag value causes the named flag to be
set. A retval action returns the code.
*/
struct percent_table_struct {
char *name;
void *setflag;
int retval;
} percent_table[] =
{
{"token", NULL, TOKEN},
{"term", NULL, TOKEN},
{"nterm", NULL, NTERM},
{"type", NULL, TYPE},
{"guard", NULL, GUARD},
{"union", NULL, UNION},
{"expect", NULL, EXPECT},
{"thong", NULL, THONG},
{"start", NULL, START},
{"left", NULL, LEFT},
{"right", NULL, RIGHT},
{"nonassoc", NULL, NONASSOC},
{"binary", NULL, NONASSOC},
{"semantic_parser", NULL, SEMANTIC_PARSER},
{"pure_parser", NULL, PURE_PARSER},
{"prec", NULL, PREC},
{"no_lines", &nolinesflag, NOOP}, /* -l */
{"raw", &rawtoknumflag, NOOP}, /* -r */
{"token_table", &toknumflag, NOOP}, /* -k */
#if 0
/* These can be utilized after main is reoganized so
open_files() is deferred 'til after read_declarations().
But %{ and %union both put information into files
that have to be opened before read_declarations().
*/
{"yacc", &fixed_outfiles, NOOP}, /* -y */
{"fixed_output_files", &fixed_outfiles, NOOP}, /* -y */
{"defines", &definesflag, NOOP}, /* -d */
{"no_parser", &noparserflag, NOOP}, /* -n */
{"output_file", &spec_outfile, SETOPT}, /* -o */
{"file_prefix", &spec_file_prefix, SETOPT}, /* -b */
{"name_prefix", &spec_name_prefix, SETOPT}, /* -p */
/* These would be acceptable, but they do not affect processing */
{"verbose", &verboseflag, NOOP}, /* -v */
{"debug", &debugflag, NOOP}, /* -t */
/* {"help", <print usage stmt>, NOOP}, /* -h */
/* {"version", <print version number> , NOOP}, /* -V */
#endif
{NULL, NULL, ILLEGAL}
};
/* Parse a token which starts with %.
Assumes the % has already been read and discarded. */
int
parse_percent_token ()
{
register int c;
register char *p;
register struct percent_table_struct *tx;
p = token_buffer;
c = getc(finput);
*p++ = '%';
*p++ = c; /* for error msg */
*p = 0;
switch (c)
{
case '%':
return (TWO_PERCENTS);
case '{':
return (PERCENT_LEFT_CURLY);
case '<':
return (LEFT);
case '>':
return (RIGHT);
case '2':
return (NONASSOC);
case '0':
return (TOKEN);
case '=':
return (PREC);
}
if (!isalpha(c))
return (ILLEGAL);
p = token_buffer;
*p++ = '%';
while (isalpha(c) || c == '_' || c == '-')
{
if (p == token_buffer + maxtoken)
p = grow_token_buffer(p);
if (c == '-') c = '_';
*p++ = c;
c = getc(finput);
}
ungetc(c, finput);
*p = 0;
/* table lookup % directive */
for (tx = percent_table; tx->name; tx++)
if (strcmp(token_buffer+1, tx->name) == 0)
break;
if (tx->retval == SETOPT)
{
*((char **)(tx->setflag)) = optarg;
return NOOP;
}
if (tx->setflag)
{
*((int *)(tx->setflag)) = 1;
return NOOP;
}
return tx->retval;
}

50
contrib/bison/lex.h Normal file
View File

@ -0,0 +1,50 @@
/* Token type definitions for bison's input reader,
Copyright (C) 1984, 1989, 1992 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. */
#define ENDFILE 0
#define IDENTIFIER 1
#define COMMA 2
#define COLON 3
#define SEMICOLON 4
#define BAR 5
#define LEFT_CURLY 6
#define TWO_PERCENTS 7
#define PERCENT_LEFT_CURLY 8
#define TOKEN 9
#define NTERM 10
#define GUARD 11
#define TYPE 12
#define UNION 13
#define START 14
#define LEFT 15
#define RIGHT 16
#define NONASSOC 17
#define PREC 18
#define SEMANTIC_PARSER 19
#define PURE_PARSER 20
#define TYPENAME 21
#define NUMBER 22
#define EXPECT 23
#define THONG 24
#define NOOP 25
#define SETOPT 26
#define ILLEGAL 27
#define MAXTOKEN 1024

39
contrib/bison/machine.h Normal file
View File

@ -0,0 +1,39 @@
/* Define machine-dependencies for bison,
Copyright (C) 1984, 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 eta10
#define MAXSHORT 2147483647
#define MINSHORT -2147483648
#else
#define MAXSHORT 32767
#define MINSHORT -32768
#endif
#if defined (MSDOS) && !defined (__GO32__)
#define BITS_PER_WORD 16
#define MAXTABLE 16383
#else
#define BITS_PER_WORD 32
#define MAXTABLE 32767
#endif
#define WORDSIZE(n) (((n) + BITS_PER_WORD - 1) / BITS_PER_WORD)
#define SETBIT(x, i) ((x)[(i)/BITS_PER_WORD] |= (1<<((i) % BITS_PER_WORD)))
#define RESETBIT(x, i) ((x)[(i)/BITS_PER_WORD] &= ~(1<<((i) % BITS_PER_WORD)))
#define BITISSET(x, i) (((x)[(i)/BITS_PER_WORD] & (1<<((i) % BITS_PER_WORD))) != 0)

238
contrib/bison/main.c Normal file
View File

@ -0,0 +1,238 @@
/* Top level entry point of bison,
Copyright (C) 1984, 1986, 1989, 1992, 1995 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" /* 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();
if (failure)
done(failure);
/* 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.
Also resolve s/r conflicts based on precedence declarations. */
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 */
/* Return a string containing a printable version of C:
either C itself, or the corresponding \DDD code. */
char *
printable_version(c)
char c;
{
static char buf[10];
if (c < ' ' || c >= '\177')
sprintf(buf, "\\%o", c);
else
{
buf[0] = c;
buf[1] = '\0';
}
return buf;
}
/* Generate a string from the integer I.
Return a ptr to internal memory containing the string. */
char *
int_to_string(i)
int i;
{
static char buf[20];
sprintf(buf, "%d", i);
return buf;
}
/* Print the message S for a fatal error. */
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);
}
/* Print a message for a fatal error. Use FMT to construct the message
and incorporate string X1. */
void
fatals(fmt, x1)
char *fmt, *x1;
{
char buffer[200];
sprintf(buffer, fmt, x1);
fatal(buffer);
}
/* Print a warning message S. */
void
warn(s)
char *s;
{
extern char *infile;
if (infile == 0)
fprintf(stderr, "error: %s\n", s);
else
fprintf(stderr, "(\"%s\", line %d) error: %s\n",
infile, lineno, s);
failure = 1;
}
/* Print a warning message containing the string for the integer X1.
The message is given by the format FMT. */
void
warni(fmt, x1)
char *fmt;
int x1;
{
char buffer[200];
sprintf(buffer, fmt, x1);
warn(buffer);
}
/* Print a warning message containing the string X1.
The message is given by the format FMT. */
void
warns(fmt, x1)
char *fmt, *x1;
{
char buffer[200];
sprintf(buffer, fmt, x1);
warn(buffer);
}
/* Print a warning message containing the two strings X1 and X2.
The message is given by the format FMT. */
void
warnss(fmt, x1, x2)
char *fmt, *x1, *x2;
{
char buffer[200];
sprintf(buffer, fmt, x1, x2);
warn(buffer);
}
/* Print a warning message containing the 3 strings X1, X2, X3.
The message is given by the format FMT. */
void
warnsss(fmt, x1, x2, x3)
char *fmt, *x1, *x2, *x3;
{
char buffer[200];
sprintf(buffer, fmt, x1, x2, x3);
warn(buffer);
}
/* Print a message for the fatal occurence of more than MAXSHORT
instances of whatever is denoted by the string S. */
void
toomany(s)
char *s;
{
char buffer[200];
sprintf(buffer, "limit of %d exceeded, too many %s", MAXSHORT, s);
fatal(buffer);
}
/* Abort for an internal error denoted by string S. */
void
berror(s)
char *s;
{
fprintf(stderr, "internal error, %s\n", s);
abort();
}

40
contrib/bison/mkinstalldirs Executable file
View File

@ -0,0 +1,40 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.10 1996/05/03 07:37:52 friedman Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

31
contrib/bison/new.h Normal file
View File

@ -0,0 +1,31 @@
/* Storage allocation interface for bison,
Copyright (C) 1984, 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. */
#define NEW(t) ((t *) xmalloc((unsigned) sizeof(t)))
#define NEW2(n, t) ((t *) xmalloc((unsigned) ((n) * sizeof(t))))
#ifdef __STDC__
#define FREE(x) (x ? (void) free((char *) (x)) : (void)0)
#else
#define FREE(x) ((x) != 0 && (free ((char *) (x)), 0))
#endif
extern char *xmalloc();
extern char *xrealloc();

136
contrib/bison/nullable.c Normal file
View File

@ -0,0 +1,136 @@
/* Part of the bison parser generator,
Copyright (C) 1984, 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. */
/* set up nullable, a vector saying which nonterminals can expand into the null string.
nullable[i - ntokens] is nonzero if symbol i can do so. */
#include <stdio.h>
#include "system.h"
#include "types.h"
#include "gram.h"
#include "new.h"
char *nullable;
void
set_nullable()
{
register short *r;
register short *s1;
register short *s2;
register int ruleno;
register int symbol;
register shorts *p;
short *squeue;
short *rcount;
shorts **rsets;
shorts *relts;
char any_tokens;
short *r1;
#ifdef TRACE
fprintf(stderr, "Entering set_nullable");
#endif
nullable = NEW2(nvars, char) - ntokens;
squeue = NEW2(nvars, short);
s1 = s2 = squeue;
rcount = NEW2(nrules + 1, short);
rsets = NEW2(nvars, shorts *) - ntokens;
/* This is said to be more elements than we actually use.
Supposedly nitems - nrules is enough.
But why take the risk? */
relts = NEW2(nitems + nvars + 1, shorts);
p = relts;
r = ritem;
while (*r)
{
if (*r < 0)
{
symbol = rlhs[-(*r++)];
if (symbol >= 0 && !nullable[symbol])
{
nullable[symbol] = 1;
*s2++ = symbol;
}
}
else
{
r1 = r;
any_tokens = 0;
for (symbol = *r++; symbol > 0; symbol = *r++)
{
if (ISTOKEN(symbol))
any_tokens = 1;
}
if (!any_tokens)
{
ruleno = -symbol;
r = r1;
for (symbol = *r++; symbol > 0; symbol = *r++)
{
rcount[ruleno]++;
p->next = rsets[symbol];
p->value = ruleno;
rsets[symbol] = p;
p++;
}
}
}
}
while (s1 < s2)
{
p = rsets[*s1++];
while (p)
{
ruleno = p->value;
p = p->next;
if (--rcount[ruleno] == 0)
{
symbol = rlhs[ruleno];
if (symbol >= 0 && !nullable[symbol])
{
nullable[symbol] = 1;
*s2++ = symbol;
}
}
}
}
FREE(squeue);
FREE(rcount);
FREE(rsets + ntokens);
FREE(relts);
}
void
free_nullable()
{
FREE(nullable + ntokens);
}

1484
contrib/bison/output.c Normal file

File diff suppressed because it is too large Load Diff

373
contrib/bison/print.c Normal file
View File

@ -0,0 +1,373 @@
/* Print information on generated parser, 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. */
#include <stdio.h>
#include "system.h"
#include "machine.h"
#include "new.h"
#include "files.h"
#include "gram.h"
#include "state.h"
extern char **tags;
extern int nstates;
extern short *accessing_symbol;
extern core **state_table;
extern shifts **shift_table;
extern errs **err_table;
extern reductions **reduction_table;
extern char *consistent;
extern char any_conflicts;
extern char *conflicts;
extern int final_state;
extern void conflict_log();
extern void verbose_conflict_log();
extern void print_reductions();
void print_token();
void print_state();
void print_core();
void print_actions();
void print_grammar();
void
terse()
{
if (any_conflicts)
{
conflict_log();
}
}
void
verbose()
{
register int i;
if (any_conflicts)
verbose_conflict_log();
print_grammar();
for (i = 0; i < nstates; i++)
{
print_state(i);
}
}
void
print_token(extnum, token)
int extnum, token;
{
fprintf(foutput, " type %d is %s\n", extnum, tags[token]);
}
void
print_state(state)
int state;
{
fprintf(foutput, "\n\nstate %d\n\n", state);
print_core(state);
print_actions(state);
}
void
print_core(state)
int state;
{
register int i;
register int k;
register int rule;
register core *statep;
register short *sp;
register short *sp1;
statep = state_table[state];
k = statep->nitems;
if (k == 0) return;
for (i = 0; i < k; i++)
{
sp1 = sp = ritem + statep->items[i];
while (*sp > 0)
sp++;
rule = -(*sp);
fprintf(foutput, " %s -> ", tags[rlhs[rule]]);
for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
{
fprintf(foutput, "%s ", tags[*sp]);
}
putc('.', foutput);
while (*sp > 0)
{
fprintf(foutput, " %s", tags[*sp]);
sp++;
}
fprintf (foutput, " (rule %d)", rule);
putc('\n', foutput);
}
putc('\n', foutput);
}
void
print_actions(state)
int state;
{
register int i;
register int k;
register int state1;
register int symbol;
register shifts *shiftp;
register errs *errp;
register reductions *redp;
register int rule;
shiftp = shift_table[state];
redp = reduction_table[state];
errp = err_table[state];
if (!shiftp && !redp)
{
if (final_state == state)
fprintf(foutput, " $default\taccept\n");
else
fprintf(foutput, " NO ACTIONS\n");
return;
}
if (shiftp)
{
k = shiftp->nshifts;
for (i = 0; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
state1 = shiftp->shifts[i];
symbol = accessing_symbol[state1];
/* The following line used to be turned off. */
if (ISVAR(symbol)) break;
if (symbol==0) /* I.e. strcmp(tags[symbol],"$")==0 */
fprintf(foutput, " $ \tgo to state %d\n", state1);
else
fprintf(foutput, " %-4s\tshift, and go to state %d\n",
tags[symbol], state1);
}
if (i > 0)
putc('\n', foutput);
}
else
{
i = 0;
k = 0;
}
if (errp)
{
int j, nerrs;
nerrs = errp->nerrs;
for (j = 0; j < nerrs; j++)
{
if (! errp->errs[j]) continue;
symbol = errp->errs[j];
fprintf(foutput, " %-4s\terror (nonassociative)\n", tags[symbol]);
}
if (j > 0)
putc('\n', foutput);
}
if (consistent[state] && redp)
{
rule = redp->rules[0];
symbol = rlhs[rule];
fprintf(foutput, " $default\treduce using rule %d (%s)\n\n",
rule, tags[symbol]);
}
else if (redp)
{
print_reductions(state);
}
if (i < k)
{
for (; i < k; i++)
{
if (! shiftp->shifts[i]) continue;
state1 = shiftp->shifts[i];
symbol = accessing_symbol[state1];
fprintf(foutput, " %-4s\tgo to state %d\n", tags[symbol], state1);
}
putc('\n', foutput);
}
}
#define END_TEST(end) \
if (column + strlen(buffer) > (end)) \
{ fprintf (foutput, "%s\n ", buffer); column = 3; buffer[0] = 0; } \
else
void
print_grammar()
{
int i, j;
short* rule;
char buffer[90];
int column = 0;
/* rule # : LHS -> RHS */
fputs("\nGrammar\n", foutput);
for (i = 1; i <= nrules; i++)
/* Don't print rules disabled in reduce_grammar_tables. */
if (rlhs[i] >= 0)
{
fprintf(foutput, "rule %-4d %s ->", i, tags[rlhs[i]]);
rule = &ritem[rrhs[i]];
if (*rule > 0)
while (*rule > 0)
fprintf(foutput, " %s", tags[*rule++]);
else
fputs (" /* empty */", foutput);
putc('\n', foutput);
}
/* TERMINAL (type #) : rule #s terminal is on RHS */
fputs("\nTerminals, with rules where they appear\n\n", foutput);
fprintf(foutput, "%s (-1)\n", tags[0]);
if (translations)
{
for (i = 0; i <= max_user_token_number; i++)
if (token_translations[i] != 2)
{
buffer[0] = 0;
column = strlen (tags[token_translations[i]]);
fprintf(foutput, "%s", tags[token_translations[i]]);
END_TEST (50);
sprintf (buffer, " (%d)", i);
for (j = 1; j <= nrules; j++)
{
for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
if (*rule == token_translations[i])
{
END_TEST (65);
sprintf (buffer + strlen(buffer), " %d", j);
break;
}
}
fprintf (foutput, "%s\n", buffer);
}
}
else
for (i = 1; i < ntokens; i++)
{
buffer[0] = 0;
column = strlen (tags[i]);
fprintf(foutput, "%s", tags[i]);
END_TEST (50);
sprintf (buffer, " (%d)", i);
for (j = 1; j <= nrules; j++)
{
for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
if (*rule == i)
{
END_TEST (65);
sprintf (buffer + strlen(buffer), " %d", j);
break;
}
}
fprintf (foutput, "%s\n", buffer);
}
fputs("\nNonterminals, with rules where they appear\n\n", foutput);
for (i = ntokens; i <= nsyms - 1; i++)
{
int left_count = 0, right_count = 0;
for (j = 1; j <= nrules; j++)
{
if (rlhs[j] == i)
left_count++;
for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
if (*rule == i)
{
right_count++;
break;
}
}
buffer[0] = 0;
fprintf(foutput, "%s", tags[i]);
column = strlen (tags[i]);
sprintf (buffer, " (%d)", i);
END_TEST (0);
if (left_count > 0)
{
END_TEST (50);
sprintf (buffer + strlen(buffer), " on left:");
for (j = 1; j <= nrules; j++)
{
END_TEST (65);
if (rlhs[j] == i)
sprintf (buffer + strlen(buffer), " %d", j);
}
}
if (right_count > 0)
{
if (left_count > 0)
sprintf (buffer + strlen(buffer), ",");
END_TEST (50);
sprintf (buffer + strlen(buffer), " on right:");
for (j = 1; j <= nrules; j++)
{
for (rule = &ritem[rrhs[j]]; *rule > 0; rule++)
if (*rule == i)
{
END_TEST (65);
sprintf (buffer + strlen(buffer), " %d", j);
break;
}
}
}
fprintf (foutput, "%s\n", buffer);
}
}

2073
contrib/bison/reader.c Normal file

File diff suppressed because it is too large Load Diff

598
contrib/bison/reduce.c Normal file
View File

@ -0,0 +1,598 @@
/* Grammar reduction for Bison.
Copyright (C) 1988, 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. */
/*
* Reduce the grammar: Find and eliminate unreachable terminals,
* nonterminals, and productions. David S. Bakin.
*/
/*
* Don't eliminate unreachable terminals: They may be used by the user's
* parser.
*/
#include <stdio.h>
#include "system.h"
#include "files.h"
#include "gram.h"
#include "machine.h"
#include "new.h"
extern char **tags; /* reader.c */
extern int verboseflag; /* getargs.c */
static int statisticsflag; /* XXXXXXX */
#ifndef TRUE
#define TRUE (1)
#define FALSE (0)
#endif
typedef int bool;
typedef unsigned *BSet;
typedef short *rule;
/*
* N is set of all nonterminals which are not useless. P is set of all rules
* which have no useless nonterminals in their RHS. V is the set of all
* accessible symbols.
*/
static BSet N, P, V, V1;
static int nuseful_productions, nuseless_productions,
nuseful_nonterminals, nuseless_nonterminals;
static void useless_nonterminals();
static void inaccessable_symbols();
static void reduce_grammar_tables();
static void print_results();
static void print_notices();
void dump_grammar();
extern void fatals ();
bool
bits_equal (L, R, n)
BSet L;
BSet R;
int n;
{
int i;
for (i = n - 1; i >= 0; i--)
if (L[i] != R[i])
return FALSE;
return TRUE;
}
int
nbits (i)
unsigned i;
{
int count = 0;
while (i != 0) {
i ^= (i & -i);
++count;
}
return count;
}
int
bits_size (S, n)
BSet S;
int n;
{
int i, count = 0;
for (i = n - 1; i >= 0; i--)
count += nbits(S[i]);
return count;
}
void
reduce_grammar ()
{
bool reduced;
/* Allocate the global sets used to compute the reduced grammar */
N = NEW2(WORDSIZE(nvars), unsigned);
P = NEW2(WORDSIZE(nrules + 1), unsigned);
V = NEW2(WORDSIZE(nsyms), unsigned);
V1 = NEW2(WORDSIZE(nsyms), unsigned);
useless_nonterminals();
inaccessable_symbols();
reduced = (bool) (nuseless_nonterminals + nuseless_productions > 0);
if (verboseflag)
print_results();
if (reduced == FALSE)
goto done_reducing;
print_notices();
if (!BITISSET(N, start_symbol - ntokens))
fatals("Start symbol %s does not derive any sentence",
tags[start_symbol]);
reduce_grammar_tables();
/* if (verboseflag) {
fprintf(foutput, "REDUCED GRAMMAR\n\n");
dump_grammar();
}
*/
/**/ statisticsflag = FALSE; /* someday getopts should handle this */
if (statisticsflag == TRUE)
fprintf(stderr,
"reduced %s defines %d terminal%s, %d nonterminal%s\
, and %d production%s.\n", infile,
ntokens, (ntokens == 1 ? "" : "s"),
nvars, (nvars == 1 ? "" : "s"),
nrules, (nrules == 1 ? "" : "s"));
done_reducing:
/* Free the global sets used to compute the reduced grammar */
FREE(N);
FREE(V);
FREE(P);
}
/*
* Another way to do this would be with a set for each production and then do
* subset tests against N, but even for the C grammar the whole reducing
* process takes only 2 seconds on my 8Mhz AT.
*/
static bool
useful_production (i, N)
int i;
BSet N;
{
rule r;
short n;
/*
* A production is useful if all of the nonterminals in its RHS
* appear in the set of useful nonterminals.
*/
for (r = &ritem[rrhs[i]]; *r > 0; r++)
if (ISVAR(n = *r))
if (!BITISSET(N, n - ntokens))
return FALSE;
return TRUE;
}
/* Remember that rules are 1-origin, symbols are 0-origin. */
static void
useless_nonterminals ()
{
BSet Np, Ns;
int i, n;
/*
* N is set as built. Np is set being built this iteration. P is set
* of all productions which have a RHS all in N.
*/
Np = NEW2(WORDSIZE(nvars), unsigned);
/*
* The set being computed is a set of nonterminals which can derive
* the empty string or strings consisting of all terminals. At each
* iteration a nonterminal is added to the set if there is a
* production with that nonterminal as its LHS for which all the
* nonterminals in its RHS are already in the set. Iterate until the
* set being computed remains unchanged. Any nonterminals not in the
* set at that point are useless in that they will never be used in
* deriving a sentence of the language.
*
* This iteration doesn't use any special traversal over the
* productions. A set is kept of all productions for which all the
* nonterminals in the RHS are in useful. Only productions not in
* this set are scanned on each iteration. At the end, this set is
* saved to be used when finding useful productions: only productions
* in this set will appear in the final grammar.
*/
n = 0;
while (1)
{
for (i = WORDSIZE(nvars) - 1; i >= 0; i--)
Np[i] = N[i];
for (i = 1; i <= nrules; i++)
{
if (!BITISSET(P, i))
{
if (useful_production(i, N))
{
SETBIT(Np, rlhs[i] - ntokens);
SETBIT(P, i);
}
}
}
if (bits_equal(N, Np, WORDSIZE(nvars)))
break;
Ns = Np;
Np = N;
N = Ns;
}
FREE(N);
N = Np;
}
static void
inaccessable_symbols ()
{
BSet Vp, Vs, Pp;
int i, n;
short t;
rule r;
/*
* Find out which productions are reachable and which symbols are
* used. Starting with an empty set of productions and a set of
* symbols which only has the start symbol in it, iterate over all
* productions until the set of productions remains unchanged for an
* iteration. For each production which has a LHS in the set of
* reachable symbols, add the production to the set of reachable
* productions, and add all of the nonterminals in the RHS of the
* production to the set of reachable symbols.
*
* Consider only the (partially) reduced grammar which has only
* nonterminals in N and productions in P.
*
* The result is the set P of productions in the reduced grammar, and
* the set V of symbols in the reduced grammar.
*
* Although this algorithm also computes the set of terminals which are
* reachable, no terminal will be deleted from the grammar. Some
* terminals might not be in the grammar but might be generated by
* semantic routines, and so the user might want them available with
* specified numbers. (Is this true?) However, the nonreachable
* terminals are printed (if running in verbose mode) so that the user
* can know.
*/
Vp = NEW2(WORDSIZE(nsyms), unsigned);
Pp = NEW2(WORDSIZE(nrules + 1), unsigned);
/* If the start symbol isn't useful, then nothing will be useful. */
if (!BITISSET(N, start_symbol - ntokens))
goto end_iteration;
SETBIT(V, start_symbol);
n = 0;
while (1)
{
for (i = WORDSIZE(nsyms) - 1; i >= 0; i--)
Vp[i] = V[i];
for (i = 1; i <= nrules; i++)
{
if (!BITISSET(Pp, i) && BITISSET(P, i) &&
BITISSET(V, rlhs[i]))
{
for (r = &ritem[rrhs[i]]; *r >= 0; r++)
{
if (ISTOKEN(t = *r)
|| BITISSET(N, t - ntokens))
{
SETBIT(Vp, t);
}
}
SETBIT(Pp, i);
}
}
if (bits_equal(V, Vp, WORDSIZE(nsyms)))
{
break;
}
Vs = Vp;
Vp = V;
V = Vs;
}
end_iteration:
FREE(V);
V = Vp;
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
SETBIT(V, 0); /* end-of-input token */
SETBIT(V, 1); /* error token */
SETBIT(V, 2); /* some undefined token */
FREE(P);
P = Pp;
nuseful_productions = bits_size(P, WORDSIZE(nrules + 1));
nuseless_productions = nrules - nuseful_productions;
nuseful_nonterminals = 0;
for (i = ntokens; i < nsyms; i++)
if (BITISSET(V, i))
nuseful_nonterminals++;
nuseless_nonterminals = nvars - nuseful_nonterminals;
/* A token that was used in %prec should not be warned about. */
for (i = 1; i < nrules; i++)
if (rprecsym[i] != 0)
SETBIT(V1, rprecsym[i]);
}
static void
reduce_grammar_tables ()
{
/* This is turned off because we would need to change the numbers
in the case statements in the actions file. */
#if 0
/* remove useless productions */
if (nuseless_productions > 0)
{
short np, pn, ni, pi;
np = 0;
ni = 0;
for (pn = 1; pn <= nrules; pn++)
{
if (BITISSET(P, pn))
{
np++;
if (pn != np)
{
rlhs[np] = rlhs[pn];
rline[np] = rline[pn];
rprec[np] = rprec[pn];
rassoc[np] = rassoc[pn];
rrhs[np] = rrhs[pn];
if (rrhs[np] != ni)
{
pi = rrhs[np];
rrhs[np] = ni;
while (ritem[pi] >= 0)
ritem[ni++] = ritem[pi++];
ritem[ni++] = -np;
}
} else {
while (ritem[ni++] >= 0);
}
}
}
ritem[ni] = 0;
nrules -= nuseless_productions;
nitems = ni;
/*
* Is it worth it to reduce the amount of memory for the
* grammar? Probably not.
*/
}
#endif /* 0 */
/* Disable useless productions,
since they may contain useless nonterms
that would get mapped below to -1 and confuse everyone. */
if (nuseless_productions > 0)
{
int pn;
for (pn = 1; pn <= nrules; pn++)
{
if (!BITISSET(P, pn))
{
rlhs[pn] = -1;
}
}
}
/* remove useless symbols */
if (nuseless_nonterminals > 0)
{
int i, n;
/* short j; JF unused */
short *nontermmap;
rule r;
/*
* create a map of nonterminal number to new nonterminal
* number. -1 in the map means it was useless and is being
* eliminated.
*/
nontermmap = NEW2(nvars, short) - ntokens;
for (i = ntokens; i < nsyms; i++)
nontermmap[i] = -1;
n = ntokens;
for (i = ntokens; i < nsyms; i++)
if (BITISSET(V, i))
nontermmap[i] = n++;
/* Shuffle elements of tables indexed by symbol number. */
for (i = ntokens; i < nsyms; i++)
{
n = nontermmap[i];
if (n >= 0)
{
sassoc[n] = sassoc[i];
sprec[n] = sprec[i];
tags[n] = tags[i];
} else {
free(tags[i]);
}
}
/* Replace all symbol numbers in valid data structures. */
for (i = 1; i <= nrules; i++)
{
/* Ignore the rules disabled above. */
if (rlhs[i] >= 0)
rlhs[i] = nontermmap[rlhs[i]];
if (ISVAR (rprecsym[i]))
/* Can this happen? */
rprecsym[i] = nontermmap[rprecsym[i]];
}
for (r = ritem; *r; r++)
if (ISVAR(*r))
*r = nontermmap[*r];
start_symbol = nontermmap[start_symbol];
nsyms -= nuseless_nonterminals;
nvars -= nuseless_nonterminals;
free(&nontermmap[ntokens]);
}
}
static void
print_results ()
{
int i;
/* short j; JF unused */
rule r;
bool b;
if (nuseless_nonterminals > 0)
{
fprintf(foutput, "Useless nonterminals:\n\n");
for (i = ntokens; i < nsyms; i++)
if (!BITISSET(V, i))
fprintf(foutput, " %s\n", tags[i]);
}
b = FALSE;
for (i = 0; i < ntokens; i++)
{
if (!BITISSET(V, i) && !BITISSET(V1, i))
{
if (!b)
{
fprintf(foutput, "\n\nTerminals which are not used:\n\n");
b = TRUE;
}
fprintf(foutput, " %s\n", tags[i]);
}
}
if (nuseless_productions > 0)
{
fprintf(foutput, "\n\nUseless rules:\n\n");
for (i = 1; i <= nrules; i++)
{
if (!BITISSET(P, i))
{
fprintf(foutput, "#%-4d ", i);
fprintf(foutput, "%s :\t", tags[rlhs[i]]);
for (r = &ritem[rrhs[i]]; *r >= 0; r++)
{
fprintf(foutput, " %s", tags[*r]);
}
fprintf(foutput, ";\n");
}
}
}
if (nuseless_nonterminals > 0 || nuseless_productions > 0 || b)
fprintf(foutput, "\n\n");
}
void
dump_grammar ()
{
int i;
rule r;
fprintf(foutput,
"ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nitems = %d\n\n",
ntokens, nvars, nsyms, nrules, nitems);
fprintf(foutput, "Variables\n---------\n\n");
fprintf(foutput, "Value Sprec Sassoc Tag\n");
for (i = ntokens; i < nsyms; i++)
fprintf(foutput, "%5d %5d %5d %s\n",
i, sprec[i], sassoc[i], tags[i]);
fprintf(foutput, "\n\n");
fprintf(foutput, "Rules\n-----\n\n");
for (i = 1; i <= nrules; i++)
{
fprintf(foutput, "%-5d(%5d%5d)%5d : (@%-5d)",
i, rprec[i], rassoc[i], rlhs[i], rrhs[i]);
for (r = &ritem[rrhs[i]]; *r > 0; r++)
fprintf(foutput, "%5d", *r);
fprintf(foutput, " [%d]\n", -(*r));
}
fprintf(foutput, "\n\n");
fprintf(foutput, "Rules interpreted\n-----------------\n\n");
for (i = 1; i <= nrules; i++)
{
fprintf(foutput, "%-5d %s :", i, tags[rlhs[i]]);
for (r = &ritem[rrhs[i]]; *r > 0; r++)
fprintf(foutput, " %s", tags[*r]);
fprintf(foutput, "\n");
}
fprintf(foutput, "\n\n");
}
static void
print_notices ()
{
extern int fixed_outfiles;
if (fixed_outfiles && nuseless_productions)
fprintf(stderr, "%d rules never reduced\n", nuseless_productions);
fprintf(stderr, "%s contains ", infile);
if (nuseless_nonterminals > 0)
{
fprintf(stderr, "%d useless nonterminal%s",
nuseless_nonterminals,
(nuseless_nonterminals == 1 ? "" : "s"));
}
if (nuseless_nonterminals > 0 && nuseless_productions > 0)
fprintf(stderr, " and ");
if (nuseless_productions > 0)
{
fprintf(stderr, "%d useless rule%s",
nuseless_productions,
(nuseless_productions == 1 ? "" : "s"));
}
fprintf(stderr, "\n");
fflush(stderr);
}

137
contrib/bison/state.h Normal file
View File

@ -0,0 +1,137 @@
/* Type definitions for nondeterministic finite state machine for bison,
Copyright (C) 1984, 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. */
/* These type definitions are used to represent a nondeterministic
finite state machine that parses the specified grammar.
This information is generated by the function generate_states
in the file LR0.
Each state of the machine is described by a set of items --
particular positions in particular rules -- that are the possible
places where parsing could continue when the machine is in this state.
These symbols at these items are the allowable inputs that can follow now.
A core represents one state. States are numbered in the number field.
When generate_states is finished, the starting state is state 0
and nstates is the number of states. (A transition to a state
whose state number is nstates indicates termination.) All the cores
are chained together and first_state points to the first one (state 0).
For each state there is a particular symbol which must have been the
last thing accepted to reach that state. It is the accessing_symbol
of the core.
Each core contains a vector of nitems items which are the indices
in the ritems vector of the items that are selected in this state.
The link field is used for chaining buckets that hash states by
their itemsets. This is for recognizing equivalent states and
combining them when the states are generated.
The two types of transitions are shifts (push the lookahead token
and read another) and reductions (combine the last n things on the
stack via a rule, replace them with the symbol that the rule derives,
and leave the lookahead token alone). When the states are generated,
these transitions are represented in two other lists.
Each shifts structure describes the possible shift transitions out
of one state, the state whose number is in the number field.
The shifts structures are linked through next and first_shift points to them.
Each contains a vector of numbers of the states that shift transitions
can go to. The accessing_symbol fields of those states' cores say what kind
of input leads to them.
A shift to state zero should be ignored. Conflict resolution
deletes shifts by changing them to zero.
Each reductions structure describes the possible reductions at the state
whose number is in the number field. The data is a list of nreds rules,
represented by their rule numbers. first_reduction points to the list
of these structures.
Conflict resolution can decide that certain tokens in certain
states should explicitly be errors (for implementing %nonassoc).
For each state, the tokens that are errors for this reason
are recorded in an errs structure, which has the state number
in its number field. The rest of the errs structure is full
of token numbers.
There is at least one shift transition present in state zero.
It leads to a next-to-final state whose accessing_symbol is
the grammar's start symbol. The next-to-final state has one shift
to the final state, whose accessing_symbol is zero (end of input).
The final state has one shift, which goes to the termination state
(whose number is nstates-1).
The reason for the extra state at the end is to placate the parser's
strategy of making all decisions one token ahead of its actions. */
typedef
struct core
{
struct core *next;
struct core *link;
short number;
short accessing_symbol;
short nitems;
short items[1];
}
core;
typedef
struct shifts
{
struct shifts *next;
short number;
short nshifts;
short shifts[1];
}
shifts;
typedef
struct errs
{
short nerrs;
short errs[1];
}
errs;
typedef
struct reductions
{
struct reductions *next;
short number;
short nreds;
short rules[1];
}
reductions;
extern int nstates;
extern core *first_state;
extern shifts *first_shift;
extern reductions *first_reduction;

150
contrib/bison/symtab.c Normal file
View File

@ -0,0 +1,150 @@
/* Symbol table manager for Bison,
Copyright (C) 1984, 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 "new.h"
#include "symtab.h"
#include "gram.h"
bucket **symtab;
bucket *firstsymbol;
bucket *lastsymbol;
int
hash(key)
char *key;
{
register char *cp;
register int k;
cp = key;
k = 0;
while (*cp)
k = ((k << 1) ^ (*cp++)) & 0x3fff;
return (k % TABSIZE);
}
char *
copys(s)
char *s;
{
register int i;
register char *cp;
register char *result;
i = 1;
for (cp = s; *cp; cp++)
i++;
result = xmalloc((unsigned int)i);
strcpy(result, s);
return (result);
}
void
tabinit()
{
/* register int i; JF unused */
symtab = NEW2(TABSIZE, bucket *);
firstsymbol = NULL;
lastsymbol = NULL;
}
bucket *
getsym(key)
char *key;
{
register int hashval;
register bucket *bp;
register int found;
hashval = hash(key);
bp = symtab[hashval];
found = 0;
while (bp != NULL && found == 0)
{
if (strcmp(key, bp->tag) == 0)
found = 1;
else
bp = bp->link;
}
if (found == 0)
{
nsyms++;
bp = NEW(bucket);
bp->link = symtab[hashval];
bp->next = NULL;
bp->tag = copys(key);
bp->class = SUNKNOWN;
if (firstsymbol == NULL)
{
firstsymbol = bp;
lastsymbol = bp;
}
else
{
lastsymbol->next = bp;
lastsymbol = bp;
}
symtab[hashval] = bp;
}
return (bp);
}
void
free_symtab()
{
register int i;
register bucket *bp,*bptmp;/* JF don't use ptr after free */
for (i = 0; i < TABSIZE; i++)
{
bp = symtab[i];
while (bp)
{
bptmp = bp->link;
#if 0 /* This causes crashes because one string can appear more than once. */
if (bp->type_name)
FREE(bp->type_name);
#endif
FREE(bp);
bp = bptmp;
}
}
FREE(symtab);
}

56
contrib/bison/symtab.h Normal file
View File

@ -0,0 +1,56 @@
/* Definitions for symtab.c and callers, part of bison,
Copyright (C) 1984, 1989, 1992 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. */
#define TABSIZE 1009
/* symbol classes */
#define SUNKNOWN 0
#define STOKEN 1 /* terminal symbol */
#define SNTERM 2 /* non-terminal */
#define SALIAS -9991 /* for symbol generated with an alias */
typedef
struct bucket
{
struct bucket *link;
struct bucket *next;
char *tag;
char *type_name;
short value;
short prec;
short assoc;
short user_token_number;
/* special value SALIAS in the identifier
half of the identifier-symbol pair for an alias */
struct bucket *alias;
/* points to the other in the identifier-symbol
pair for an alias */
char class;
}
bucket;
extern bucket **symtab;
extern bucket *firstsymbol;
extern bucket *getsym();

25
contrib/bison/system.h Normal file
View File

@ -0,0 +1,25 @@
#ifdef MSDOS
#include <io.h>
#endif
#if defined(HAVE_STDLIB_H) || defined(MSDOS)
#include <stdlib.h>
#endif
#if (defined(VMS) || defined(MSDOS)) && !defined(HAVE_STRING_H)
#define HAVE_STRING_H 1
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#ifndef bcopy
#define bcopy(src, dst, num) memcpy((dst), (src), (num))
#endif
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */

27
contrib/bison/types.h Normal file
View File

@ -0,0 +1,27 @@
/* Define data type for representing bison's grammar input as it is parsed,
Copyright (C) 1984, 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. */
typedef
struct shorts
{
struct shorts *next;
short value;
}
shorts;

1
contrib/bison/version.c Normal file
View File

@ -0,0 +1 @@
char *version_string = "GNU Bison version 1.25\n";

180
contrib/bison/vmsgetargs.c Normal file
View File

@ -0,0 +1,180 @@
/* VMS version of getargs; Uses DCL command parsing.
Copyright (C) 1989, 1992 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 <ctype.h>
#include <stdio.h>
#include "files.h"
/*
* VMS version of getargs: Uses DCL command parsing
* (argc and argv are ignored)
*/
int verboseflag;
int definesflag;
int debugflag;
int nolinesflag;
extern int noparserflag;
extern int toknumflag;
extern int rawtoknumflag;
extern int fixed_outfiles;
extern char * version_string;
/* Allocate storgate and initialize, since bison uses them elsewhere. */
char *spec_name_prefix;
char *spec_file_prefix;
getargs(argc,argv)
int argc;
char *argv[];
{
register char *cp;
static char Input_File[256];
static char output_spec[256], name_prefix_spec[256], file_prefix_spec[256];
extern char *infile;
verboseflag = 0;
definesflag = 0;
debugflag = 0;
fixed_outfiles = 0;
nolinesflag = 0;
noparserflag = 0;
toknumflag = 0;
rawtoknumflag = 0;
/*
* Check for /VERBOSE qualifier
*/
if (cli_present("BISON$VERBOSE")) verboseflag = 1;
/*
* Check for /DEFINES qualifier
*/
if (cli_present("BISON$DEFINES")) definesflag = 1;
/*
* Check for /FIXED_OUTFILES qualifier
*/
if (cli_present("BISON$FIXED_OUTFILES")) fixed_outfiles = 1;
if (cli_present("BISON$YACC")) fixed_outfiles = 1;
/*
* Check for /VERSION qualifier
*/
if (cli_present("BISON$VERSION")) printf("%s",version_string);
/*
* Check for /NOLINES qualifier
*/
if (cli_present("BISON$NOLINES")) nolinesflag = 1;
/*
* Check for /NOPARSER qualifier
*/
if (cli_present("BISON$NOPARSER")) noparserflag = 1;
/*
* Check for /RAW qualifier
*/
if (cli_present("BISON$RAW")) rawtoknumflag = 1;
/*
* Check for /TOKEN_TABLE qualifier
*/
if (cli_present("BISON$TOKEN_TABLE")) toknumflag = 1;
/*
* Check for /DEBUG qualifier
*/
if (cli_present("BISON$DEBUG")) debugflag = 1;
/*
* Get the filename
*/
cli_get_value("BISON$INFILE", Input_File, sizeof(Input_File));
/*
* Lowercaseify the input filename
*/
cp = Input_File;
while(*cp)
{
if (isupper(*cp)) *cp = tolower(*cp);
cp++;
}
infile = Input_File;
/*
* Get the output file
*/
if (cli_present("BISON$OUTPUT"))
{
cli_get_value("BISON$OUTPUT", output_spec, sizeof(output_spec));
for (cp = spec_outfile = output_spec; *cp; cp++)
if (isupper(*cp))
*cp = tolower(*cp);
}
/*
* Get the output file
*/
if (cli_present("BISON$FILE_PREFIX"))
{
cli_get_value("BISON$FILE_PREFIX", file_prefix_spec,
sizeof(file_prefix_spec));
for (cp = spec_file_prefix = file_prefix_spec; *cp; cp++)
if (isupper(*cp))
*cp = tolower(*cp);
}
/*
* Get the output file
*/
if (cli_present("BISON$NAME_PREFIX"))
{
cli_get_value("BISON$NAME_PREFIX", name_prefix_spec,
sizeof(name_prefix_spec));
for (cp = spec_name_prefix = name_prefix_spec; *cp; cp++)
if (isupper(*cp))
*cp = tolower(*cp);
}
}
/************ DCL PARSING ROUTINES **********/
/*
* See if "NAME" is present
*/
int
cli_present(Name)
char *Name;
{
struct {int Size; char *Ptr;} Descr;
Descr.Ptr = Name;
Descr.Size = strlen(Name);
return((cli$present(&Descr) & 1) ? 1 : 0);
}
/*
* Get value of "NAME"
*/
int
cli_get_value(Name,Buffer,Size)
char *Name;
char *Buffer;
{
struct {int Size; char *Ptr;} Descr1,Descr2;
Descr1.Ptr = Name;
Descr1.Size = strlen(Name);
Descr2.Ptr = Buffer;
Descr2.Size = Size-1;
if (cli$get_value(&Descr1,&Descr2,&Descr2.Size) & 1) {
Buffer[Descr2.Size] = 0;
return(1);
}
return(0);
}

42
contrib/bison/vmshlp.mar Normal file
View File

@ -0,0 +1,42 @@
;/* Macro help routines for the BISON/VMS program
; Gabor Karsai, Vanderbilt University
;
;BISON is distributed in the hope that it will be useful, but WITHOUT ANY
;WARRANTY. No author or distributor accepts responsibility to anyone
;for the consequences of using it or for whether it serves any
;particular purpose or works at all, unless he says so in writing.
;Refer to the BISON General Public License for full details.
;
;Everyone is granted permission to copy, modify and redistribute BISON,
;but only under the conditions described in the BISON General Public
;License. A copy of this license is supposed to have been given to you
;along with BISON so you can know your rights and responsibilities. It
;should be in a file named COPYING. Among other things, the copyright
;notice and this notice must be preserved on all copies.
;
; In other words, you are welcome to use, share and improve this program.
; You are forbidden to forbid anyone else to use, share and improve
; what you give them. Help stamp out software-hoarding! */
;
.psect vmshlp pic,usr,rel,ovr,shr,long,exe,nowrt
alloca::
.word 0
subl2 ^X4(ap),sp
movl ^X10(fp),r1
movq ^X8(fp),ap
bicl2 #03,sp
addl2 #^X1c,sp
movl sp,r0
jmp (r1)
bcopy::
.word ^X0e00
movl ^X04(ap),r11
movl ^X08(ap),r10
movl ^X0c(ap),r9
brb 1$
2$: movb (r10)+,(r11)+
1$: sobgeq r9,2$
ret
.end

119
contrib/bison/warshall.c Normal file
View File

@ -0,0 +1,119 @@
/* Generate transitive closure of a matrix,
Copyright (C) 1984, 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"
/* given n by n matrix of bits R, modify its contents
to be the transive closure of what was given. */
void
TC(R, n)
unsigned *R;
int n;
{
register int rowsize;
register unsigned mask;
register unsigned *rowj;
register unsigned *rp;
register unsigned *rend;
register unsigned *ccol;
unsigned *relend;
unsigned *cword;
unsigned *rowi;
rowsize = WORDSIZE(n) * sizeof(unsigned);
relend = (unsigned *) ((char *) R + (n * rowsize));
cword = R;
mask = 1;
rowi = R;
while (rowi < relend)
{
ccol = cword;
rowj = R;
while (rowj < relend)
{
if (*ccol & mask)
{
rp = rowi;
rend = (unsigned *) ((char *) rowj + rowsize);
while (rowj < rend)
*rowj++ |= *rp++;
}
else
{
rowj = (unsigned *) ((char *) rowj + rowsize);
}
ccol = (unsigned *) ((char *) ccol + rowsize);
}
mask <<= 1;
if (mask == 0)
{
mask = 1;
cword++;
}
rowi = (unsigned *) ((char *) rowi + rowsize);
}
}
/* Reflexive Transitive Closure. Same as TC
and then set all the bits on the diagonal of R. */
void
RTC(R, n)
unsigned *R;
int n;
{
register int rowsize;
register unsigned mask;
register unsigned *rp;
register unsigned *relend;
TC(R, n);
rowsize = WORDSIZE(n) * sizeof(unsigned);
relend = (unsigned *) ((char *) R + n*rowsize);
mask = 1;
rp = R;
while (rp < relend)
{
*rp |= mask;
mask <<= 1;
if (mask == 0)
{
mask = 1;
rp++;
}
rp = (unsigned *) ((char *) rp + rowsize);
}
}