BSD 1 development
[unix-history] / eyacc / ey1.c
CommitLineData
c8f7ac22
CH
1# include "ey.h"
2 /* * * * * e y a c c * * * * */
3
4 /**** NB -----
5 *
6 * This version of yacc, known as "eyacc" has been slightly but
7 * importantly modified to allow error recovery in the UNIX Pascal
8 * translator "pi" and also in "pix".
9 *
10 * Changes here include:
11 *
12 * 1) Enumeration of test actions when "error" is an input token.
13 *
14 * 2) Change to the encoding of the action entries. Test entries
15 * are encoded as the arithmetic inverse of the symbol being tested
16 * for. This is an optimization that makes the parser run at the
17 * same speed even though, with error productions and enumerated
18 * lookaheads, it would normally be much slower. Of course the
19 * same thing could be done to the regular yacc...
20 *
21 * 3) Different table sizes
22 *
23 * 4) Recognizes form feeds
24 *
25 * 5) Also most of the numbers for the sizes of the tables have been
26 * increased, to an extent to allow for "eyacc"ing of the Pascal grammar
27 * and of a grammar which I have for "EUCLID".
28 *
29 * There seem to be subtle dependencies between the various magic
30 * numbers... I found some of them but to be safe most of the limits
31 * are very generous... for this reason "eyacc" will most likely
32 * have to run separate i/d... no matter.
33 *
34 * Bill Joy
35 * Computer Science Division
36 * EECS Department
37 * University of California, Berkeley
38 * Berkeley, California 94704
39 *
40 * Office: (415) 642-4948
41 * Home: (415) 524-4510
42 ****/
43
44 /* features to be fixed up ...
45
46 *** Print estimate of total space needed for parser
47 *** Either list inputs on y.output, or list empty prdn's in states
48 *** Mention nonterms not used (or, rules. not reduced) as nonfatal error
49 *** Output states where conflicts were found by default on y.output
50 *** Engage in newspeak: production=>grammar rules, term=>token, etc.
51 *** handle # define, #ifdef, etc., in yacc actions, %{ %}
52 */
53
54 /* new features to be added
55
56 *** reductions by single productions ( by request )
57 *** follow sets for start symbol
58 *** option to only do slr(1)
59 *** easily changed array names on output
60 *** allocate core, rather than predefined
61 *** input controlled by a grammar
62 *** support multiple choices for conflicts
63 *** better conflict diagnostics
64 */
65
66
67
68main(argc,argv) int argc; char *argv[]; {
69 auto int n;
70
71 whereami();
72 setup(argc,argv); /* initialize and read productions */
73 tbitset = (nterms+16)/16;
74 cpres(); /* make table of which productions yield a given nonterminal */
75 cempty(); /* make a table of which nonterminals can match the empty string */
76 cpfir(); /* make a table of e free first lists */
77 stagen(); /* generate the states */
78 output(); /* write the states and the tables */
79 go2out();
80 summary();
81 windup();
82 }
83
84whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */
85
86 int i;
87
88 i = 1;
89 i = i << 30;
90 if( i == 0 ) {
91 machine = UNIX;
92 return;
93 }
94 i = i << 4;
95 if( i == 0 ){
96 machine = IBM;
97 return;
98 }
99 machine = GCOS;
100 }
101
102windup(){
103 /* no errors, do the optimization if appropriate */
104 char *cp;
105 int i;
106
107 cflush(1);
108 if( !oflag ) cexit(0);
109
110 for( i=3; i<10; ++i ) cclose(i);
111 switch( machine ){
112
113 case GCOS:
114 if( rflag ){
115 if( foutput<0 ) system( "./yopt -r" );
116 else system( "./yopt -rv" );
117 }
118 else {
119 if( foutput<0 ) system( "./yopt" );
120 else system( "./yopt -v" );
121 }
122 cexit(0); /* terminate */
123
124 case UNIX:
125 cp = "/usr/nlib/yaccopt";
126 if( rflag ) execl( cp, cp, (foutput<0)?"-r":"-rv", 0 );
127 else if( foutput<0 ) execl( cp, cp, 0 );
128 else execl( cp, cp, "-v", 0 );
129 error( "optimization execl call fails" );
130
131 case IBM:
132 if( rflag ){
133 if( foutput<0 ) system( "MH2019.yaccopt -r" );
134 else system( "MH2019.yaccopt -rv" );
135 }
136 else {
137 if( foutput<0 ) system( "MH2019.yaccopt" );
138 else system( "MH2019.yaccopt -v" );
139 }
140 cexit(0);
141
142 }
143
144 }
145
146settty()
147/* sets the output file to y.output */
148{
149 cflush( foutput ); /* a bit of a cheat */
150 cout = foutput;
151 }
152
153settab(){ /* sets the output file to y.tab.c */
154
155 cflush( ftable );
156 cout = ftable;
157 }
158
159char *chcopy( p, q ) char *p, *q; {
160 /* copies string q into p, returning next free char ptr */
161 while( *p = *q++ ) ++p;
162 return( p );
163 }
164
165char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */
166 int i,*p;
167 static char sarr[100];
168 char *q;
169
170 for( p=pp->pitem; *p>0 ; ++p ) ;
171 p = prdptr[-*p];
172 q = chcopy( sarr, nontrst[*p-NTBASE].name );
173 q = chcopy( q, " : " );
174
175 for(;;){
176 *q++ = ++p==(pp->pitem) ? '_' : ' ';
177 if((i = *p) <= 0) break;
178 q = chcopy( q, symnam(i) );
179 }
180
181 *q = '\0' ;
182 return( sarr );
183 }
184
185char *symnam(i){ /* return a pointer to the name of symbol i */
186 char *cp;
187
188 cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ;
189 if( *cp == ' ' ) ++cp;
190 return( cp );
191 }
192
193summary(){ /* output the summary on the tty */
194
195 int i, s, *pn;
196
197
198 if( !rflag ){
199 settab();
200 printf("\nint nterms %d;",nterms);
201 printf("\nint nnonter %d;", nnonter);
202 printf("\nint nstate %d;", nstate);
203 printf("\nchar *yysterm[] {");
204 for (i=1;i<=nterms;i++) if( trmset[i].value >= 0400 ) printf("\n\"%s\",",symnam(i));
205 printf( "\n0 };\n" );
206 printf("\nchar *yysnter[] {");
207 for (i=0;i<nnonter;i++) printf("\n\"%s\",",nontrst[i].name);
208 printf("\n\"%s\" };\n",nontrst[nnonter].name);
209 }
210
211 settty();
212 printf("\n%d/%d terminals, %d/%d nonterminals\n", nterms, tlim,
213 nnonter, ntlim );
214 printf("%d/%d grammar rules, %d/%d states\n", nprod, prdlim, nstate, stsize );
215 printf("%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf );
216 pn = pstate[nstate+1];
217 printf("%d/%d working sets used\n", zzcwset, wssize );
218 printf("memory: states,etc. %d/%d, parser %d/%d\n", pn-mem0, memsiz,
219 memact, actsiz );
220 printf("%d/%d distinct lookahead sets\n", nlset, lsetsz );
221 printf("%d extra closures\n", zzclose - 2*nstate );
222 printf("%d action entries\n", zzacent );
223 printf("%d action entries saved through merging %d states\n",zzacsave,zznsave);
224 printf("%d goto entries\n", zzgoent );
225 printf("%d entries saved by goto default\n", zzgobest );
226 if( zzsrconf!=0 || zzrrconf!=0 ){
227 cflush( errfileno );
228 cout = errfileno;
229 printf("\nconflicts: ");
230 if( zzsrconf )printf( "%d shift/reduce" , zzsrconf );
231 if( zzsrconf && zzrrconf )printf( ", " );
232 if( zzrrconf )printf( "%d reduce/reduce" , zzrrconf );
233 printf( "\n" );
234 }
235 }
236
237error(s,a1){ /* write out error comment */
238
239 int c;
240 ++nerrors;
241 cflush( errfileno );
242 cout = errfileno; /* set output to tty */
243 printf("\n fatal error: ");
244 printf(s,a1);
245 printf(", line %d\n", lineno );
246 if( !fatfl ) return;
247 summary();
248 cexit(1);
249 }
250
251arrset(s) char s[]; {
252 printf("\nint %s[] {0", s );
253 arrndx = 1;
254 }
255
256arrval(n){
257 printf(",%d",n);
258 if( (++arrndx%10) == 0 ) printf("\n");
259 }
260
261arrdone(){
262 printf(",-1};\n");
263 }
264
265copy(v) char *v; { /* copy ctokn to v */
266 char *p;
267
268 p=ctokn;
269 while( *v++ = *p++ );
270 }
271
272compare(v) char *v; { /* compare ctokn with v */
273 char *p;
274
275 for( p=ctokn; ; ++p ){
276 if( *p != *v++ ) return( 0 );
277 if( *p == 0 ) return(1);
278 }
279 }
280
281int *yalloc(n){ /* allocate n+1 words from vector mem */
282 int *omem;
283 omem = mem;
284 mem =+ n+1;
285 if(mem-mem0 >= memsiz) error("memory overflow");
286 return(omem);
287 }
288
289aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */
290 int i;
291 for( i=0; i<n; ++i ) v[i] = c;
292 }
293
294union( a, b, c ) int *a, *b, *c; {
295 /* set a to the union of b and c */
296 /* a may equal b */
297 /* return 1 if c is not a subset of b, 0 otherwise */
298
299 _REGISTER int i, x, sub;
300
301 sub = 0;
302 for( i=0; i<tbitset; ++i ){
303 x = b[i] | c[i];
304 if( x != b[i] ) sub=1;
305 a[i] = x;
306 }
307 return( sub );
308 }
309
310prlook( pp ) int *pp;{
311 int j;
312 pp = pp->lset;
313 if( pp == 0 ) printf("\tNULL");
314 else {
315 printf(" { " );
316 for( j=1; j<=nterms; ++j ){
317 if( (pp[j>>4]>>(j&017) )&01 != 0 ) printf( "%s ", symnam(j) );
318 }
319 printf( "}" );
320 }
321 }