4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
29 #pragma ident "%Z%%M% %I% %E% SMI"
33 static void go2gen(int);
34 static void precftn(int, int, int);
35 static void wract(int);
36 static void wrstate(int);
37 static void wdef(wchar_t *, int);
38 static void wrmbchars(void);
39 /* important local variables */
40 static int lastred
; /* number of the last reduction of a state */
45 /* print the output for the states */
52 (void) fprintf(ftable
, "static YYCONST yytabelem yyexca[] ={\n");
54 SLOOP(i
) { /* output the stuff for state i */
55 nolook
= !(tystate
[i
] == MUSTLOOKAHEAD
);
59 aryfil(temp1
, ntoksz
+nnontersz
+1, 0);
62 if (c
> 1 && c
< NTBASE
&& temp1
[c
] == 0) {
69 } else if (c
> NTBASE
&&
70 temp1
[(c
-= NTBASE
) + ntokens
] == 0) {
71 temp1
[c
+ ntokens
] = amem
[indgo
[i
] + c
];
75 temp1
[1] = ACCEPTCODE
;
76 /* now, we have the shifts; look at the reductions */
80 if (c
<= 0) { /* reduction */
83 if (BIT(u
->ws
.lset
, k
)) {
86 else if (temp1
[k
] < 0) {
93 (void) fprintf(foutput
,
94 WSFMT("\n%d: reduce/reduce conflict"
95 " (red'ns %d and %d ) on %ws"),
98 if (-temp1
[k
] > lastred
)
108 precftn(lastred
, k
, i
);
116 (void) fprintf(ftable
, "\t};\n");
117 wdef(L
"YYNPROD", nprod
);
123 static int pkdebug
= 0;
129 /* pack state i from temp1 into amem */
136 * we don't need to worry about checking because we
137 * we will only look up entries known to be there...
140 /* eliminate leading and trailing 0's */
143 for (pp
= p
, off
= 0; *pp
== 0 && pp
<= q
; ++pp
, --off
)
146 return (0); /* no actions */
149 /* now, find a place for the elements from p to q, inclusive */
150 /* for( rr=amem; rr<=r; ++rr,++off ){ */ /* try rr */
152 for (; ; ++rr
, ++off
) {
153 while (rr
>= &amem
[new_actsize
-1])
156 for (pp
= p
; pp
<= q
; ++pp
, ++qq
) {
159 while (qq
>= &amem
[new_actsize
-1]) {
163 if (*pp
!= *qq
&& *qq
!= 0)
168 /* we have found an acceptable k */
170 if (pkdebug
&& foutput
!= NULL
)
171 (void) fprintf(foutput
,
172 "off = %d, k = %" PRIdPTR
"\n", off
, rr
-amem
);
175 for (pp
= p
; pp
<= q
; ++pp
, ++qq
) {
178 while (qq
>= &amem
[new_actsize
-1]) {
187 if (pkdebug
&& foutput
!= NULL
) {
188 for (pp
= amem
; pp
<= memp
; pp
+= 10) {
189 (void) fprintf(foutput
, "\t");
190 for (qq
= pp
; qq
<= pp
+ 9; ++qq
)
191 (void) fprintf(foutput
, "%d ", *qq
);
192 (void) fprintf(foutput
, "\n");
198 /* error("no space in action table" ); */
205 /* output the gotos for the nontermninals */
206 int i
, j
, k
, best
, count
, cbest
, times
;
208 (void) fprintf(ftemp
, "$\n"); /* mark begining of gotos */
210 for (i
= 1; i
<= nnonter
; ++i
) {
212 /* find the best one to make default */
215 for (j
= 0; j
< nstate
; ++j
) { /* is j the most frequent */
218 if (tystate
[j
] == best
)
220 /* is tystate[j] the most frequent */
223 for (k
= j
; k
< nstate
; ++k
)
224 if (tystate
[k
] == cbest
)
232 /* best is now the default entry */
233 zzgobest
+= (times
-1);
234 for (j
= 0; j
< nstate
; ++j
) {
235 if (tystate
[j
] != 0 && tystate
[j
] != best
) {
236 (void) fprintf(ftemp
, "%d,%d,", j
, tystate
[j
]);
241 /* now, the default */
244 (void) fprintf(ftemp
, "%d\n", best
);
249 static int g2debug
= 0;
250 static void go2gen(int c
)
252 /* output the gotos for nonterminal c */
256 /* first, find nonterminals with gotos on c */
257 aryfil(temp1
, nnonter
+ 1, 0);
264 if ((cc
= prdptr
[i
][1] - NTBASE
) >= 0) {
265 /* cc is a nonterminal */
266 if (temp1
[cc
] != 0) {
269 * thus, the left side of
270 * production i does too.
272 cc
= *prdptr
[i
] - NTBASE
;
273 if (temp1
[cc
] == 0) {
282 /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
284 if (g2debug
&& foutput
!= NULL
) {
285 (void) fprintf(foutput
, WSFMT("%ws: gotos on "),
287 NTLOOP(i
) if (temp1
[i
])
288 (void) fprintf(foutput
, WSFMT("%ws "), nontrst
[i
].name
);
289 (void) fprintf(foutput
, "\n");
292 /* now, go through and put gotos into tystate */
293 aryfil(tystate
, nstate
, 0);
296 if ((cc
= *p
->pitem
) >= NTBASE
) {
297 if (temp1
[cc
-= NTBASE
]) {
298 /* goto on c is possible */
299 tystate
[i
] = amem
[indgo
[i
] + c
];
307 /* decide a shift/reduce conflict by precedence. */
309 precftn(int r
, int t
, int s
)
313 * r is a rule number, t a token number
314 * the conflict is in state s
315 * temp1[t] is changed to reflect the action
322 if (PLEVEL(lt
) == 0 || PLEVEL(lp
) == 0) {
325 (void) fprintf(foutput
,
326 WSFMT("\n%d: shift/reduce conflict"
327 " (shift %d, red'n %d) on %ws"),
328 s
, temp1
[t
], r
, symnam(t
));
332 if (PLEVEL(lt
) == PLEVEL(lp
))
333 action
= ASSOC(lt
) & ~04;
334 else if (PLEVEL(lt
) > PLEVEL(lp
))
335 action
= RASC
; /* shift */
337 action
= LASC
; /* reduce */
340 case BASC
: /* error action */
343 case LASC
: /* reduce */
353 /* temp1 has the actions, lastred the default */
355 int ntimes
, tred
, count
, j
;
358 /* find the best choice for lastred */
365 if (temp1
[j
] + lastred
== 0)
367 /* count the number of appearances of temp1[j] */
370 levprd
[tred
] |= REDFLAG
;
372 if (temp1
[p
] + tred
== 0)
375 if (count
> ntimes
) {
382 * for error recovery, arrange that, if there is a shift on the
383 * error recovery token, `error', that the default be the error action
388 /* clear out entries in temp1 which equal lastred */
390 if (temp1
[p
] + lastred
== 0)
399 if ((p1
= temp1
[p0
]) != 0) {
403 } else if (p1
== ACCEPTCODE
) {
406 } else if (p1
== ERRCODE
) {
411 (void) fprintf(ftable
, "-1, %d,\n", i
);
412 (void) fprintf(ftable
,
413 "\t%d, %d,\n", tokset
[p0
].value
, p1
);
416 (void) fprintf(ftemp
,
417 "%d,%d,", tokset
[p0
].value
, p1
);
424 (void) fprintf(ftable
, "\t-2, %d,\n", lastred
);
426 (void) fprintf(ftemp
, "\n");
434 register ITEM
*pp
, *qq
;
439 (void) fprintf(foutput
, "\nstate %d\n", i
);
441 (void) fprintf(foutput
, WSFMT("\t%ws\n"), writem(pp
->pitem
));
443 if (tystate
[i
] == MUSTLOOKAHEAD
) {
444 /* print out empty productions in closure */
445 WSLOOP(wsets
+ (pstate
[i
+ 1] - pstate
[i
]), u
) {
447 (void) fprintf(foutput
,
448 WSFMT("\t%ws\n"), writem(u
->pitem
));
452 /* check for state equal to another */
453 TLOOP(j0
) if ((j1
= temp1
[j0
]) != 0) {
454 (void) fprintf(foutput
, WSFMT("\n\t%ws "), symnam(j0
));
455 if (j1
> 0) { /* shift, error, or accept */
456 if (j1
== ACCEPTCODE
)
457 (void) fprintf(foutput
, "accept");
458 else if (j1
== ERRCODE
)
459 (void) fprintf(foutput
, "error");
461 (void) fprintf(foutput
, "shift %d", j1
);
464 (void) fprintf(foutput
, "reduce %d", -j1
);
467 /* output the final production */
469 (void) fprintf(foutput
, "\n\t. reduce %d\n\n", lastred
);
471 (void) fprintf(foutput
, "\n\t. error\n\n");
473 /* now, output nonterminal actions */
475 for (j0
= 1; j0
<= nnonter
; ++j0
) {
477 (void) fprintf(foutput
,
478 WSFMT("\t%ws goto %d\n"),
479 symnam(j0
+ NTBASE
), temp1
[j1
]);
484 wdef(wchar_t *s
, int n
)
486 /* output a definition of s to the value n */
487 (void) fprintf(ftable
, WSFMT("# define %ws %d\n"), s
, n
);
496 (void) fprintf(ftable
, WSFMT("static YYCONST yytabelem %ws[]={\n"), s
);
497 for (i
= 0; i
< n
; ) {
499 (void) fprintf(ftable
, "\n");
500 (void) fprintf(ftable
, "%6d", v
[i
]);
502 (void) fprintf(ftable
, " };\n");
504 (void) fprintf(ftable
, ",");
512 * in order to free up the mem and amem arrays for the optimizer,
513 * and still be able to output yyr1, etc., after the sizes of
514 * the action array is known, we hide the nonterminals
515 * derived by productions in levprd.
523 if (!(levprd
[i
] & REDFLAG
)) {
525 if (foutput
!= NULL
) {
526 (void) fprintf(foutput
,
527 WSFMT("Rule not reduced: %ws\n"),
531 levprd
[i
] = *prdptr
[i
] - NTBASE
;
535 * TRANSLATION_NOTE -- This is a message from yacc.
536 * Check how 'reduced' is translated in yacc man page/document.
538 (void) fprintf(stderr
,
539 gettext("%d rules never reduced\n"),
548 /* Compare two MBLITs. */
549 return ((p
->character
) - (q
->character
));
556 wdef(L
"YYNMBCHARS", nmbchars
);
557 qsort(mbchars
, nmbchars
, sizeof (*mbchars
),
558 (int (*)(const void *, const void *))cmpmbchars
);
559 (void) fprintf(ftable
,
560 "static struct{\n\twchar_t character;"
561 "\n\tint tvalue;\n}yymbchars[YYNMBCHARS]={\n");
562 for (i
= 0; i
< nmbchars
; ++i
) {
563 (void) fprintf(ftable
, "\t{%#x,%d}",
564 (int)mbchars
[i
].character
, mbchars
[i
].tvalue
);
565 if (i
< nmbchars
- 1) {
567 (void) fprintf(ftable
, ",\n");
570 (void) fprintf(ftable
, "\n};\n");