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