[comp.sys.m6809] Bison.os9 Part 1 of 5.

jimomura@lsuc.UUCP (Jim Omura) (09/13/87)

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#	Run the following text with /bin/sh to create:
#	Copying
#	Makefile
#	Makefile.old
#	References
#	allocate.c
#	bison.hairy
#	bison.simple
#	closure.c
#	conflicts.c
# By:	Jim Omura ()
cat << \SHAR_EOF > Copying



                    BISON GENERAL PUBLIC LICENSE

 Copyright (C) 1986 Richard M. Stallman
 Everyone is permitted to copy and distribute verbatim copies
 of this license, but changing it is not allowed.

  The license agreements of most software companies keep you at the
mercy of those companies.  By contrast, our general public license is
intended to give everyone the right to share BISON.  To make sure that
you get the rights we want you to have, we need to make restrictions
that forbid anyone to deny you these rights or to ask you to surrender
the rights.  Hence this license agreement.

  Specifically, we want to make sure that you have the right to give
away copies of BISON, that you receive source code or else can get it
if you want it, that you can change BISON or use pieces of it in new
free programs, and that you know you can do these things.

  To make sure that everyone has such rights, we have to forbid you to
deprive anyone else of these rights.  For example, if you distribute
copies of BISON, 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 tell them their rights.

  Also, for our own protection, we must make certain that everyone
finds out that there is no warranty for BISON.  If BISON is modified by
someone else and passed on, we want its recipients to know that what
they have is not what we distributed, so that any problems introduced
by others will not reflect on our reputation.

  Therefore we (Richard Stallman and the Free Software Fundation,
Inc.) make the following terms which say what you must do to be
allowed to distribute or change BISON.


                        COPYING POLICIES

  1. You may copy and distribute verbatim copies of BISON source code as
you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy a valid copyright notice "Copyright
(C) 1986 Free Software Foundation, Inc." (or with the year updated if
that is appropriate); keep intact the notices on all files that refer
to this License Agreement and to the absence of any warranty; and give
any other recipients of the BISON program a copy of this License
Agreement along with the program.

  2. You may modify your copy or copies of BISON or any portion of it,
and copy and distribute such modifications under the terms of
Paragraph 1 above, provided that you also do the following:

    a) cause the modified files to carry prominent notices stating
    that you changed the files and the date of any change; and

    b) cause the whole of any work that you distribute or publish,
    that in whole or in part contains or is a derivative of BISON
    or any part thereof, to be freely distributed
    and licensed to all third parties on terms identical to those
    contained in this License Agreement (except that you may choose
    to grant more extensive warranty protection to third parties,
    at your option).

    c) if the modified program serves as a debugger, cause it
    when started running in the simplest and usual way, to print
    an announcement including a valid copyright notice
    "Copyright (C) 1986 Free Software Foundation, Inc." (or with
    the year updated if appropriate), saying 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 Agreement.

  3. You may copy and distribute BISON or any portion of it in
compiled, executable or object code form under the terms of Paragraphs
1 and 2 above provided that you do the following:

    a) cause each such copy to be accompanied by the
    corresponding machine-readable source code, which must
    be distributed under the terms of Paragraphs 1 and 2 above; or,

    b) cause each such copy to be accompanied by a
    written offer, with no time limit, to give any third party
    free (except for a nominal shipping charge) a machine readable
    copy of the corresponding source code, to be distributed
    under the terms of Paragraphs 1 and 2 above; or,

    c) in the case of a recipient of BISON in compiled, executable
    or object code form (without the corresponding source code) you
    shall cause copies you distribute to be accompanied by a copy
    of the written offer of source code which you received along
    with the copy you received.

  4. You may not copy, sublicense, distribute or transfer BISON
except as expressly provided under this License Agreement.  Any attempt
otherwise to copy, sublicense, distribute or transfer BISON is void and
your rights to use the program under this License agreement shall be
automatically terminated.  However, parties who have received computer
software programs from you with this License Agreement will not have
their licenses terminated so long as such parties remain in full compliance.

In other words, go ahead and share BISON, but don't try to stop
anyone else from sharing it farther.  Help stamp out software hoarding!

                       NO WARRANTY

  BECAUSE BISON IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO
WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE BISON "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 BISON IS WITH YOU.  SHOULD BISON PROVE DEFECTIVE, YOU
ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
WHO MAY MODIFY AND REDISTRIBUTE BISON AS PERMITTED ABOVE, BE LIABLE TO
YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) BISON, EVEN
IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR
ANY CLAIM BY ANY OTHER PARTY.
SHAR_EOF
cat << \SHAR_EOF > Makefile
# Makefile for bison

# where the installed binary goes
ODIR = /h0/cmds
MAIN = bison

# where the parsers go
PARSERDIR = /h0/lib

# names of parser files
PFILE = bison.simple
PFILE1 = bison.hairy

# It is unwise ever to compile a program without symbols.
CFLAGS = -ixt=/r0
RDIR   = RELS

PFILES = -DXPFILE="$(PARSERDIR)/$(PFILE)" \
         -DXPFILE1="$(PARSERDIR)/$(PFILE1)"

OBJS    = lr0.r allocate.r closure.r conflicts.r derives.r files.r \
          getargs.r gram.r lalr.r lex.r main.r nullable.r output.r \
	  print.r reader.r symtab.r warshall.r

$(ODIR)/$(MAIN): $(OBJS)
  chd $(RDIR); cc $(CFLAGS) $(OBJS) -f=$(ODIR)/$(MAIN)

# This file is different to pass the parser file names
# to the compiler.

files.r: files.c files.h new.h gram.h
        cc $(CFLAGS) $(PFILES) files.c -r=$(RDIR)

# dependencies on the include files

lr0.r: machine.h new.h gram.h state.h
closure.r: machine.h new.h gram.h
conflicts.r: machine.h new.h files.h gram.h state.h
derives.r: new.h types.h gram.h
getargs.r: files.h
lalr.r: machine.h types.h state.h new.h gram.h
lex.r: files.h symtab.h lex.h
main.r: machine.h
nullable.r: types.h gram.h new.h
output.r: machine.h new.h files.h gram.h state.h
print.r: machine.h new.h files.h gram.h state.h
reader.r: files.h new.h symtab.h lex.h gram.h
symtab.r: new.h symtab.h gram.h
warshall.r: machine.h

# E O F

SHAR_EOF
cat << \SHAR_EOF > Makefile.old
# Makefile for bison

# where the installed binary goes
BINDIR = /usr/local

# where the parsers go
PARSERDIR = /usr/local/lib

# names of parser files
PFILE = bison.simple
PFILE1 = bison.hairy

# It is unwise ever to compile a program without symbols.
CFLAGS = -g

PFILES = -DXPFILE=\"$(PARSERDIR)/$(PFILE)\" \
         -DXPFILE1=\"$(PARSERDIR)/$(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 symtab.o    \
          warshall.o

start: bison

clean:
        rm -f *.o core

install: bison
        install bison $(BINDIR)
        install -c $(PFILE) $(PFILE1) $(PARSERDIR)

bison: $(OBJECTS)
        $(CC) -g -o bison $(OBJECTS)

# This file is different to pass the parser file names
# to the compiler.
files.o: files.c files.h new.h gram.h
        $(CC) -c $(CFLAGS) $(PFILES) files.c

LR0.o: machine.h new.h gram.h state.h
closure.o: machine.h new.h gram.h
conflicts.o: machine.h new.h files.h gram.h state.h
derives.o: new.h types.h gram.h
getargs.o: files.h
lalr.o: machine.h types.h state.h new.h gram.h
lex.o: files.h symtab.h lex.h
main.o: machine.h
nullable.o: types.h gram.h new.h
output.o: machine.h new.h files.h gram.h state.h
print.o: machine.h new.h files.h gram.h state.h
reader.o: files.h new.h symtab.h lex.h gram.h
symtab.o: new.h symtab.h gram.h
warshall.o: machine.h
SHAR_EOF
cat << \SHAR_EOF > References
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 gets you the nth item
>from the parse stack.

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; their technique is the standard one now.  I don't
remember anymore where their paper first appeared but it is well
known.

        paul rubin
        free software foundation


SHAR_EOF
cat << \SHAR_EOF > allocate.c
/* Allocate and clear storage for bison,
   Copyright (C) 1984 Bob Corbett and Free Software Foundation, Inc.

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!  */

#include <stdio.h>


char *
allocate(n)
register unsigned n;
{
  register char *block;
  register char *cp;
  register char *cend;
  register int *ip;

  extern char *calloc();

  block = calloc(n,1);
  if (block == NULL)
    {
      fprintf(stderr, "storage limit exceeded");
      done(1);
    }

  return (block);
}

#ifdef OSK

         /* ADDITIONAL ROUTINES REQUIRED FOR OS-9 V2.0 SYSTEMS */
         
/*
 *	a substitute for the standard realloc function
 */
char *realloc (oldptr, newsize)
char *oldptr;
int newsize;
{   
	register char *newptr;
	register int i;
	extern char *malloc();
	if ((newptr = malloc(newsize)) == (char *)0)
		return (char *)0;
/*  
 *	new block allocated ok, copy old contents to it
 */ 
	for (i=0; i<newsize; i++)
		newptr[i] = oldptr[i];
	free (oldptr);
	return newptr;	
}

/* 
 * ALLOCA - should allocate an memory area and free it when the calling
 *          routine returns. This version doesn't automatically free the
 *          memory. Instead an ALLOCA(-1) call must be inserted in front
 *          of each RETURN statement in the calling routine. (sigh)
 */
 
char *alloca_pointer;
char *alloca(i)
int i;
{
	if (i == -1) {
		free(alloca_pointer);
		return(0);
	} else
		return(alloca_pointer = allocate(i));
}

/*
 * bcopy() -- copy N bytes from S1 to S2
 */

bcopy(s1, s2, n)
char	*s1, *s2;
int	n;
{           
        if (s1 == s2)
            return;
        if (s1 < s2)
        {
            s1 += n - 1;
            s2 += n - 1;
            while (n--)
                *s2-- = *s1--;
        }
        else
        {
            while (n--)
                *s2++ = *s1++;
        }
}
#endif

/* E O F */

SHAR_EOF
cat << \SHAR_EOF > bison.hairy
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;
}

/* E O F */
SHAR_EOF
cat << \SHAR_EOF > bison.simple
#line 2 "bison.simple"

/* Skeleton output parser for bison,
   copyright (C) 1984 Bob Corbett and Richard Stallman

   Permission is granted to anyone to make or distribute verbatim copies of this program
   provided that the copyright notice and this permission notice are preserved;
   and provided that the recipient is not asked to waive or limit his right to
   redistribute copies as permitted by this permission notice;
   and provided that anyone possessing an executable copy
   is granted access to copy the source code, in machine-readable form,
   in some reasonable manner.

   Permission is granted to distribute derived works or enhanced versions of
   this program under the above conditions with the additional condition
   that the entire derivative or enhanced work
   must be covered by a permission notice identical to this one.

   Anything distributed as part of a package containing portions derived
   from this program, which cannot in current practice perform its function usefully
   in the absense of what was derived directly from this program,
   is to be considered as forming, together with the latter,
   a single work derived from this program,
   which must be entirely covered by a permission notice identical to this one
   in order for distribution of the package to be permitted.

 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!  */

/* 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 YYFAIL          goto yyerrlab;

#define YYTERROR        1

#ifndef YYIMPURE
#define YYLEX           yylex()
#endif

#ifndef YYPURE
#define YYLEX           yylex(&yylval, &yylloc)
#endif

/* If nonreentrant, generate the variables here */

#ifndef YYIMPURE

int     yychar;                 /*  the lookahead symbol                */
YYSTYPE yylval;                 /*  the semantic value of the           */
                                /*  lookahead symbol                    */

YYLTYPE yylloc;                 /*  location data for the lookahead     */
                                /*  symbol                              */

int yydebug = 0;                /*  nonzero means print parse trace     */

#endif  /* YYIMPURE */


/*  YYMAXDEPTH indicates the initial size of the parser's stacks        */

#ifndef YYMAXDEPTH
#define YYMAXDEPTH 200
#endif

/*  YYMAXLIMIT is the maximum size the stacks can grow to
    (effective only if the built-in stack extension method is used).  */

#ifndef YYMAXLIMIT
#define YYMAXLIMIT 10000
#endif


#line 87 "bison.simple"
int
yyparse()
{
  register int yystate;
  register int yyn;
  register short *yyssp;
  register YYSTYPE *yyvsp;
  YYLTYPE *yylsp;
  int yyerrstatus;      /*  number of tokens to shift before error messages enabled */
  int yychar1;          /*  lookahead token as an internal (translated) token number */

  short yyssa[YYMAXDEPTH];      /*  the state stack                     */
  YYSTYPE yyvsa[YYMAXDEPTH];    /*  the semantic value stack            */
  YYLTYPE yylsa[YYMAXDEPTH];    /*  the location stack                  */

  short *yyss = yyssa;          /*  refer to the stacks thru separate pointers */
  YYSTYPE *yyvs = yyvsa;        /*  to allow yyoverflow to reallocate them elsewhere */
  YYLTYPE *yyls = yylsa;

  int yymaxdepth = YYMAXDEPTH;

#ifndef YYPURE

  int yychar;
  YYSTYPE yylval;
  YYLTYPE yylloc;

  extern int yydebug;

#endif


  YYSTYPE yyval;                /*  the variable used to return         */
                                /*  semantic values from the action     */
                                /*  routines                            */

  int yylen;

  if (yydebug)
    fprintf(stderr, "Starting parse\n");

  yystate = 0;
  yyerrstatus = 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.  */

  yyssp = yyss - 1;
  yyvsp = yyvs;
  yylsp = yyls;

/* 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 + yymaxdepth - 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;
      YYLTYPE *yyls1 = yyls;
      short *yyss1 = yyss;

      /* 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.  */
      yyoverflow("parser stack overflow",
                 &yyss1, size * sizeof (*yyssp),
                 &yyvs1, size * sizeof (*yyvsp),
                 &yyls1, size * sizeof (*yylsp),
                 &yymaxdepth);

      yyss = yyss1; yyvs = yyvs1; yyls = yyls1;
#else /* no yyoverflow */
      /* Extend the stack our own way.  */
      if (yymaxdepth >= YYMAXLIMIT)
        yyerror("parser stack overflow");
      yymaxdepth *= 2;
      if (yymaxdepth > YYMAXLIMIT)
        yymaxdepth = YYMAXLIMIT;
#ifdef OSK
/* 
 * We don't have ALLOCA & BCOPY in the OS-9 lib. so we use MALLOC and
 * _STRASS. WARNING: the MALLOC'ed space must be FREEd again at the
 * exit of the routine (ALLOCA does this automatically)
 */
      yyss = (short *) malloc (yymaxdepth * sizeof (*yyssp));
      _strass ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
      yyls = (YYLTYPE *) malloc (yymaxdepth * sizeof (*yylsp));
      _strass ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
      yyvs = (YYSTYPE *) malloc (yymaxdepth * sizeof (*yyvsp));
      _strass ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
#else
      yyss = (short *) alloca (yymaxdepth * sizeof (*yyssp));
      bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
      yyls = (YYLTYPE *) alloca (yymaxdepth * sizeof (*yylsp));
      bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
      yyvs = (YYSTYPE *) alloca (yymaxdepth * sizeof (*yyvsp));
      bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
#endif
#endif /* no yyoverflow */

      yyssp = yyss + size - 1;
      yylsp = yyls + size - 1;
      yyvsp = yyvs + size - 1;

      if (yydebug)
        fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);

      if (yyssp >= yyss + yymaxdepth - 1)
        YYERROR;
    }

  if (yydebug)
    fprintf(stderr, "Entering state %d\n", yystate);

/* 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)
    {
      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)
        fprintf(stderr, "Now at end of input.\n");
    }
  else
    {
      yychar1 = YYTRANSLATE(yychar);

      if (yydebug)
        fprintf(stderr, "Parsing next token; it is %d (%s)\n", yychar, yytname[yychar1]);
    }

  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)
    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);

  /* Discard the token being shifted unless it is eof.  */
  if (yychar != YYEOF)
    yychar = YYEMPTY;

  *++yyvsp = yylval;
#ifdef OSK
  _strass(++yylsp, &yylloc, sizeof(yylloc));
#else
  *++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];
  yyval = yyvsp[1-yylen]; /* implement default value of the action */

  if (yydebug)
    {
      if (yylen == 1)
        fprintf (stderr, "Reducing 1 value via line %d, ",
                 yyrline[yyn]);
      else
        fprintf (stderr, "Reducing %d values via line %d, ",
                 yylen, yyrline[yyn]);
    }

$   /* the action file gets copied in in place of this dollarsign */
#line 303 "bison.simple"

  yyvsp -= yylen;
  yylsp -= yylen;
  yyssp -= yylen;

  if (yydebug)
    {
      short *ssp1 = yyss - 1;
      fprintf (stderr, "state stack now", yyssp-yyss);
      while (ssp1 != yyssp)
        fprintf (stderr, " %d", *++ssp1);
      fprintf (stderr, "\n");
    }

  *++yyvsp = yyval;

  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;
    }

  /* 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.  */
    {
      yyerror("parse error");
    }

  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)
        YYERROR;

      if (yydebug)
        fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);

      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. */

#ifndef THIS_WILL_NEVER_BE_DEFINED
  /* 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) YYERROR;
  yyvsp--;
  yylsp--;
  yystate = *--yyssp;

  if (yydebug)
    {
      short *ssp1 = yyss - 1;
      fprintf (stderr, "Error: state stack now", yyssp-yyss);
      while (ssp1 != yyssp)
        fprintf (stderr, " %d", *++ssp1);
      fprintf (stderr, "\n");
    }

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)
    fprintf(stderr, "Shifting error token, ");

  *++yyvsp = yylval;
#ifdef OSK
  _strass(++yylsp, &yylloc, sizeof(yylloc));
#else
  *++yylsp = yylloc;
#endif

  yystate = yyn;
  goto yynewstate;
}

/* E O F */
SHAR_EOF
cat << \SHAR_EOF > closure.c
/* Subroutines for bison
   Copyright (C) 1984 Bob Corbett and Free Software Foundation, Inc.

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!  */

/* 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 "machine.h"
#include "new.h"
#include "gram.h"


extern short **derives;


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;



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.  */

set_fderives()
{
  register unsigned *rrow;
  register unsigned *vrow;
  register int j;
  register unsigned mask;
  register unsigned cword;
  register short *rp;

  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++;
      mask = 1;
      for (j = ntokens; j < nsyms; j++)
        {
          if (cword & mask)
            {
              rp = derives[j];
              while ((ruleno = *rp++) > 0)
                {
                  SETBIT(rrow, ruleno);
                }
            }

          mask <<= 1;
          if (mask == 0 && j + 1 < nsyms)
            {
              cword = *vrow++;
              mask = 1;
            }
        }

      vrow += varsetsize;
      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. */

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
}



closure(core, n)
short *core;
int n;
{
  register int ruleno;
  register unsigned word;
  register unsigned mask;
  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
        {
          mask = 1;
          while (mask)
            {
              if (word & mask)
                {
                  itemno = rrhs[ruleno];
                  while (csp < csend && *csp < itemno)
                    *itemsetend++ = *csp++;
                  *itemsetend++ = itemno;
                }

              mask <<= 1;
              ruleno++;
            }
        }
    }

  while (csp < csend)
    *itemsetend++ = *csp++;

#ifdef  DEBUG
  print_closure(n);
#endif
}



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;
  register unsigned cword;
  register unsigned mask;

  extern char **tags;

  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) * vrowsize);

      cword = *rowp++;
      mask = 1;
      for (j = 0; j < nsyms; j++)
        {
          if (cword & mask)
            printf("   %s\n", tags[j + ntokens]);

          mask <<= 1;

          if (mask == 0 && j + 1 < nsyms)
            {
              cword = *rowp++;
              mask = 1;
            }
        }
    }
}



print_fderives()
{
  register int i;
  register int j;
  register unsigned *rp;
  register unsigned cword;
  register unsigned mask;

  extern char **tags;

  printf("\n\n\nFDERIVES\n");

  for (i = ntokens; i < nsyms; i++)
    {
      printf("\n\n%s derives\n\n", tags[i]);
      rp = fderives + i * rrowsize;
      cword = *rp++;
      mask = 1;
      for (j = 0; j <= nrules; j++)
        {
          if (cword & mask)
            printf("   %d\n", j);

          mask <<= 1;
          if (mask == 0 && j + 1 < nrules)
            {
              cword = *rp++;
              mask = 1;
            }
        }
    }

  fflush(stdout);
}

#endif
SHAR_EOF
cat << \SHAR_EOF > conflicts.c
/* Find and resolve or report look-ahead conflicts for bison,
   Copyright (C) 1984 Bob Corbett and Free Software Foundation, Inc.

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!  */

#include <stdio.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;

char any_conflicts;
char *conflicts;
errs **err_table;


static unsigned *shiftset;
static unsigned *lookaheadset;
static int src_total;
static int rrc_total;
static int src_count;
static int rrc_count;



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);
}



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.  */

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 *) alloca (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 precision.
           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 *) allocate ((unsigned int)i);
      bcopy (errp, err_table[state], i);
    }
  else
    err_table[state] = 0;
#ifdef OSK
    alloca(-1);
#endif
}



/* 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.  */

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;
        }
    }
}



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);
}



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();
}
  


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();
}



total_conflicts()
{
  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);
}



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++;
        }
    }
}



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++;
        }
    }
}



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  %d  (%s)]\n",
                    tags[i], default_rule, tags[rlhs[default_rule]]);

          mask <<= 1;
          if (mask == 0)
            {
              mask = 1;
              fp3++;
            }
        }

      fprintf(foutput, "    $default\treduce  %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  %d  (%s)\n",
                                  tags[i], rule, tags[rlhs[rule]]);
                        }
                      else defaulted = 1;

                      count++;
                    }
                  else
                    {
                      if (defaulted)
                        {
                          rule = LAruleno[default_LA];
                          fprintf(foutput, "    %-4s\treduce  %d  (%s)\n",
                                  tags[i], rule, tags[rlhs[rule]]);
                          defaulted = 0;
                        }
                      rule = LAruleno[j];
                      fprintf(foutput, "    %-4s\t[reduce  %d  (%s)]\n",
                              tags[i], rule, tags[rlhs[rule]]);
                    }
                }

              fp3 += tokensetsize;
            }

          mask <<= 1;
          if (mask == 0)
            {
              mask = 1;
              fp1++;
            }
        }

      if (default_LA >= 0)
        {
          fprintf(foutput, "    $default\treduce  %d  (%s)\n",
                  default_rule, tags[rlhs[default_rule]]);
        }

      putc('\n', foutput);
    }
}



finalize_conflicts()
{
  FREE(conflicts);
  FREE(shiftset);
  FREE(lookaheadset);
}
SHAR_EOF
#	End of shell archive
exit 0
-- 
Jim Omura, 2A King George's Drive, Toronto, (416) 652-3880
ihnp4!utzoo!lsuc!jimomura
Byte Information eXchange: jimomura