xref: /onnv-gate/usr/src/cmd/sgs/yacc/common/y2.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */
28*0Sstevel@tonic-gate /* All Rights Reserved */
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #include "dextern"
33*0Sstevel@tonic-gate #include "sgs.h"
34*0Sstevel@tonic-gate #define	IDENTIFIER 257
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate #define	MARK 258
37*0Sstevel@tonic-gate #define	TERM 259
38*0Sstevel@tonic-gate #define	LEFT 260
39*0Sstevel@tonic-gate #define	RIGHT 261
40*0Sstevel@tonic-gate #define	BINARY 262
41*0Sstevel@tonic-gate #define	PREC 263
42*0Sstevel@tonic-gate #define	LCURLY 264
43*0Sstevel@tonic-gate #define	C_IDENTIFIER 265  /* name followed by colon */
44*0Sstevel@tonic-gate #define	NUMBER 266
45*0Sstevel@tonic-gate #define	START 267
46*0Sstevel@tonic-gate #define	TYPEDEF 268
47*0Sstevel@tonic-gate #define	TYPENAME 269
48*0Sstevel@tonic-gate #define	UNION 270
49*0Sstevel@tonic-gate #define	ENDFILE 0
50*0Sstevel@tonic-gate #define	LHS_TEXT_LEN		80	/* length of lhstext */
51*0Sstevel@tonic-gate #define	RHS_TEXT_LEN		640	/* length of rhstext */
52*0Sstevel@tonic-gate 	/* communication variables between various I/O routines */
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate #define	v_FLAG	0x01
55*0Sstevel@tonic-gate #define	d_FLAG	0x02
56*0Sstevel@tonic-gate #define	DEFAULT_PREFIX	"y"
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate char *infile;				/* input file name 		*/
59*0Sstevel@tonic-gate static int numbval;			/* value of an input number 	*/
60*0Sstevel@tonic-gate static int toksize = NAMESIZE;
61*0Sstevel@tonic-gate static wchar_t *tokname;	/* input token name		*/
62*0Sstevel@tonic-gate char *parser = NULL;		/* location of common parser 	*/
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate static void finact(void);
65*0Sstevel@tonic-gate static wchar_t *cstash(wchar_t *);
66*0Sstevel@tonic-gate static void defout(void);
67*0Sstevel@tonic-gate static void cpyunion(void);
68*0Sstevel@tonic-gate static void cpycode(void);
69*0Sstevel@tonic-gate static void cpyact(int);
70*0Sstevel@tonic-gate static void lhsfill(wchar_t *);
71*0Sstevel@tonic-gate static void rhsfill(wchar_t *);
72*0Sstevel@tonic-gate static void lrprnt(void);
73*0Sstevel@tonic-gate static void beg_debug(void);
74*0Sstevel@tonic-gate static void end_toks(void);
75*0Sstevel@tonic-gate static void end_debug(void);
76*0Sstevel@tonic-gate static void exp_tokname(void);
77*0Sstevel@tonic-gate static void exp_prod(void);
78*0Sstevel@tonic-gate static void exp_ntok(void);
79*0Sstevel@tonic-gate static void exp_nonterm(void);
80*0Sstevel@tonic-gate static int defin(int, wchar_t *);
81*0Sstevel@tonic-gate static int gettok(void);
82*0Sstevel@tonic-gate static int chfind(int, wchar_t *);
83*0Sstevel@tonic-gate static int skipcom(void);
84*0Sstevel@tonic-gate static int findchtok(int);
85*0Sstevel@tonic-gate static void put_prefix_define(char *);
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate /* storage of names */
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate /*
91*0Sstevel@tonic-gate  * initial block to place token and
92*0Sstevel@tonic-gate  * nonterminal names are stored
93*0Sstevel@tonic-gate  * points to initial block - more space
94*0Sstevel@tonic-gate  * is allocated as needed.
95*0Sstevel@tonic-gate  */
96*0Sstevel@tonic-gate static wchar_t cnamesblk0[CNAMSZ];
97*0Sstevel@tonic-gate static wchar_t *cnames = cnamesblk0;
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate /* place where next name is to be put in */
100*0Sstevel@tonic-gate static wchar_t *cnamp = cnamesblk0;
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate /* number of defined symbols output */
103*0Sstevel@tonic-gate static int ndefout = 3;
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	/* storage of types */
106*0Sstevel@tonic-gate static int defunion = 0;	/* union of types defined? */
107*0Sstevel@tonic-gate static int ntypes = 0;		/* number of types defined */
108*0Sstevel@tonic-gate static wchar_t *typeset[NTYPES]; /* pointers to type tags */
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate 	/* symbol tables for tokens and nonterminals */
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate int ntokens = 0;
113*0Sstevel@tonic-gate int ntoksz = NTERMS;
114*0Sstevel@tonic-gate TOKSYMB *tokset;
115*0Sstevel@tonic-gate int *toklev;
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate int nnonter = -1;
118*0Sstevel@tonic-gate NTSYMB *nontrst;
119*0Sstevel@tonic-gate int nnontersz = NNONTERM;
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate static int start;	/* start symbol */
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 	/* assigned token type values */
124*0Sstevel@tonic-gate static int extval = 0;
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	/* input and output file descriptors */
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate FILE *finput;		/* yacc input file */
129*0Sstevel@tonic-gate FILE *faction;		/* file for saving actions */
130*0Sstevel@tonic-gate FILE *fdefine;		/* file for # defines */
131*0Sstevel@tonic-gate FILE *ftable;		/* y.tab.c file */
132*0Sstevel@tonic-gate FILE *ftemp;		/* tempfile to pass 2 */
133*0Sstevel@tonic-gate FILE *fdebug;		/* where the strings for debugging are stored */
134*0Sstevel@tonic-gate FILE *foutput;		/* y.output file */
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate 	/* output string */
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate static wchar_t *lhstext;
139*0Sstevel@tonic-gate static wchar_t *rhstext;
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate 	/* storage for grammar rules */
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate int *mem0; /* production storage */
144*0Sstevel@tonic-gate int *mem;
145*0Sstevel@tonic-gate int *tracemem;
146*0Sstevel@tonic-gate extern int *optimmem;
147*0Sstevel@tonic-gate int new_memsize = MEMSIZE;
148*0Sstevel@tonic-gate int nprod = 1;	/* number of productions */
149*0Sstevel@tonic-gate int nprodsz = NPROD;
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate int **prdptr;
152*0Sstevel@tonic-gate int *levprd;
153*0Sstevel@tonic-gate wchar_t *had_act;
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate /* flag for generating the # line's default is yes */
156*0Sstevel@tonic-gate int gen_lines = 1;
157*0Sstevel@tonic-gate int act_lines = 0;
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate /* flag for whether to include runtime debugging */
160*0Sstevel@tonic-gate static int gen_testing = 0;
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate /* flag for version stamping--default turned off */
163*0Sstevel@tonic-gate static char *v_stmp = "n";
164*0Sstevel@tonic-gate 
165*0Sstevel@tonic-gate #ifndef NOLIBW	/* No wchar_t, no multibyte char handling! */
166*0Sstevel@tonic-gate int nmbchars = 0;	/* number of mb literals in mbchars */
167*0Sstevel@tonic-gate MBCLIT *mbchars = (MBCLIT *) 0; /* array of mb literals */
168*0Sstevel@tonic-gate int nmbcharsz = 0; /* allocated space for mbchars */
169*0Sstevel@tonic-gate #endif /* !NOLIBW */
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate void
172*0Sstevel@tonic-gate setup(argc, argv)
173*0Sstevel@tonic-gate int argc;
174*0Sstevel@tonic-gate char *argv[];
175*0Sstevel@tonic-gate {	int ii, i, j, lev, t, ty;
176*0Sstevel@tonic-gate 		/* ty is the sequencial number of token name in tokset */
177*0Sstevel@tonic-gate 	int c;
178*0Sstevel@tonic-gate 	int *p;
179*0Sstevel@tonic-gate 	char *cp;
180*0Sstevel@tonic-gate 	wchar_t actname[8];
181*0Sstevel@tonic-gate 	unsigned int options = 0;
182*0Sstevel@tonic-gate 	char *file_prefix = DEFAULT_PREFIX;
183*0Sstevel@tonic-gate 	char *sym_prefix = "";
184*0Sstevel@tonic-gate #define	F_NAME_LENGTH	128
185*0Sstevel@tonic-gate 	char	fname[F_NAME_LENGTH+1];
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 	extern char	*optarg;
188*0Sstevel@tonic-gate 	extern int	optind;
189*0Sstevel@tonic-gate 	extern 		getopt();
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 	foutput = NULL;
192*0Sstevel@tonic-gate 	fdefine = NULL;
193*0Sstevel@tonic-gate 	i = 1;
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate 	tokname = (wchar_t *)malloc(sizeof (wchar_t) * toksize);
196*0Sstevel@tonic-gate 	tokset = (TOKSYMB *)malloc(sizeof (TOKSYMB) * ntoksz);
197*0Sstevel@tonic-gate 	toklev = (int *)malloc(sizeof (int) * ntoksz);
198*0Sstevel@tonic-gate 	nontrst = (NTSYMB *)malloc(sizeof (NTSYMB) * nnontersz);
199*0Sstevel@tonic-gate 	mem0 = (int *)malloc(sizeof (int) * new_memsize);
200*0Sstevel@tonic-gate 	prdptr = (int **)malloc(sizeof (int *) * (nprodsz+2));
201*0Sstevel@tonic-gate 	levprd = (int *)malloc(sizeof (int) * (nprodsz+2));
202*0Sstevel@tonic-gate 	had_act = (wchar_t *)calloc((nprodsz + 2), sizeof (wchar_t));
203*0Sstevel@tonic-gate 	lhstext = (wchar_t *)malloc(sizeof (wchar_t) * LHS_TEXT_LEN);
204*0Sstevel@tonic-gate 	rhstext = (wchar_t *)malloc(sizeof (wchar_t) * RHS_TEXT_LEN);
205*0Sstevel@tonic-gate 	aryfil(toklev, ntoksz, 0);
206*0Sstevel@tonic-gate 	aryfil(levprd, nprodsz, 0);
207*0Sstevel@tonic-gate 	for (ii = 0; ii < ntoksz; ++ii)
208*0Sstevel@tonic-gate 		tokset[ii].value = 0;
209*0Sstevel@tonic-gate 	for (ii = 0; ii < nnontersz; ++ii)
210*0Sstevel@tonic-gate 		nontrst[ii].tvalue = 0;
211*0Sstevel@tonic-gate 	aryfil(mem0, new_memsize, 0);
212*0Sstevel@tonic-gate 	mem = mem0;
213*0Sstevel@tonic-gate 	tracemem = mem0;
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "vVdltp:Q:Y:P:b:")) != EOF)
216*0Sstevel@tonic-gate 		switch (c) {
217*0Sstevel@tonic-gate 		case 'v':
218*0Sstevel@tonic-gate 			options |= v_FLAG;
219*0Sstevel@tonic-gate 			break;
220*0Sstevel@tonic-gate 		case 'V':
221*0Sstevel@tonic-gate 			(void) fprintf(stderr, "yacc: %s %s\n",
222*0Sstevel@tonic-gate 			    (const char *)SGU_PKG,
223*0Sstevel@tonic-gate 			    (const char *)SGU_REL);
224*0Sstevel@tonic-gate 			break;
225*0Sstevel@tonic-gate 		case 'Q':
226*0Sstevel@tonic-gate 			v_stmp = optarg;
227*0Sstevel@tonic-gate 			if (*v_stmp != 'y' && *v_stmp != 'n')
228*0Sstevel@tonic-gate /*
229*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
230*0Sstevel@tonic-gate  *	This message is passed to error() function.
231*0Sstevel@tonic-gate  *	Do not translate -Q and [y/n].
232*0Sstevel@tonic-gate  */
233*0Sstevel@tonic-gate 				error(gettext(
234*0Sstevel@tonic-gate 			"yacc: -Q should be followed by [y/n]"));
235*0Sstevel@tonic-gate 			break;
236*0Sstevel@tonic-gate 		case 'd':
237*0Sstevel@tonic-gate 			options |= d_FLAG;
238*0Sstevel@tonic-gate 			break;
239*0Sstevel@tonic-gate 		case 'l':
240*0Sstevel@tonic-gate 			gen_lines = 0;	/* don't gen #lines */
241*0Sstevel@tonic-gate 			break;
242*0Sstevel@tonic-gate 		case 't':
243*0Sstevel@tonic-gate 			gen_testing = 1;	/* set YYDEBUG on */
244*0Sstevel@tonic-gate 			break;
245*0Sstevel@tonic-gate 		case 'Y':
246*0Sstevel@tonic-gate 			cp = (char *)malloc(strlen(optarg)+
247*0Sstevel@tonic-gate 				sizeof ("/yaccpar") + 1);
248*0Sstevel@tonic-gate 			cp = strcpy(cp, optarg);
249*0Sstevel@tonic-gate 			parser = strcat(cp, "/yaccpar");
250*0Sstevel@tonic-gate 			break;
251*0Sstevel@tonic-gate 		case 'P':
252*0Sstevel@tonic-gate 			parser = optarg;
253*0Sstevel@tonic-gate 			break;
254*0Sstevel@tonic-gate 		case 'p':
255*0Sstevel@tonic-gate 			if (strcmp(optarg, "yy") != 0)
256*0Sstevel@tonic-gate 				sym_prefix = optarg;
257*0Sstevel@tonic-gate 			else
258*0Sstevel@tonic-gate 				sym_prefix = "";
259*0Sstevel@tonic-gate 			break;
260*0Sstevel@tonic-gate 		case 'b':
261*0Sstevel@tonic-gate 			file_prefix = optarg;
262*0Sstevel@tonic-gate 			break;
263*0Sstevel@tonic-gate 		case '?':
264*0Sstevel@tonic-gate 		default:
265*0Sstevel@tonic-gate /*
266*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
267*0Sstevel@tonic-gate  *	This message is passed to error() function.
268*0Sstevel@tonic-gate  *	This is a usage message. The translate should be
269*0Sstevel@tonic-gate  *	consistent with man page translation.
270*0Sstevel@tonic-gate  */
271*0Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(
272*0Sstevel@tonic-gate "Usage: yacc [-vVdltY] [-Q(y/n)] [-b file_prefix] [-p sym_prefix]"
273*0Sstevel@tonic-gate " [-P parser] file\n"));
274*0Sstevel@tonic-gate 			exit(1);
275*0Sstevel@tonic-gate 		}
276*0Sstevel@tonic-gate 	/*
277*0Sstevel@tonic-gate 	 * Open y.output if -v is specified
278*0Sstevel@tonic-gate 	 */
279*0Sstevel@tonic-gate 	if (options & v_FLAG) {
280*0Sstevel@tonic-gate 		strncpy(fname,
281*0Sstevel@tonic-gate 			file_prefix,
282*0Sstevel@tonic-gate 			F_NAME_LENGTH-strlen(".output"));
283*0Sstevel@tonic-gate 		strcat(fname, ".output");
284*0Sstevel@tonic-gate 		foutput = fopen(fname, "w");
285*0Sstevel@tonic-gate 		if (foutput == NULL)
286*0Sstevel@tonic-gate 			error(gettext(
287*0Sstevel@tonic-gate 			"cannot open y.output"));
288*0Sstevel@tonic-gate 	}
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate 	/*
291*0Sstevel@tonic-gate 	 * Open y.tab.h if -d is specified
292*0Sstevel@tonic-gate 	 */
293*0Sstevel@tonic-gate 	if (options & d_FLAG) {
294*0Sstevel@tonic-gate 		strncpy(fname,
295*0Sstevel@tonic-gate 			file_prefix,
296*0Sstevel@tonic-gate 			F_NAME_LENGTH-strlen(".tab.h"));
297*0Sstevel@tonic-gate 		strcat(fname, ".tab.h");
298*0Sstevel@tonic-gate 		fdefine = fopen(fname, "w");
299*0Sstevel@tonic-gate 		if (fdefine == NULL)
300*0Sstevel@tonic-gate 			error(gettext(
301*0Sstevel@tonic-gate 			"cannot open y.tab.h"));
302*0Sstevel@tonic-gate 	}
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate 	fdebug = fopen(DEBUGNAME, "w");
305*0Sstevel@tonic-gate 	if (fdebug == NULL)
306*0Sstevel@tonic-gate /*
307*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
308*0Sstevel@tonic-gate  *	This message is passed to error() function.
309*0Sstevel@tonic-gate  *	Do not translate yacc.debug.
310*0Sstevel@tonic-gate  */
311*0Sstevel@tonic-gate 		error(gettext(
312*0Sstevel@tonic-gate 		"cannot open yacc.debug"));
313*0Sstevel@tonic-gate 	/*
314*0Sstevel@tonic-gate 	 * Open y.tab.c
315*0Sstevel@tonic-gate 	 */
316*0Sstevel@tonic-gate 	strncpy(fname,
317*0Sstevel@tonic-gate 		file_prefix,
318*0Sstevel@tonic-gate 		F_NAME_LENGTH-strlen(".tab.c"));
319*0Sstevel@tonic-gate 	strcat(fname, ".tab.c");
320*0Sstevel@tonic-gate 	ftable = fopen(fname, "w");
321*0Sstevel@tonic-gate 	if (ftable == NULL)
322*0Sstevel@tonic-gate 		error(gettext(
323*0Sstevel@tonic-gate 		"cannot open %s"), fname);
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate 	ftemp = fopen(TEMPNAME, "w");
326*0Sstevel@tonic-gate 	faction = fopen(ACTNAME, "w");
327*0Sstevel@tonic-gate 	if (ftemp == NULL || faction == NULL)
328*0Sstevel@tonic-gate /*
329*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
330*0Sstevel@tonic-gate  *	This message is passed to error() function.
331*0Sstevel@tonic-gate  *	The message means: "Could not open a temporary file."
332*0Sstevel@tonic-gate  */
333*0Sstevel@tonic-gate 		error(gettext(
334*0Sstevel@tonic-gate 		"cannot open temp file"));
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate 	if ((finput = fopen(infile = argv[optind], "r")) == NULL)
337*0Sstevel@tonic-gate /*
338*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
339*0Sstevel@tonic-gate  *	This message is passed to error() function.
340*0Sstevel@tonic-gate  */
341*0Sstevel@tonic-gate 		error(gettext(
342*0Sstevel@tonic-gate 		"cannot open input file"));
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 	lineno = 1;
345*0Sstevel@tonic-gate 	cnamp = cnames;
346*0Sstevel@tonic-gate 	(void) defin(0, L"$end");
347*0Sstevel@tonic-gate 	extval = 0400;
348*0Sstevel@tonic-gate 	(void) defin(0, L"error");
349*0Sstevel@tonic-gate 	(void) defin(1, L"$accept");
350*0Sstevel@tonic-gate 	mem = mem0;
351*0Sstevel@tonic-gate 	lev = 0;
352*0Sstevel@tonic-gate 	ty = 0;
353*0Sstevel@tonic-gate 	i = 0;
354*0Sstevel@tonic-gate 	beg_debug();	/* initialize fdebug file */
355*0Sstevel@tonic-gate 
356*0Sstevel@tonic-gate 	/*
357*0Sstevel@tonic-gate 	 * sorry -- no yacc parser here.....
358*0Sstevel@tonic-gate 	 *	we must bootstrap somehow...
359*0Sstevel@tonic-gate 	 */
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate 	t = gettok();
362*0Sstevel@tonic-gate 	if (*v_stmp == 'y')
363*0Sstevel@tonic-gate 		(void) fprintf(ftable, "#ident\t\"yacc: %s %s\"\n",
364*0Sstevel@tonic-gate 		    (const char *)SGU_PKG, (const char *)SGU_REL);
365*0Sstevel@tonic-gate 	for (; t != MARK && t != ENDFILE; ) {
366*0Sstevel@tonic-gate 		int tok_in_line;
367*0Sstevel@tonic-gate 		switch (t) {
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate 		case L';':
370*0Sstevel@tonic-gate 			t = gettok();
371*0Sstevel@tonic-gate 			break;
372*0Sstevel@tonic-gate 
373*0Sstevel@tonic-gate 		case START:
374*0Sstevel@tonic-gate 			if ((t = gettok()) != IDENTIFIER) {
375*0Sstevel@tonic-gate 				error("bad %%start construction");
376*0Sstevel@tonic-gate 				}
377*0Sstevel@tonic-gate 			start = chfind(1, tokname);
378*0Sstevel@tonic-gate 			t = gettok();
379*0Sstevel@tonic-gate 			continue;
380*0Sstevel@tonic-gate 
381*0Sstevel@tonic-gate 		case TYPEDEF:
382*0Sstevel@tonic-gate 			tok_in_line = 0;
383*0Sstevel@tonic-gate 			if ((t = gettok()) != TYPENAME)
384*0Sstevel@tonic-gate /*
385*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
386*0Sstevel@tonic-gate  *	This message is passed to error() function.
387*0Sstevel@tonic-gate  *	Do not translate %%type.
388*0Sstevel@tonic-gate  */
389*0Sstevel@tonic-gate 				error(gettext(
390*0Sstevel@tonic-gate 				"bad syntax in %%type"));
391*0Sstevel@tonic-gate 			ty = numbval;
392*0Sstevel@tonic-gate 			for (;;) {
393*0Sstevel@tonic-gate 				t = gettok();
394*0Sstevel@tonic-gate 				switch (t) {
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate 				case IDENTIFIER:
397*0Sstevel@tonic-gate 			/*
398*0Sstevel@tonic-gate 			 * The following lines are idented to left.
399*0Sstevel@tonic-gate 			 */
400*0Sstevel@tonic-gate 			tok_in_line = 1;
401*0Sstevel@tonic-gate 			if ((t = chfind(1, tokname)) < NTBASE) {
402*0Sstevel@tonic-gate 				j = TYPE(toklev[t]);
403*0Sstevel@tonic-gate 				if (j != 0 && j != ty) {
404*0Sstevel@tonic-gate /*
405*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
406*0Sstevel@tonic-gate  *	This message is passed to error() function.
407*0Sstevel@tonic-gate  */
408*0Sstevel@tonic-gate 					error(gettext(
409*0Sstevel@tonic-gate 					"type redeclaration of token %ws"),
410*0Sstevel@tonic-gate 					tokset[t].name);
411*0Sstevel@tonic-gate 					}
412*0Sstevel@tonic-gate 				else
413*0Sstevel@tonic-gate 					SETTYPE(toklev[t], ty);
414*0Sstevel@tonic-gate 			} else {
415*0Sstevel@tonic-gate 				j = nontrst[t-NTBASE].tvalue;
416*0Sstevel@tonic-gate 				if (j != 0 && j != ty) {
417*0Sstevel@tonic-gate /*
418*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
419*0Sstevel@tonic-gate  *	This message is passed to error() function.
420*0Sstevel@tonic-gate  *	Check how nonterminal is translated in translated
421*0Sstevel@tonic-gate  *	yacc man page or yacc user's document.
422*0Sstevel@tonic-gate  */
423*0Sstevel@tonic-gate 					error(gettext(
424*0Sstevel@tonic-gate 				"type redeclaration of nonterminal %ws"),
425*0Sstevel@tonic-gate 						nontrst[t-NTBASE].name);
426*0Sstevel@tonic-gate 					}
427*0Sstevel@tonic-gate 				else
428*0Sstevel@tonic-gate 					nontrst[t-NTBASE].tvalue = ty;
429*0Sstevel@tonic-gate 				}
430*0Sstevel@tonic-gate 			/* FALLTHRU */
431*0Sstevel@tonic-gate 			/*
432*0Sstevel@tonic-gate 			 * End Indentation
433*0Sstevel@tonic-gate 			 */
434*0Sstevel@tonic-gate 				case L',':
435*0Sstevel@tonic-gate 					continue;
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate 				case L';':
438*0Sstevel@tonic-gate 					t = gettok();
439*0Sstevel@tonic-gate 					break;
440*0Sstevel@tonic-gate 				default:
441*0Sstevel@tonic-gate 					break;
442*0Sstevel@tonic-gate 					}
443*0Sstevel@tonic-gate 				if (!tok_in_line)
444*0Sstevel@tonic-gate /*
445*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
446*0Sstevel@tonic-gate  *	This message is passed to error() function.
447*0Sstevel@tonic-gate  */
448*0Sstevel@tonic-gate 					error(gettext(
449*0Sstevel@tonic-gate 					"missing tokens or illegal tokens"));
450*0Sstevel@tonic-gate 				break;
451*0Sstevel@tonic-gate 				}
452*0Sstevel@tonic-gate 			continue;
453*0Sstevel@tonic-gate 
454*0Sstevel@tonic-gate 		case UNION:
455*0Sstevel@tonic-gate 			/* copy the union declaration to the output */
456*0Sstevel@tonic-gate 			cpyunion();
457*0Sstevel@tonic-gate 			defunion = 1;
458*0Sstevel@tonic-gate 			t = gettok();
459*0Sstevel@tonic-gate 			continue;
460*0Sstevel@tonic-gate 
461*0Sstevel@tonic-gate 		case LEFT:
462*0Sstevel@tonic-gate 		case BINARY:
463*0Sstevel@tonic-gate 		case RIGHT:
464*0Sstevel@tonic-gate 			i++;
465*0Sstevel@tonic-gate 			/* FALLTHRU */
466*0Sstevel@tonic-gate 		case TERM:
467*0Sstevel@tonic-gate 			tok_in_line = 0;
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate 			/* nonzero means new prec. and assoc. */
470*0Sstevel@tonic-gate 			lev = (t-TERM) | 04;
471*0Sstevel@tonic-gate 			ty = 0;
472*0Sstevel@tonic-gate 
473*0Sstevel@tonic-gate 			/* get identifiers so defined */
474*0Sstevel@tonic-gate 
475*0Sstevel@tonic-gate 			t = gettok();
476*0Sstevel@tonic-gate 			if (t == TYPENAME) { /* there is a type defined */
477*0Sstevel@tonic-gate 				ty = numbval;
478*0Sstevel@tonic-gate 				t = gettok();
479*0Sstevel@tonic-gate 				}
480*0Sstevel@tonic-gate 
481*0Sstevel@tonic-gate 			for (;;) {
482*0Sstevel@tonic-gate 				switch (t) {
483*0Sstevel@tonic-gate 
484*0Sstevel@tonic-gate 				case L',':
485*0Sstevel@tonic-gate 					t = gettok();
486*0Sstevel@tonic-gate 					continue;
487*0Sstevel@tonic-gate 
488*0Sstevel@tonic-gate 				case L';':
489*0Sstevel@tonic-gate 					break;
490*0Sstevel@tonic-gate 
491*0Sstevel@tonic-gate 				case IDENTIFIER:
492*0Sstevel@tonic-gate 					tok_in_line = 1;
493*0Sstevel@tonic-gate 					j = chfind(0, tokname);
494*0Sstevel@tonic-gate 					if (j > NTBASE) {
495*0Sstevel@tonic-gate /*
496*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
497*0Sstevel@tonic-gate  *	This message is passed to error() function.
498*0Sstevel@tonic-gate  */
499*0Sstevel@tonic-gate 						error(gettext(
500*0Sstevel@tonic-gate 				"%ws is not a token."),
501*0Sstevel@tonic-gate 						tokname);
502*0Sstevel@tonic-gate 					}
503*0Sstevel@tonic-gate 					if (lev & ~04) {
504*0Sstevel@tonic-gate 						if (ASSOC(toklev[j]) & ~04)
505*0Sstevel@tonic-gate /*
506*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
507*0Sstevel@tonic-gate  *	This message is passed to error() function.
508*0Sstevel@tonic-gate  */
509*0Sstevel@tonic-gate 							error(gettext(
510*0Sstevel@tonic-gate 				"redeclaration of precedence of %ws"),
511*0Sstevel@tonic-gate 						tokname);
512*0Sstevel@tonic-gate 						SETASC(toklev[j], lev);
513*0Sstevel@tonic-gate 						SETPLEV(toklev[j], i);
514*0Sstevel@tonic-gate 					} else {
515*0Sstevel@tonic-gate 						if (ASSOC(toklev[j]))
516*0Sstevel@tonic-gate 						(void) warning(1, gettext(
517*0Sstevel@tonic-gate 				"redeclaration of precedence of %ws."),
518*0Sstevel@tonic-gate 							tokname);
519*0Sstevel@tonic-gate 						SETASC(toklev[j], lev);
520*0Sstevel@tonic-gate 						}
521*0Sstevel@tonic-gate 					if (ty) {
522*0Sstevel@tonic-gate 						if (TYPE(toklev[j]))
523*0Sstevel@tonic-gate 							error(gettext(
524*0Sstevel@tonic-gate /*
525*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
526*0Sstevel@tonic-gate  *	This message is passed to error() function.
527*0Sstevel@tonic-gate  */
528*0Sstevel@tonic-gate 						"redeclaration of type of %ws"),
529*0Sstevel@tonic-gate 							tokname);
530*0Sstevel@tonic-gate 						SETTYPE(toklev[j], ty);
531*0Sstevel@tonic-gate 						}
532*0Sstevel@tonic-gate 					if ((t = gettok()) == NUMBER) {
533*0Sstevel@tonic-gate 						tokset[j].value = numbval;
534*0Sstevel@tonic-gate 						if (j < ndefout && j > 2) {
535*0Sstevel@tonic-gate /*
536*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
537*0Sstevel@tonic-gate  *	This message is passed to error() function.
538*0Sstevel@tonic-gate  */
539*0Sstevel@tonic-gate 							error(gettext(
540*0Sstevel@tonic-gate 				"type number of %ws should be defined earlier"),
541*0Sstevel@tonic-gate 							tokset[j].name);
542*0Sstevel@tonic-gate 							}
543*0Sstevel@tonic-gate 						if (numbval >= -YYFLAG1) {
544*0Sstevel@tonic-gate /*
545*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
546*0Sstevel@tonic-gate  *	This message is passed to error() function.
547*0Sstevel@tonic-gate  */
548*0Sstevel@tonic-gate 							error(gettext(
549*0Sstevel@tonic-gate 				"token numbers must be less than %d"),
550*0Sstevel@tonic-gate 							-YYFLAG1);
551*0Sstevel@tonic-gate 							}
552*0Sstevel@tonic-gate 						t = gettok();
553*0Sstevel@tonic-gate 						}
554*0Sstevel@tonic-gate 					continue;
555*0Sstevel@tonic-gate 
556*0Sstevel@tonic-gate 					}
557*0Sstevel@tonic-gate 				if (!tok_in_line)
558*0Sstevel@tonic-gate /*
559*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
560*0Sstevel@tonic-gate  *	This message is passed to error() function.
561*0Sstevel@tonic-gate  */
562*0Sstevel@tonic-gate 					error(gettext(
563*0Sstevel@tonic-gate 					"missing tokens or illegal tokens"));
564*0Sstevel@tonic-gate 				break;
565*0Sstevel@tonic-gate 				}
566*0Sstevel@tonic-gate 			continue;
567*0Sstevel@tonic-gate 
568*0Sstevel@tonic-gate 		case LCURLY:
569*0Sstevel@tonic-gate 			defout();
570*0Sstevel@tonic-gate 			cpycode();
571*0Sstevel@tonic-gate 			t = gettok();
572*0Sstevel@tonic-gate 			continue;
573*0Sstevel@tonic-gate 
574*0Sstevel@tonic-gate 		default:
575*0Sstevel@tonic-gate 			error("syntax error");
576*0Sstevel@tonic-gate 
577*0Sstevel@tonic-gate 			}
578*0Sstevel@tonic-gate 
579*0Sstevel@tonic-gate 		}
580*0Sstevel@tonic-gate 
581*0Sstevel@tonic-gate 	if (t == ENDFILE) {
582*0Sstevel@tonic-gate /*
583*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
584*0Sstevel@tonic-gate  *	This message is passed to error() function.
585*0Sstevel@tonic-gate  *	Do not translate %%%%.
586*0Sstevel@tonic-gate  */
587*0Sstevel@tonic-gate 		error("unexpected EOF before %%%%");
588*0Sstevel@tonic-gate 		}
589*0Sstevel@tonic-gate 
590*0Sstevel@tonic-gate 	/* t is MARK */
591*0Sstevel@tonic-gate 
592*0Sstevel@tonic-gate 	defout();
593*0Sstevel@tonic-gate 	end_toks();	/* all tokens dumped - get ready for reductions */
594*0Sstevel@tonic-gate 
595*0Sstevel@tonic-gate 	(void) fprintf(ftable, "\n#include <inttypes.h>\n");
596*0Sstevel@tonic-gate 	(void) fprintf(ftable, "\n#ifdef __STDC__\n");
597*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#include <stdlib.h>\n");
598*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#include <string.h>\n");
599*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#define	YYCONST	const\n");
600*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#else\n");
601*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#include <malloc.h>\n");
602*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#include <memory.h>\n");
603*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#define	YYCONST\n");
604*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#endif\n");
605*0Sstevel@tonic-gate 	(void) fprintf(ftable, "\n#include <values.h>\n");
606*0Sstevel@tonic-gate 
607*0Sstevel@tonic-gate 	if (sym_prefix[0] != '\0')
608*0Sstevel@tonic-gate 		put_prefix_define(sym_prefix);
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate 	(void) fprintf(ftable,
611*0Sstevel@tonic-gate 	"\n#if defined(__cplusplus) || defined(__STDC__)\n");
612*0Sstevel@tonic-gate 	(void) fprintf(ftable,
613*0Sstevel@tonic-gate 	"\n#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
614*0Sstevel@tonic-gate 	(void) fprintf(ftable, "extern \"C\" {\n");
615*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#endif\n");
616*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#ifndef yyerror\n");
617*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#if defined(__cplusplus)\n");
618*0Sstevel@tonic-gate 	(void) fprintf(ftable, "	void yyerror(YYCONST char *);\n");
619*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#endif\n");
620*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#endif\n");
621*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#ifndef yylex\n");
622*0Sstevel@tonic-gate 	(void) fprintf(ftable, "	int yylex(void);\n");
623*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#endif\n");
624*0Sstevel@tonic-gate 	(void) fprintf(ftable, "	int yyparse(void);\n");
625*0Sstevel@tonic-gate 	(void) fprintf(ftable,
626*0Sstevel@tonic-gate 	"#if defined(__cplusplus) && defined(__EXTERN_C__)\n");
627*0Sstevel@tonic-gate 	(void) fprintf(ftable, "}\n");
628*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#endif\n");
629*0Sstevel@tonic-gate 	(void) fprintf(ftable, "\n#endif\n\n");
630*0Sstevel@tonic-gate 
631*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#define yyclearin yychar = -1\n");
632*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#define yyerrok yyerrflag = 0\n");
633*0Sstevel@tonic-gate 	(void) fprintf(ftable, "extern int yychar;\nextern int yyerrflag;\n");
634*0Sstevel@tonic-gate 	if (!(defunion || ntypes))
635*0Sstevel@tonic-gate 		(void) fprintf(ftable,
636*0Sstevel@tonic-gate 			"#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n");
637*0Sstevel@tonic-gate 	(void) fprintf(ftable, "YYSTYPE yylval;\n");
638*0Sstevel@tonic-gate 	(void) fprintf(ftable, "YYSTYPE yyval;\n");
639*0Sstevel@tonic-gate 	(void) fprintf(ftable, "typedef int yytabelem;\n");
640*0Sstevel@tonic-gate 	(void) fprintf(ftable,
641*0Sstevel@tonic-gate 		"#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n");
642*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#if YYMAXDEPTH > 0\n");
643*0Sstevel@tonic-gate 	(void) fprintf(ftable, "int yy_yys[YYMAXDEPTH], *yys = yy_yys;\n");
644*0Sstevel@tonic-gate 	(void) fprintf(ftable, "YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv;\n");
645*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#else	/* user does initial allocation */\n");
646*0Sstevel@tonic-gate 	(void) fprintf(ftable, "int *yys;\nYYSTYPE *yyv;\n#endif\n");
647*0Sstevel@tonic-gate 	(void) fprintf(ftable, "static int yymaxdepth = YYMAXDEPTH;\n");
648*0Sstevel@tonic-gate 
649*0Sstevel@tonic-gate 	prdptr[0] = mem;
650*0Sstevel@tonic-gate 	/* added production */
651*0Sstevel@tonic-gate 	*mem++ = NTBASE;
652*0Sstevel@tonic-gate 
653*0Sstevel@tonic-gate 	/* if start is 0, we will overwrite with the lhs of the first rule */
654*0Sstevel@tonic-gate 	*mem++ = start;
655*0Sstevel@tonic-gate 	*mem++ = 1;
656*0Sstevel@tonic-gate 	*mem++ = 0;
657*0Sstevel@tonic-gate 	prdptr[1] = mem;
658*0Sstevel@tonic-gate 
659*0Sstevel@tonic-gate 	while ((t = gettok()) == LCURLY)
660*0Sstevel@tonic-gate 		cpycode();
661*0Sstevel@tonic-gate 
662*0Sstevel@tonic-gate 	if (t != C_IDENTIFIER)
663*0Sstevel@tonic-gate 		error("bad syntax on first rule");
664*0Sstevel@tonic-gate 
665*0Sstevel@tonic-gate 	if (!start)
666*0Sstevel@tonic-gate 		prdptr[0][1] = chfind(1, tokname);
667*0Sstevel@tonic-gate 
668*0Sstevel@tonic-gate 	/* read rules */
669*0Sstevel@tonic-gate 
670*0Sstevel@tonic-gate 	while (t != MARK && t != ENDFILE) {
671*0Sstevel@tonic-gate 
672*0Sstevel@tonic-gate 		/* process a rule */
673*0Sstevel@tonic-gate 
674*0Sstevel@tonic-gate 		if (t == L'|') {
675*0Sstevel@tonic-gate 			rhsfill((wchar_t *)0); /* restart fill of rhs */
676*0Sstevel@tonic-gate 			*mem = *prdptr[nprod-1];
677*0Sstevel@tonic-gate 			if (++mem >= &tracemem[new_memsize])
678*0Sstevel@tonic-gate 				exp_mem(1);
679*0Sstevel@tonic-gate 		} else if (t == C_IDENTIFIER) {
680*0Sstevel@tonic-gate 			*mem = chfind(1, tokname);
681*0Sstevel@tonic-gate 			if (*mem < NTBASE)
682*0Sstevel@tonic-gate /*
683*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
684*0Sstevel@tonic-gate  *	This message is passed to error() function.
685*0Sstevel@tonic-gate  *	Check how nonterminal is translated.
686*0Sstevel@tonic-gate  */
687*0Sstevel@tonic-gate 				error(gettext(
688*0Sstevel@tonic-gate 				"illegal nonterminal in grammar rule"));
689*0Sstevel@tonic-gate 			if (++mem >= &tracemem[new_memsize])
690*0Sstevel@tonic-gate 				exp_mem(1);
691*0Sstevel@tonic-gate 			lhsfill(tokname);	/* new rule: restart strings */
692*0Sstevel@tonic-gate 		} else
693*0Sstevel@tonic-gate /*
694*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
695*0Sstevel@tonic-gate  *	This message is passed to error() function.
696*0Sstevel@tonic-gate  */
697*0Sstevel@tonic-gate 			error(gettext(
698*0Sstevel@tonic-gate 			"illegal rule: missing semicolon or | ?"));
699*0Sstevel@tonic-gate 
700*0Sstevel@tonic-gate 		/* read rule body */
701*0Sstevel@tonic-gate 
702*0Sstevel@tonic-gate 
703*0Sstevel@tonic-gate 		t = gettok();
704*0Sstevel@tonic-gate 	more_rule:
705*0Sstevel@tonic-gate 		while (t == IDENTIFIER) {
706*0Sstevel@tonic-gate 			*mem = chfind(1, tokname);
707*0Sstevel@tonic-gate 			if (*mem < NTBASE)
708*0Sstevel@tonic-gate 				levprd[nprod] = toklev[*mem]& ~04;
709*0Sstevel@tonic-gate 			if (++mem >= &tracemem[new_memsize])
710*0Sstevel@tonic-gate 				exp_mem(1);
711*0Sstevel@tonic-gate 			rhsfill(tokname);	/* add to rhs string */
712*0Sstevel@tonic-gate 			t = gettok();
713*0Sstevel@tonic-gate 			}
714*0Sstevel@tonic-gate 
715*0Sstevel@tonic-gate 		if (t == PREC) {
716*0Sstevel@tonic-gate 			if (gettok() != IDENTIFIER)
717*0Sstevel@tonic-gate /*
718*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
719*0Sstevel@tonic-gate  *	This message is passed to error() function.
720*0Sstevel@tonic-gate  *	Do not translate %%prec.
721*0Sstevel@tonic-gate  */
722*0Sstevel@tonic-gate 				error(gettext(
723*0Sstevel@tonic-gate 				"illegal %%prec syntax"));
724*0Sstevel@tonic-gate 			j = chfind(2, tokname);
725*0Sstevel@tonic-gate 			if (j >= NTBASE)
726*0Sstevel@tonic-gate /*
727*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
728*0Sstevel@tonic-gate  *	This message is passed to error() function.
729*0Sstevel@tonic-gate  *	Do not translate %%prec.
730*0Sstevel@tonic-gate  */
731*0Sstevel@tonic-gate 				error(gettext(
732*0Sstevel@tonic-gate 				"nonterminal %ws illegal after %%prec"),
733*0Sstevel@tonic-gate 				nontrst[j-NTBASE].name);
734*0Sstevel@tonic-gate 			levprd[nprod] = toklev[j] & ~04;
735*0Sstevel@tonic-gate 			t = gettok();
736*0Sstevel@tonic-gate 			}
737*0Sstevel@tonic-gate 
738*0Sstevel@tonic-gate 		if (t == L'=') {
739*0Sstevel@tonic-gate 			had_act[nprod] = 1;
740*0Sstevel@tonic-gate 			levprd[nprod] |= ACTFLAG;
741*0Sstevel@tonic-gate 			(void) fprintf(faction, "\ncase %d:", nprod);
742*0Sstevel@tonic-gate 			cpyact(mem-prdptr[nprod] - 1);
743*0Sstevel@tonic-gate 			(void) fprintf(faction, " break;");
744*0Sstevel@tonic-gate 			if ((t = gettok()) == IDENTIFIER) {
745*0Sstevel@tonic-gate 				/* action within rule... */
746*0Sstevel@tonic-gate 
747*0Sstevel@tonic-gate 				lrprnt();		/* dump lhs, rhs */
748*0Sstevel@tonic-gate 				(void) wsprintf(actname, "$$%d", nprod);
749*0Sstevel@tonic-gate 				/*
750*0Sstevel@tonic-gate 				 * make it nonterminal
751*0Sstevel@tonic-gate 				 */
752*0Sstevel@tonic-gate 				j = chfind(1, actname);
753*0Sstevel@tonic-gate 
754*0Sstevel@tonic-gate 				/*
755*0Sstevel@tonic-gate 				 * the current rule will become rule
756*0Sstevel@tonic-gate 				 * number nprod+1 move the contents down,
757*0Sstevel@tonic-gate 				 * and make room for the null
758*0Sstevel@tonic-gate 				 */
759*0Sstevel@tonic-gate 
760*0Sstevel@tonic-gate 				if (mem + 2 >= &tracemem[new_memsize])
761*0Sstevel@tonic-gate 					exp_mem(1);
762*0Sstevel@tonic-gate 				for (p = mem; p >= prdptr[nprod]; --p)
763*0Sstevel@tonic-gate 					p[2] = *p;
764*0Sstevel@tonic-gate 				mem += 2;
765*0Sstevel@tonic-gate 
766*0Sstevel@tonic-gate 				/* enter null production for action */
767*0Sstevel@tonic-gate 
768*0Sstevel@tonic-gate 				p = prdptr[nprod];
769*0Sstevel@tonic-gate 
770*0Sstevel@tonic-gate 				*p++ = j;
771*0Sstevel@tonic-gate 				*p++ = -nprod;
772*0Sstevel@tonic-gate 
773*0Sstevel@tonic-gate 				/* update the production information */
774*0Sstevel@tonic-gate 
775*0Sstevel@tonic-gate 				levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
776*0Sstevel@tonic-gate 				levprd[nprod] = ACTFLAG;
777*0Sstevel@tonic-gate 
778*0Sstevel@tonic-gate 				if (++nprod >= nprodsz)
779*0Sstevel@tonic-gate 					exp_prod();
780*0Sstevel@tonic-gate 				prdptr[nprod] = p;
781*0Sstevel@tonic-gate 
782*0Sstevel@tonic-gate 				/*
783*0Sstevel@tonic-gate 				 * make the action appear in
784*0Sstevel@tonic-gate 				 * the original rule
785*0Sstevel@tonic-gate 				 */
786*0Sstevel@tonic-gate 				*mem++ = j;
787*0Sstevel@tonic-gate 				if (mem >= &tracemem[new_memsize])
788*0Sstevel@tonic-gate 					exp_mem(1);
789*0Sstevel@tonic-gate 				/* get some more of the rule */
790*0Sstevel@tonic-gate 				goto more_rule;
791*0Sstevel@tonic-gate 			}
792*0Sstevel@tonic-gate 		}
793*0Sstevel@tonic-gate 		while (t == L';')
794*0Sstevel@tonic-gate 			t = gettok();
795*0Sstevel@tonic-gate 		*mem++ = -nprod;
796*0Sstevel@tonic-gate 		if (mem >= &tracemem[new_memsize])
797*0Sstevel@tonic-gate 			exp_mem(1);
798*0Sstevel@tonic-gate 
799*0Sstevel@tonic-gate 		/* check that default action is reasonable */
800*0Sstevel@tonic-gate 
801*0Sstevel@tonic-gate 		if (ntypes && !(levprd[nprod] & ACTFLAG) &&
802*0Sstevel@tonic-gate 				nontrst[*prdptr[nprod]-NTBASE].tvalue) {
803*0Sstevel@tonic-gate 			/* no explicit action, LHS has value */
804*0Sstevel@tonic-gate 			register tempty;
805*0Sstevel@tonic-gate 			tempty = prdptr[nprod][1];
806*0Sstevel@tonic-gate 			if (tempty < 0)
807*0Sstevel@tonic-gate /*
808*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
809*0Sstevel@tonic-gate  *	This message is passed to error() function.
810*0Sstevel@tonic-gate  *	LHS means Left Hand Side. It does not need to be translated.
811*0Sstevel@tonic-gate  */
812*0Sstevel@tonic-gate 				error(gettext(
813*0Sstevel@tonic-gate 				"must return a value, since LHS has a type"));
814*0Sstevel@tonic-gate 			else if (tempty >= NTBASE)
815*0Sstevel@tonic-gate 				tempty = nontrst[tempty-NTBASE].tvalue;
816*0Sstevel@tonic-gate 			else
817*0Sstevel@tonic-gate 				tempty = TYPE(toklev[tempty]);
818*0Sstevel@tonic-gate 			if (tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue) {
819*0Sstevel@tonic-gate /*
820*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
821*0Sstevel@tonic-gate  *	This message is passed to error() function.
822*0Sstevel@tonic-gate  *	Check how action is transltated in yacc man page or documents.
823*0Sstevel@tonic-gate  */
824*0Sstevel@tonic-gate 				error(gettext(
825*0Sstevel@tonic-gate 				"default action causes potential type clash"));
826*0Sstevel@tonic-gate 			}
827*0Sstevel@tonic-gate 		}
828*0Sstevel@tonic-gate 
829*0Sstevel@tonic-gate 		if (++nprod >= nprodsz)
830*0Sstevel@tonic-gate 			exp_prod();
831*0Sstevel@tonic-gate 		prdptr[nprod] = mem;
832*0Sstevel@tonic-gate 		levprd[nprod] = 0;
833*0Sstevel@tonic-gate 		}
834*0Sstevel@tonic-gate 	/* end of all rules */
835*0Sstevel@tonic-gate 
836*0Sstevel@tonic-gate 	end_debug();		/* finish fdebug file's input */
837*0Sstevel@tonic-gate 	finact();
838*0Sstevel@tonic-gate 	if (t == MARK) {
839*0Sstevel@tonic-gate 		if (gen_lines)
840*0Sstevel@tonic-gate 			(void) fprintf(ftable, "\n# line %d \"%s\"\n",
841*0Sstevel@tonic-gate 				lineno, infile);
842*0Sstevel@tonic-gate 		while ((c = getwc(finput)) != EOF)
843*0Sstevel@tonic-gate 			(void) putwc(c, ftable);
844*0Sstevel@tonic-gate 		}
845*0Sstevel@tonic-gate 	(void) fclose(finput);
846*0Sstevel@tonic-gate }
847*0Sstevel@tonic-gate 
848*0Sstevel@tonic-gate static void
849*0Sstevel@tonic-gate finact()
850*0Sstevel@tonic-gate {
851*0Sstevel@tonic-gate 	/* finish action routine */
852*0Sstevel@tonic-gate 	(void) fclose(faction);
853*0Sstevel@tonic-gate 	(void) fprintf(ftable, "# define YYERRCODE %d\n", tokset[2].value);
854*0Sstevel@tonic-gate }
855*0Sstevel@tonic-gate 
856*0Sstevel@tonic-gate static wchar_t *
857*0Sstevel@tonic-gate cstash(s)
858*0Sstevel@tonic-gate register wchar_t *s;
859*0Sstevel@tonic-gate {
860*0Sstevel@tonic-gate 	wchar_t *temp;
861*0Sstevel@tonic-gate 	static int used = 0;
862*0Sstevel@tonic-gate 	static int used_save = 0;
863*0Sstevel@tonic-gate 	static int exp_cname = CNAMSZ;
864*0Sstevel@tonic-gate 	int len = wslen(s);
865*0Sstevel@tonic-gate 
866*0Sstevel@tonic-gate 	/*
867*0Sstevel@tonic-gate 	 * 2/29/88 -
868*0Sstevel@tonic-gate 	 * Don't need to expand the table, just allocate new space.
869*0Sstevel@tonic-gate 	 */
870*0Sstevel@tonic-gate 	used_save = used;
871*0Sstevel@tonic-gate 	while (len >= (exp_cname - used_save)) {
872*0Sstevel@tonic-gate 		exp_cname += CNAMSZ;
873*0Sstevel@tonic-gate 		if (!used)
874*0Sstevel@tonic-gate 			free((char *)cnames);
875*0Sstevel@tonic-gate 		if ((cnames = (wchar_t *)
876*0Sstevel@tonic-gate 			malloc(sizeof (wchar_t)*exp_cname)) == NULL)
877*0Sstevel@tonic-gate /*
878*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
879*0Sstevel@tonic-gate  *	This message is passed to error() function.
880*0Sstevel@tonic-gate  *
881*0Sstevel@tonic-gate  *	You may just translate this as:
882*0Sstevel@tonic-gate  *	'Could not allocate internally used memory.'
883*0Sstevel@tonic-gate  */
884*0Sstevel@tonic-gate 			error(gettext(
885*0Sstevel@tonic-gate 			"cannot expand string dump"));
886*0Sstevel@tonic-gate 		cnamp = cnames;
887*0Sstevel@tonic-gate 		used = 0;
888*0Sstevel@tonic-gate 	}
889*0Sstevel@tonic-gate 
890*0Sstevel@tonic-gate 	temp = cnamp;
891*0Sstevel@tonic-gate 	do {
892*0Sstevel@tonic-gate 		*cnamp++ = *s;
893*0Sstevel@tonic-gate 	} while (*s++);
894*0Sstevel@tonic-gate 	used += cnamp - temp;
895*0Sstevel@tonic-gate 	return (temp);
896*0Sstevel@tonic-gate }
897*0Sstevel@tonic-gate 
898*0Sstevel@tonic-gate static int
899*0Sstevel@tonic-gate defin(t, s)
900*0Sstevel@tonic-gate register wchar_t *s;
901*0Sstevel@tonic-gate {
902*0Sstevel@tonic-gate 	/* define s to be a terminal if t=0 or a nonterminal if t=1 */
903*0Sstevel@tonic-gate 
904*0Sstevel@tonic-gate 	register val;
905*0Sstevel@tonic-gate 
906*0Sstevel@tonic-gate 	if (t) {
907*0Sstevel@tonic-gate 		if (++nnonter >= nnontersz)
908*0Sstevel@tonic-gate 			exp_nonterm();
909*0Sstevel@tonic-gate 		nontrst[nnonter].name = cstash(s);
910*0Sstevel@tonic-gate 		return (NTBASE + nnonter);
911*0Sstevel@tonic-gate 		}
912*0Sstevel@tonic-gate 	/* must be a token */
913*0Sstevel@tonic-gate 	if (++ntokens >= ntoksz)
914*0Sstevel@tonic-gate 		exp_ntok();
915*0Sstevel@tonic-gate 	tokset[ntokens].name = cstash(s);
916*0Sstevel@tonic-gate 
917*0Sstevel@tonic-gate 	/* establish value for token */
918*0Sstevel@tonic-gate 
919*0Sstevel@tonic-gate 	if (s[0] == L' ' && s[2] == 0) { /* single character literal */
920*0Sstevel@tonic-gate 		val = findchtok(s[1]);
921*0Sstevel@tonic-gate 	} else if (s[0] == L' ' && s[1] == L'\\') { /* escape sequence */
922*0Sstevel@tonic-gate 		if (s[3] == 0) { /* single character escape sequence */
923*0Sstevel@tonic-gate 			switch (s[2]) {
924*0Sstevel@tonic-gate 				/* character which is escaped */
925*0Sstevel@tonic-gate 			case L'a':
926*0Sstevel@tonic-gate 				(void) warning(1, gettext(
927*0Sstevel@tonic-gate /*
928*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
929*0Sstevel@tonic-gate  *	This message is passed to warning() function.
930*0Sstevel@tonic-gate  *	Do not trasnlate ANSI C, \\a.
931*0Sstevel@tonic-gate  */
932*0Sstevel@tonic-gate 		"\\a is ANSI C \"alert\" character"));
933*0Sstevel@tonic-gate #if __STDC__ - 1 == 0
934*0Sstevel@tonic-gate 				val = L'\a';
935*0Sstevel@tonic-gate 				break;
936*0Sstevel@tonic-gate #else
937*0Sstevel@tonic-gate 				val = L'\007';
938*0Sstevel@tonic-gate 				break;
939*0Sstevel@tonic-gate #endif
940*0Sstevel@tonic-gate 			case L'v': val = L'\v'; break;
941*0Sstevel@tonic-gate 			case L'n': val = L'\n'; break;
942*0Sstevel@tonic-gate 			case L'r': val = L'\r'; break;
943*0Sstevel@tonic-gate 			case L'b': val = L'\b'; break;
944*0Sstevel@tonic-gate 			case L't': val = L'\t'; break;
945*0Sstevel@tonic-gate 			case L'f': val = L'\f'; break;
946*0Sstevel@tonic-gate 			case L'\'': val = L'\''; break;
947*0Sstevel@tonic-gate 			case L'"': val = L'"'; break;
948*0Sstevel@tonic-gate 			case L'?': val = L'?'; break;
949*0Sstevel@tonic-gate 			case L'\\': val = L'\\'; break;
950*0Sstevel@tonic-gate /*
951*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
952*0Sstevel@tonic-gate  *	This message is passed to error() function.
953*0Sstevel@tonic-gate  */
954*0Sstevel@tonic-gate 			default: error(gettext(
955*0Sstevel@tonic-gate 				"invalid escape"));
956*0Sstevel@tonic-gate 			}
957*0Sstevel@tonic-gate 		} else if (s[2] <= L'7' && s[2] >= L'0') { /* \nnn sequence */
958*0Sstevel@tonic-gate 			int i = 3;
959*0Sstevel@tonic-gate 			val = s[2] - L'0';
960*0Sstevel@tonic-gate 			while (iswdigit(s[i]) && i <= 4) {
961*0Sstevel@tonic-gate 				if (s[i] >= L'0' && s[i] <= L'7')
962*0Sstevel@tonic-gate 					val = val * 8 + s[i] - L'0';
963*0Sstevel@tonic-gate 				else
964*0Sstevel@tonic-gate /*
965*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
966*0Sstevel@tonic-gate  *	This message is passed to error() function.
967*0Sstevel@tonic-gate  */
968*0Sstevel@tonic-gate 					error(gettext(
969*0Sstevel@tonic-gate 					"illegal octal number"));
970*0Sstevel@tonic-gate 				i++;
971*0Sstevel@tonic-gate 			}
972*0Sstevel@tonic-gate 			if (s[i] != 0)
973*0Sstevel@tonic-gate /*
974*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
975*0Sstevel@tonic-gate  *	This message is passed to error() function.
976*0Sstevel@tonic-gate  *	Do not translate \\nnn.
977*0Sstevel@tonic-gate  */
978*0Sstevel@tonic-gate 				error(gettext(
979*0Sstevel@tonic-gate 				"illegal \\nnn construction"));
980*0Sstevel@tonic-gate 			if (val > 255)
981*0Sstevel@tonic-gate /*
982*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
983*0Sstevel@tonic-gate  *	This message is passed to error() function.
984*0Sstevel@tonic-gate  *	Do not translate
985*0Sstevel@tonic-gate  *		\\nnn, \\xnnnnnnnn.
986*0Sstevel@tonic-gate  */
987*0Sstevel@tonic-gate 				error(
988*0Sstevel@tonic-gate "\\nnn exceed \\377; use \\xnnnnnnnn for wchar_t value of multibyte char");
989*0Sstevel@tonic-gate 			if (val == 0 && i >= 4)
990*0Sstevel@tonic-gate /*
991*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
992*0Sstevel@tonic-gate  *	This message is passed to error() function.
993*0Sstevel@tonic-gate  *	Do not translate \\000.
994*0Sstevel@tonic-gate  */
995*0Sstevel@tonic-gate 				error(gettext(
996*0Sstevel@tonic-gate 				"'\\000' is illegal"));
997*0Sstevel@tonic-gate 		} else if (s[2] == L'x') { /* hexadecimal \xnnn sequence */
998*0Sstevel@tonic-gate 			int i = 3;
999*0Sstevel@tonic-gate 			val = 0;
1000*0Sstevel@tonic-gate /*
1001*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1002*0Sstevel@tonic-gate  *	This message is passed to warning() function.
1003*0Sstevel@tonic-gate  *	Do not translate \\x, ANSI C.
1004*0Sstevel@tonic-gate  */
1005*0Sstevel@tonic-gate 			(void) warning(1, gettext(
1006*0Sstevel@tonic-gate 				"\\x is ANSI C hex escape"));
1007*0Sstevel@tonic-gate 			if (iswxdigit(s[i]))
1008*0Sstevel@tonic-gate 				while (iswxdigit(s[i])) {
1009*0Sstevel@tonic-gate 					int tmpval;
1010*0Sstevel@tonic-gate 					if (iswdigit(s[i]))
1011*0Sstevel@tonic-gate 						tmpval = s[i] - L'0';
1012*0Sstevel@tonic-gate 					else if (s[i] >= L'a')
1013*0Sstevel@tonic-gate 						tmpval = s[i] - L'a' + 10;
1014*0Sstevel@tonic-gate 					else
1015*0Sstevel@tonic-gate 						tmpval = s[i] - L'A' + 10;
1016*0Sstevel@tonic-gate 					val = 16 * val + tmpval;
1017*0Sstevel@tonic-gate 					i++;
1018*0Sstevel@tonic-gate 				}
1019*0Sstevel@tonic-gate 			else
1020*0Sstevel@tonic-gate 				error(gettext(
1021*0Sstevel@tonic-gate 				"illegal hexadecimal number"));
1022*0Sstevel@tonic-gate 			if (s[i] != 0)
1023*0Sstevel@tonic-gate /*
1024*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1025*0Sstevel@tonic-gate  *	This message is passed to error() function.
1026*0Sstevel@tonic-gate  *	Do not translate \\xnn.
1027*0Sstevel@tonic-gate  */
1028*0Sstevel@tonic-gate 				error(gettext(
1029*0Sstevel@tonic-gate 				"illegal \\xnn construction"));
1030*0Sstevel@tonic-gate #define	LWCHAR_MAX	0x7fffffff
1031*0Sstevel@tonic-gate 			if ((unsigned)val > LWCHAR_MAX)
1032*0Sstevel@tonic-gate /*
1033*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1034*0Sstevel@tonic-gate  *	This message is passed to error() function.
1035*0Sstevel@tonic-gate  *	Do not translate \\xnnnnnnnn and %#x.
1036*0Sstevel@tonic-gate  */
1037*0Sstevel@tonic-gate 			    error(gettext(
1038*0Sstevel@tonic-gate 			    " \\xnnnnnnnn exceed %#x"),
1039*0Sstevel@tonic-gate 			    LWCHAR_MAX);
1040*0Sstevel@tonic-gate 			if (val == 0)
1041*0Sstevel@tonic-gate /*
1042*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1043*0Sstevel@tonic-gate  *	This message is passed to error() function.
1044*0Sstevel@tonic-gate  *	Do not translate \\x00.
1045*0Sstevel@tonic-gate  */
1046*0Sstevel@tonic-gate 				error(gettext(
1047*0Sstevel@tonic-gate 				"'\\x00' is illegal"));
1048*0Sstevel@tonic-gate 			val = findchtok(val);
1049*0Sstevel@tonic-gate 		} else
1050*0Sstevel@tonic-gate 			error(gettext(
1051*0Sstevel@tonic-gate 			"invalid escape"));
1052*0Sstevel@tonic-gate 	} else {
1053*0Sstevel@tonic-gate 		val = extval++;
1054*0Sstevel@tonic-gate 	}
1055*0Sstevel@tonic-gate 	tokset[ntokens].value = val;
1056*0Sstevel@tonic-gate 	toklev[ntokens] = 0;
1057*0Sstevel@tonic-gate 	return (ntokens);
1058*0Sstevel@tonic-gate }
1059*0Sstevel@tonic-gate 
1060*0Sstevel@tonic-gate static void
1061*0Sstevel@tonic-gate defout()
1062*0Sstevel@tonic-gate {
1063*0Sstevel@tonic-gate 	/* write out the defines (at the end of the declaration section) */
1064*0Sstevel@tonic-gate 
1065*0Sstevel@tonic-gate 	register int i, c;
1066*0Sstevel@tonic-gate 	register wchar_t *cp;
1067*0Sstevel@tonic-gate 
1068*0Sstevel@tonic-gate 	for (i = ndefout; i <= ntokens; ++i) {
1069*0Sstevel@tonic-gate 
1070*0Sstevel@tonic-gate 		cp = tokset[i].name;
1071*0Sstevel@tonic-gate 		if (*cp == L' ')	/* literals */
1072*0Sstevel@tonic-gate 		{
1073*0Sstevel@tonic-gate 			(void) fprintf(fdebug, "\t\"%ws\",\t%d,\n",
1074*0Sstevel@tonic-gate 				tokset[i].name + 1, tokset[i].value);
1075*0Sstevel@tonic-gate 			continue;	/* was cp++ */
1076*0Sstevel@tonic-gate 		}
1077*0Sstevel@tonic-gate 
1078*0Sstevel@tonic-gate 		for (; (c = *cp) != 0; ++cp) {
1079*0Sstevel@tonic-gate 			if (iswlower(c) || iswupper(c) ||
1080*0Sstevel@tonic-gate 				iswdigit(c) || c == L'_') /* EMPTY */;
1081*0Sstevel@tonic-gate 			else
1082*0Sstevel@tonic-gate 				goto nodef;
1083*0Sstevel@tonic-gate 			}
1084*0Sstevel@tonic-gate 
1085*0Sstevel@tonic-gate 		(void) fprintf(fdebug,
1086*0Sstevel@tonic-gate 			"\t\"%ws\",\t%d,\n", tokset[i].name,
1087*0Sstevel@tonic-gate 			tokset[i].value);
1088*0Sstevel@tonic-gate 		(void) fprintf(ftable,
1089*0Sstevel@tonic-gate 			"# define %ws %d\n", tokset[i].name,
1090*0Sstevel@tonic-gate 			tokset[i].value);
1091*0Sstevel@tonic-gate 		if (fdefine != NULL)
1092*0Sstevel@tonic-gate 			(void) fprintf(fdefine,
1093*0Sstevel@tonic-gate 				"# define %ws %d\n",
1094*0Sstevel@tonic-gate 				tokset[i].name,
1095*0Sstevel@tonic-gate 				tokset[i].value);
1096*0Sstevel@tonic-gate 
1097*0Sstevel@tonic-gate 	nodef:;
1098*0Sstevel@tonic-gate 	}
1099*0Sstevel@tonic-gate 	ndefout = ntokens+1;
1100*0Sstevel@tonic-gate }
1101*0Sstevel@tonic-gate 
1102*0Sstevel@tonic-gate static
1103*0Sstevel@tonic-gate gettok()
1104*0Sstevel@tonic-gate {
1105*0Sstevel@tonic-gate 	register i, base;
1106*0Sstevel@tonic-gate 	static int peekline; /* number of '\n' seen in lookahead */
1107*0Sstevel@tonic-gate 	register c, match, reserve;
1108*0Sstevel@tonic-gate begin:
1109*0Sstevel@tonic-gate 	reserve = 0;
1110*0Sstevel@tonic-gate 	lineno += peekline;
1111*0Sstevel@tonic-gate 	peekline = 0;
1112*0Sstevel@tonic-gate 	c = getwc(finput);
1113*0Sstevel@tonic-gate 	/*
1114*0Sstevel@tonic-gate 	 * while (c == ' ' || c == '\n' || c == '\t' || c == '\f') {
1115*0Sstevel@tonic-gate 	 */
1116*0Sstevel@tonic-gate 	while (iswspace(c)) {
1117*0Sstevel@tonic-gate 		if (c == L'\n')
1118*0Sstevel@tonic-gate 			++lineno;
1119*0Sstevel@tonic-gate 		c = getwc(finput);
1120*0Sstevel@tonic-gate 	}
1121*0Sstevel@tonic-gate 	if (c == L'/') { /* skip comment */
1122*0Sstevel@tonic-gate 		lineno += skipcom();
1123*0Sstevel@tonic-gate 		goto begin;
1124*0Sstevel@tonic-gate 	}
1125*0Sstevel@tonic-gate 
1126*0Sstevel@tonic-gate 	switch (c) {
1127*0Sstevel@tonic-gate 
1128*0Sstevel@tonic-gate 	case EOF:
1129*0Sstevel@tonic-gate 		return (ENDFILE);
1130*0Sstevel@tonic-gate 	case L'{':
1131*0Sstevel@tonic-gate 		(void) ungetwc(c, finput);
1132*0Sstevel@tonic-gate 		return (L'=');  /* action ... */
1133*0Sstevel@tonic-gate 	case L'<':  /* get, and look up, a type name (union member name) */
1134*0Sstevel@tonic-gate 		i = 0;
1135*0Sstevel@tonic-gate 		while ((c = getwc(finput)) != L'>' &&
1136*0Sstevel@tonic-gate 				c != EOF && c != L'\n') {
1137*0Sstevel@tonic-gate 			tokname[i] = c;
1138*0Sstevel@tonic-gate 			if (++i >= toksize)
1139*0Sstevel@tonic-gate 				exp_tokname();
1140*0Sstevel@tonic-gate 			}
1141*0Sstevel@tonic-gate 		if (c != L'>')
1142*0Sstevel@tonic-gate 			error(gettext(
1143*0Sstevel@tonic-gate 			"unterminated < ... > clause"));
1144*0Sstevel@tonic-gate 		tokname[i] = 0;
1145*0Sstevel@tonic-gate 		if (i == 0)
1146*0Sstevel@tonic-gate 			error("missing type name in < ... > clause");
1147*0Sstevel@tonic-gate 		for (i = 1; i <= ntypes; ++i) {
1148*0Sstevel@tonic-gate 			if (!wscmp(typeset[i], tokname)) {
1149*0Sstevel@tonic-gate 				numbval = i;
1150*0Sstevel@tonic-gate 				return (TYPENAME);
1151*0Sstevel@tonic-gate 				}
1152*0Sstevel@tonic-gate 			}
1153*0Sstevel@tonic-gate 		typeset[numbval = ++ntypes] = cstash(tokname);
1154*0Sstevel@tonic-gate 		return (TYPENAME);
1155*0Sstevel@tonic-gate 
1156*0Sstevel@tonic-gate 	case L'"':
1157*0Sstevel@tonic-gate 	case L'\'':
1158*0Sstevel@tonic-gate 		match = c;
1159*0Sstevel@tonic-gate 		tokname[0] = L' ';
1160*0Sstevel@tonic-gate 		i = 1;
1161*0Sstevel@tonic-gate 		for (;;) {
1162*0Sstevel@tonic-gate 			c = getwc(finput);
1163*0Sstevel@tonic-gate 			if (c == L'\n' || c == EOF)
1164*0Sstevel@tonic-gate 				error(gettext(
1165*0Sstevel@tonic-gate 				"illegal or missing ' or \""));
1166*0Sstevel@tonic-gate 			if (c == L'\\') {
1167*0Sstevel@tonic-gate 				c = getwc(finput);
1168*0Sstevel@tonic-gate 				tokname[i] = L'\\';
1169*0Sstevel@tonic-gate 				if (++i >= toksize)
1170*0Sstevel@tonic-gate 					exp_tokname();
1171*0Sstevel@tonic-gate 			} else if (c == match) break;
1172*0Sstevel@tonic-gate 			tokname[i] = c;
1173*0Sstevel@tonic-gate 			if (++i >= toksize)
1174*0Sstevel@tonic-gate 				exp_tokname();
1175*0Sstevel@tonic-gate 			}
1176*0Sstevel@tonic-gate 		break;
1177*0Sstevel@tonic-gate 
1178*0Sstevel@tonic-gate 	case L'%':
1179*0Sstevel@tonic-gate 	case L'\\':
1180*0Sstevel@tonic-gate 
1181*0Sstevel@tonic-gate 		switch (c = getwc(finput)) {
1182*0Sstevel@tonic-gate 
1183*0Sstevel@tonic-gate 		case L'0':	return (TERM);
1184*0Sstevel@tonic-gate 		case L'<':	return (LEFT);
1185*0Sstevel@tonic-gate 		case L'2':	return (BINARY);
1186*0Sstevel@tonic-gate 		case L'>':	return (RIGHT);
1187*0Sstevel@tonic-gate 		case L'%':
1188*0Sstevel@tonic-gate 		case L'\\':	return (MARK);
1189*0Sstevel@tonic-gate 		case L'=':	return (PREC);
1190*0Sstevel@tonic-gate 		case L'{':	return (LCURLY);
1191*0Sstevel@tonic-gate 		default:	reserve = 1;
1192*0Sstevel@tonic-gate 			}
1193*0Sstevel@tonic-gate 
1194*0Sstevel@tonic-gate 	default:
1195*0Sstevel@tonic-gate 
1196*0Sstevel@tonic-gate 		if (iswdigit(c)) { /* number */
1197*0Sstevel@tonic-gate 			numbval = c - L'0';
1198*0Sstevel@tonic-gate 			base = (c == L'0') ? 8 : 10;
1199*0Sstevel@tonic-gate 			for (c = getwc(finput);
1200*0Sstevel@tonic-gate 					iswdigit(c);
1201*0Sstevel@tonic-gate 					c = getwc(finput)) {
1202*0Sstevel@tonic-gate 				numbval = numbval*base + c - L'0';
1203*0Sstevel@tonic-gate 				}
1204*0Sstevel@tonic-gate 			(void) ungetwc(c, finput);
1205*0Sstevel@tonic-gate 			return (NUMBER);
1206*0Sstevel@tonic-gate 		} else if (iswlower(c) || iswupper(c) ||
1207*0Sstevel@tonic-gate 				c == L'_' || c == L'.' ||
1208*0Sstevel@tonic-gate 				c == L'$') {
1209*0Sstevel@tonic-gate 			i = 0;
1210*0Sstevel@tonic-gate 			while (iswlower(c) || iswupper(c) ||
1211*0Sstevel@tonic-gate 					iswdigit(c) || c == L'_' ||
1212*0Sstevel@tonic-gate 					c == L'.' || c == L'$') {
1213*0Sstevel@tonic-gate 				tokname[i] = c;
1214*0Sstevel@tonic-gate 				if (reserve && iswupper(c))
1215*0Sstevel@tonic-gate 					tokname[i] = towlower(c);
1216*0Sstevel@tonic-gate 				if (++i >= toksize)
1217*0Sstevel@tonic-gate 					exp_tokname();
1218*0Sstevel@tonic-gate 				c = getwc(finput);
1219*0Sstevel@tonic-gate 				}
1220*0Sstevel@tonic-gate 			}
1221*0Sstevel@tonic-gate 		else
1222*0Sstevel@tonic-gate 			return (c);
1223*0Sstevel@tonic-gate 
1224*0Sstevel@tonic-gate 		(void) ungetwc(c, finput);
1225*0Sstevel@tonic-gate 		}
1226*0Sstevel@tonic-gate 
1227*0Sstevel@tonic-gate 	tokname[i] = 0;
1228*0Sstevel@tonic-gate 
1229*0Sstevel@tonic-gate 	if (reserve) { /* find a reserved word */
1230*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"term"))
1231*0Sstevel@tonic-gate 			return (TERM);
1232*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"token"))
1233*0Sstevel@tonic-gate 			return (TERM);
1234*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"left"))
1235*0Sstevel@tonic-gate 			return (LEFT);
1236*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"nonassoc"))
1237*0Sstevel@tonic-gate 			return (BINARY);
1238*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"binary"))
1239*0Sstevel@tonic-gate 			return (BINARY);
1240*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"right"))
1241*0Sstevel@tonic-gate 			return (RIGHT);
1242*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"prec"))
1243*0Sstevel@tonic-gate 			return (PREC);
1244*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"start"))
1245*0Sstevel@tonic-gate 			return (START);
1246*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"type"))
1247*0Sstevel@tonic-gate 			return (TYPEDEF);
1248*0Sstevel@tonic-gate 		if (!wscmp(tokname, L"union"))
1249*0Sstevel@tonic-gate 			return (UNION);
1250*0Sstevel@tonic-gate 		error(gettext(
1251*0Sstevel@tonic-gate 		"invalid escape, or illegal reserved word: %ws"),
1252*0Sstevel@tonic-gate 		tokname);
1253*0Sstevel@tonic-gate 		}
1254*0Sstevel@tonic-gate 
1255*0Sstevel@tonic-gate 	/* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
1256*0Sstevel@tonic-gate 
1257*0Sstevel@tonic-gate 	c = getwc(finput);
1258*0Sstevel@tonic-gate 	/*
1259*0Sstevel@tonic-gate 	 * while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/')
1260*0Sstevel@tonic-gate 	 * {
1261*0Sstevel@tonic-gate 	 */
1262*0Sstevel@tonic-gate 	while (iswspace(c) || c == L'/') {
1263*0Sstevel@tonic-gate 		if (c == L'\n') {
1264*0Sstevel@tonic-gate 			++peekline;
1265*0Sstevel@tonic-gate 		} else if (c == L'/') { /* look for comments */
1266*0Sstevel@tonic-gate 			peekline += skipcom();
1267*0Sstevel@tonic-gate 			}
1268*0Sstevel@tonic-gate 		c = getwc(finput);
1269*0Sstevel@tonic-gate 		}
1270*0Sstevel@tonic-gate 	if (c == L':')
1271*0Sstevel@tonic-gate 		return (C_IDENTIFIER);
1272*0Sstevel@tonic-gate 	(void) ungetwc(c, finput);
1273*0Sstevel@tonic-gate 	return (IDENTIFIER);
1274*0Sstevel@tonic-gate }
1275*0Sstevel@tonic-gate 
1276*0Sstevel@tonic-gate static
1277*0Sstevel@tonic-gate fdtype(t)
1278*0Sstevel@tonic-gate {
1279*0Sstevel@tonic-gate 	/* determine the type of a symbol */
1280*0Sstevel@tonic-gate 	register v;
1281*0Sstevel@tonic-gate 	if (t >= NTBASE)
1282*0Sstevel@tonic-gate 		v = nontrst[t-NTBASE].tvalue;
1283*0Sstevel@tonic-gate 	else
1284*0Sstevel@tonic-gate 		v = TYPE(toklev[t]);
1285*0Sstevel@tonic-gate 	if (v <= 0)
1286*0Sstevel@tonic-gate 		error(gettext(
1287*0Sstevel@tonic-gate 			"must specify type for %ws"),
1288*0Sstevel@tonic-gate 			(t >= NTBASE) ? nontrst[t-NTBASE].name:
1289*0Sstevel@tonic-gate 			tokset[t].name);
1290*0Sstevel@tonic-gate 	return (v);
1291*0Sstevel@tonic-gate }
1292*0Sstevel@tonic-gate 
1293*0Sstevel@tonic-gate static
1294*0Sstevel@tonic-gate chfind(t, s)
1295*0Sstevel@tonic-gate register wchar_t *s;
1296*0Sstevel@tonic-gate {
1297*0Sstevel@tonic-gate 	int i;
1298*0Sstevel@tonic-gate 
1299*0Sstevel@tonic-gate 	if (s[0] == ' ')
1300*0Sstevel@tonic-gate 		t = 0;
1301*0Sstevel@tonic-gate 	TLOOP(i) {
1302*0Sstevel@tonic-gate 		if (!wscmp(s, tokset[i].name)) {
1303*0Sstevel@tonic-gate 			return (i);
1304*0Sstevel@tonic-gate 		}
1305*0Sstevel@tonic-gate 	}
1306*0Sstevel@tonic-gate 	NTLOOP(i) {
1307*0Sstevel@tonic-gate 		if (!wscmp(s, nontrst[i].name)) {
1308*0Sstevel@tonic-gate 			return (i + NTBASE);
1309*0Sstevel@tonic-gate 		}
1310*0Sstevel@tonic-gate 	}
1311*0Sstevel@tonic-gate 	/* cannot find name */
1312*0Sstevel@tonic-gate 	if (t > 1)
1313*0Sstevel@tonic-gate 		error(gettext(
1314*0Sstevel@tonic-gate 		"%ws should have been defined earlier"), s);
1315*0Sstevel@tonic-gate 	return (defin(t, s));
1316*0Sstevel@tonic-gate }
1317*0Sstevel@tonic-gate 
1318*0Sstevel@tonic-gate static void
1319*0Sstevel@tonic-gate cpyunion()
1320*0Sstevel@tonic-gate {
1321*0Sstevel@tonic-gate 	/*
1322*0Sstevel@tonic-gate 	 * copy the union declaration to the output,
1323*0Sstevel@tonic-gate 	 * and the define file if present
1324*0Sstevel@tonic-gate 	 */
1325*0Sstevel@tonic-gate 	int level, c;
1326*0Sstevel@tonic-gate 	if (gen_lines)
1327*0Sstevel@tonic-gate 		(void) fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
1328*0Sstevel@tonic-gate 	(void) fprintf(ftable, "typedef union\n");
1329*0Sstevel@tonic-gate 	if (fdefine)
1330*0Sstevel@tonic-gate 		(void) fprintf(fdefine, "\ntypedef union\n");
1331*0Sstevel@tonic-gate 	(void) fprintf(ftable, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
1332*0Sstevel@tonic-gate 	if (fdefine)
1333*0Sstevel@tonic-gate 		(void) fprintf(fdefine,
1334*0Sstevel@tonic-gate 			"#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
1335*0Sstevel@tonic-gate 
1336*0Sstevel@tonic-gate 	level = 0;
1337*0Sstevel@tonic-gate 	for (;;) {
1338*0Sstevel@tonic-gate 		if ((c = getwc(finput)) == EOF)
1339*0Sstevel@tonic-gate /*
1340*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1341*0Sstevel@tonic-gate  *	This message is passed to error() function.
1342*0Sstevel@tonic-gate  *	EOF - End Of File.
1343*0Sstevel@tonic-gate  *	Do not translate %%union.
1344*0Sstevel@tonic-gate  */
1345*0Sstevel@tonic-gate 			error(gettext(
1346*0Sstevel@tonic-gate 			"EOF encountered while processing %%union"));
1347*0Sstevel@tonic-gate 		(void) putwc(c, ftable);
1348*0Sstevel@tonic-gate 		if (fdefine)
1349*0Sstevel@tonic-gate 			(void) putwc(c, fdefine);
1350*0Sstevel@tonic-gate 
1351*0Sstevel@tonic-gate 		switch (c) {
1352*0Sstevel@tonic-gate 
1353*0Sstevel@tonic-gate 		case L'\n':
1354*0Sstevel@tonic-gate 			++lineno;
1355*0Sstevel@tonic-gate 			break;
1356*0Sstevel@tonic-gate 
1357*0Sstevel@tonic-gate 		case L'{':
1358*0Sstevel@tonic-gate 			++level;
1359*0Sstevel@tonic-gate 			break;
1360*0Sstevel@tonic-gate 
1361*0Sstevel@tonic-gate 		case L'}':
1362*0Sstevel@tonic-gate 			--level;
1363*0Sstevel@tonic-gate 			if (level == 0) { /* we are finished copying */
1364*0Sstevel@tonic-gate 				(void) fprintf(ftable, " YYSTYPE;\n");
1365*0Sstevel@tonic-gate 				if (fdefine)
1366*0Sstevel@tonic-gate 					(void) fprintf(fdefine,
1367*0Sstevel@tonic-gate 					" YYSTYPE;\nextern YYSTYPE yylval;\n");
1368*0Sstevel@tonic-gate 				return;
1369*0Sstevel@tonic-gate 				}
1370*0Sstevel@tonic-gate 			}
1371*0Sstevel@tonic-gate 		}
1372*0Sstevel@tonic-gate }
1373*0Sstevel@tonic-gate 
1374*0Sstevel@tonic-gate static void
1375*0Sstevel@tonic-gate cpycode()
1376*0Sstevel@tonic-gate {
1377*0Sstevel@tonic-gate 	/* copies code between \{ and \} */
1378*0Sstevel@tonic-gate 
1379*0Sstevel@tonic-gate 	int c;
1380*0Sstevel@tonic-gate 	c = getwc(finput);
1381*0Sstevel@tonic-gate 	if (c == L'\n') {
1382*0Sstevel@tonic-gate 		c = getwc(finput);
1383*0Sstevel@tonic-gate 		lineno++;
1384*0Sstevel@tonic-gate 		}
1385*0Sstevel@tonic-gate 	if (gen_lines)
1386*0Sstevel@tonic-gate 		(void) fprintf(ftable, "\n# line %d \"%s\"\n", lineno, infile);
1387*0Sstevel@tonic-gate 	while (c != EOF) {
1388*0Sstevel@tonic-gate 		if (c == L'\\') {
1389*0Sstevel@tonic-gate 			if ((c = getwc(finput)) == L'}')
1390*0Sstevel@tonic-gate 				return;
1391*0Sstevel@tonic-gate 			else
1392*0Sstevel@tonic-gate 				(void) putwc(L'\\', ftable);
1393*0Sstevel@tonic-gate 		} else if (c == L'%') {
1394*0Sstevel@tonic-gate 			if ((c = getwc(finput)) == L'}')
1395*0Sstevel@tonic-gate 				return;
1396*0Sstevel@tonic-gate 			else
1397*0Sstevel@tonic-gate 				(void) putwc(L'%', ftable);
1398*0Sstevel@tonic-gate 		}
1399*0Sstevel@tonic-gate 		(void) putwc(c, ftable);
1400*0Sstevel@tonic-gate 		if (c == L'\n')
1401*0Sstevel@tonic-gate 			++lineno;
1402*0Sstevel@tonic-gate 		c = getwc(finput);
1403*0Sstevel@tonic-gate 		}
1404*0Sstevel@tonic-gate /*
1405*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1406*0Sstevel@tonic-gate  *	This message is passed to error() function.
1407*0Sstevel@tonic-gate  *	Do not translate %%}.
1408*0Sstevel@tonic-gate  */
1409*0Sstevel@tonic-gate 	error(gettext(
1410*0Sstevel@tonic-gate 	"eof before %%}"));
1411*0Sstevel@tonic-gate }
1412*0Sstevel@tonic-gate 
1413*0Sstevel@tonic-gate static
1414*0Sstevel@tonic-gate skipcom()
1415*0Sstevel@tonic-gate {
1416*0Sstevel@tonic-gate 	/* skip over comments */
1417*0Sstevel@tonic-gate 	register c, i = 0;  /* i is the number of lines skipped */
1418*0Sstevel@tonic-gate 
1419*0Sstevel@tonic-gate 	/* skipcom is called after reading a / */
1420*0Sstevel@tonic-gate 
1421*0Sstevel@tonic-gate 	if (getwc(finput) != L'*')
1422*0Sstevel@tonic-gate 		error(gettext(
1423*0Sstevel@tonic-gate 		"illegal comment"));
1424*0Sstevel@tonic-gate 	c = getwc(finput);
1425*0Sstevel@tonic-gate 	while (c != EOF) {
1426*0Sstevel@tonic-gate 		while (c == L'*') {
1427*0Sstevel@tonic-gate 			if ((c = getwc(finput)) == L'/')
1428*0Sstevel@tonic-gate 				return (i);
1429*0Sstevel@tonic-gate 			}
1430*0Sstevel@tonic-gate 		if (c == L'\n')
1431*0Sstevel@tonic-gate 			++i;
1432*0Sstevel@tonic-gate 		c = getwc(finput);
1433*0Sstevel@tonic-gate 		}
1434*0Sstevel@tonic-gate /*
1435*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1436*0Sstevel@tonic-gate  *	This message is passed to error() function.
1437*0Sstevel@tonic-gate  *	EOF -- End Of File.
1438*0Sstevel@tonic-gate  */
1439*0Sstevel@tonic-gate 	error(gettext(
1440*0Sstevel@tonic-gate 	"EOF inside comment"));
1441*0Sstevel@tonic-gate 	/* NOTREACHED */
1442*0Sstevel@tonic-gate }
1443*0Sstevel@tonic-gate 
1444*0Sstevel@tonic-gate static void
1445*0Sstevel@tonic-gate cpyact(offset)
1446*0Sstevel@tonic-gate {
1447*0Sstevel@tonic-gate 	/* copy C action to the next ; or closing } */
1448*0Sstevel@tonic-gate 	int brac, c, match, i, t, j, s, tok, argument, m;
1449*0Sstevel@tonic-gate 	wchar_t id_name[NAMESIZE+1];
1450*0Sstevel@tonic-gate 	int id_idx = 0;
1451*0Sstevel@tonic-gate 
1452*0Sstevel@tonic-gate 	if (gen_lines) {
1453*0Sstevel@tonic-gate 		(void) fprintf(faction, "\n# line %d \"%s\"\n", lineno, infile);
1454*0Sstevel@tonic-gate 		act_lines++;
1455*0Sstevel@tonic-gate 	}
1456*0Sstevel@tonic-gate 	brac = 0;
1457*0Sstevel@tonic-gate 	id_name[0] = 0;
1458*0Sstevel@tonic-gate loop:
1459*0Sstevel@tonic-gate 	c = getwc(finput);
1460*0Sstevel@tonic-gate swt:
1461*0Sstevel@tonic-gate 	switch (c) {
1462*0Sstevel@tonic-gate 	case L';':
1463*0Sstevel@tonic-gate 		if (brac == 0) {
1464*0Sstevel@tonic-gate 			(void) putwc(c, faction);
1465*0Sstevel@tonic-gate 			return;
1466*0Sstevel@tonic-gate 		}
1467*0Sstevel@tonic-gate 		goto lcopy;
1468*0Sstevel@tonic-gate 	case L'{':
1469*0Sstevel@tonic-gate 		brac++;
1470*0Sstevel@tonic-gate 		goto lcopy;
1471*0Sstevel@tonic-gate 	case L'$':
1472*0Sstevel@tonic-gate 		s = 1;
1473*0Sstevel@tonic-gate 		tok = -1;
1474*0Sstevel@tonic-gate 		argument = 1;
1475*0Sstevel@tonic-gate 		while ((c = getwc(finput)) == L' ' || c == L'\t') /* EMPTY */;
1476*0Sstevel@tonic-gate 		if (c == L'<') { /* type description */
1477*0Sstevel@tonic-gate 			(void) ungetwc(c, finput);
1478*0Sstevel@tonic-gate 			if (gettok() != TYPENAME)
1479*0Sstevel@tonic-gate /*
1480*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1481*0Sstevel@tonic-gate  *	This message is passed to error() function.
1482*0Sstevel@tonic-gate  *	Do not translate $<ident>
1483*0Sstevel@tonic-gate  */
1484*0Sstevel@tonic-gate 				error(gettext(
1485*0Sstevel@tonic-gate 				"bad syntax on $<ident> clause"));
1486*0Sstevel@tonic-gate 			tok = numbval;
1487*0Sstevel@tonic-gate 			c = getwc(finput);
1488*0Sstevel@tonic-gate 		}
1489*0Sstevel@tonic-gate 		if (c == L'$') {
1490*0Sstevel@tonic-gate 			(void) fprintf(faction, "yyval");
1491*0Sstevel@tonic-gate 			if (ntypes) { /* put out the proper tag... */
1492*0Sstevel@tonic-gate 				if (tok < 0)
1493*0Sstevel@tonic-gate 					tok = fdtype(*prdptr[nprod]);
1494*0Sstevel@tonic-gate 				(void) fprintf(faction,
1495*0Sstevel@tonic-gate 					".%ws", typeset[tok]);
1496*0Sstevel@tonic-gate 			}
1497*0Sstevel@tonic-gate 			goto loop;
1498*0Sstevel@tonic-gate 		}
1499*0Sstevel@tonic-gate 		if (iswalpha(c)) {
1500*0Sstevel@tonic-gate 			int same = 0;
1501*0Sstevel@tonic-gate 			int id_sw = 0;
1502*0Sstevel@tonic-gate 			(void) ungetwc(c, finput);
1503*0Sstevel@tonic-gate 			if (gettok() != IDENTIFIER)
1504*0Sstevel@tonic-gate /*
1505*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1506*0Sstevel@tonic-gate  *	This message is passed to error() function.
1507*0Sstevel@tonic-gate  *	Check how action is translated in yacc man page/document.
1508*0Sstevel@tonic-gate  */
1509*0Sstevel@tonic-gate 				error(gettext(
1510*0Sstevel@tonic-gate 				"bad action format"));
1511*0Sstevel@tonic-gate 			/*
1512*0Sstevel@tonic-gate 			 * Save the number of non-terminal
1513*0Sstevel@tonic-gate 			 */
1514*0Sstevel@tonic-gate 			id_sw = nnonter;
1515*0Sstevel@tonic-gate 			t = chfind(1, tokname);
1516*0Sstevel@tonic-gate 			/*
1517*0Sstevel@tonic-gate 			 * Check if the identifier is added as a non-terminal
1518*0Sstevel@tonic-gate 			 */
1519*0Sstevel@tonic-gate 			if (id_sw != nnonter)
1520*0Sstevel@tonic-gate 				id_sw = 1;
1521*0Sstevel@tonic-gate 			else
1522*0Sstevel@tonic-gate 				id_sw = 0;
1523*0Sstevel@tonic-gate 			while ((c = getwc(finput)) == L' ' ||
1524*0Sstevel@tonic-gate 				c == L'\t') /* EMPTY */;
1525*0Sstevel@tonic-gate 			if (c == L'#') {
1526*0Sstevel@tonic-gate 				while ((c = getwc(finput)) == L' ' ||
1527*0Sstevel@tonic-gate 					c == L'\t') /* EMPTY */;
1528*0Sstevel@tonic-gate 				if (iswdigit(c)) {
1529*0Sstevel@tonic-gate 					m = 0;
1530*0Sstevel@tonic-gate 					while (iswdigit(c)) {
1531*0Sstevel@tonic-gate 						m = m*10+c-L'0';
1532*0Sstevel@tonic-gate 						c = getwc(finput);
1533*0Sstevel@tonic-gate 					}
1534*0Sstevel@tonic-gate 					argument = m;
1535*0Sstevel@tonic-gate 				} else
1536*0Sstevel@tonic-gate 					error(gettext(
1537*0Sstevel@tonic-gate 					"illegal character \"#\""));
1538*0Sstevel@tonic-gate 			}
1539*0Sstevel@tonic-gate 			if (argument < 1)
1540*0Sstevel@tonic-gate /*
1541*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1542*0Sstevel@tonic-gate  *	This message is passed to error() function.
1543*0Sstevel@tonic-gate  *	Check how action is translated in yacc man page/document.
1544*0Sstevel@tonic-gate  */
1545*0Sstevel@tonic-gate 				error(gettext(
1546*0Sstevel@tonic-gate 				"illegal action argument no."));
1547*0Sstevel@tonic-gate 			for (i = 1; i <= offset; ++i)
1548*0Sstevel@tonic-gate 				if (prdptr[nprod][i] == t)
1549*0Sstevel@tonic-gate 					if (++same == argument) {
1550*0Sstevel@tonic-gate 						(void) fprintf(faction,
1551*0Sstevel@tonic-gate 							"yypvt[-%d]", offset-i);
1552*0Sstevel@tonic-gate 						if (ntypes) {
1553*0Sstevel@tonic-gate 							if (tok < 0)
1554*0Sstevel@tonic-gate 								tok =
1555*0Sstevel@tonic-gate 								/* CSTYLED */
1556*0Sstevel@tonic-gate 								fdtype(prdptr[nprod][i]);
1557*0Sstevel@tonic-gate 							(void) fprintf(faction,
1558*0Sstevel@tonic-gate 							".%ws", typeset[tok]);
1559*0Sstevel@tonic-gate 						}
1560*0Sstevel@tonic-gate 						goto swt;
1561*0Sstevel@tonic-gate 					}
1562*0Sstevel@tonic-gate 			/*
1563*0Sstevel@tonic-gate 			 * This used to be handled as error.
1564*0Sstevel@tonic-gate 			 * Treat this as a valid C statement.
1565*0Sstevel@tonic-gate 			 * (Likely id with $ in.)
1566*0Sstevel@tonic-gate 			 * If non-terminal is added, remove it from the list.
1567*0Sstevel@tonic-gate 			 */
1568*0Sstevel@tonic-gate 			fprintf(faction, "$%ws", tokname);
1569*0Sstevel@tonic-gate /*
1570*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1571*0Sstevel@tonic-gate  *	This message is passed to warning() function.
1572*0Sstevel@tonic-gate  *	Do not translate Ansi C.
1573*0Sstevel@tonic-gate  */
1574*0Sstevel@tonic-gate 			warning(1, gettext(
1575*0Sstevel@tonic-gate 	"Illegal character '$' in Ansi C symbol: %ws$%ws."),
1576*0Sstevel@tonic-gate 				id_name, tokname);
1577*0Sstevel@tonic-gate 
1578*0Sstevel@tonic-gate 			if (id_sw == 1)
1579*0Sstevel@tonic-gate 				--nnonter;
1580*0Sstevel@tonic-gate 			goto swt;
1581*0Sstevel@tonic-gate 		}
1582*0Sstevel@tonic-gate 		if (c == '-') {
1583*0Sstevel@tonic-gate 			s = -s;
1584*0Sstevel@tonic-gate 			c = getwc(finput);
1585*0Sstevel@tonic-gate 		}
1586*0Sstevel@tonic-gate 		if (iswdigit(c)) {
1587*0Sstevel@tonic-gate 			j = 0;
1588*0Sstevel@tonic-gate 			while (iswdigit(c)) {
1589*0Sstevel@tonic-gate 				j = j*10 + c - L'0';
1590*0Sstevel@tonic-gate 				c = getwc(finput);
1591*0Sstevel@tonic-gate 			}
1592*0Sstevel@tonic-gate 			j = j*s - offset;
1593*0Sstevel@tonic-gate 			if (j > 0) {
1594*0Sstevel@tonic-gate /*
1595*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1596*0Sstevel@tonic-gate  *	This message is passed to error() function.
1597*0Sstevel@tonic-gate  *	Do not translate $%d.
1598*0Sstevel@tonic-gate  */
1599*0Sstevel@tonic-gate 				error(gettext(
1600*0Sstevel@tonic-gate 				"Illegal use of $%d"),
1601*0Sstevel@tonic-gate 				j + offset);
1602*0Sstevel@tonic-gate 			}
1603*0Sstevel@tonic-gate 			(void) fprintf(faction, "yypvt[-%d]", -j);
1604*0Sstevel@tonic-gate 			if (ntypes) { /* put out the proper tag */
1605*0Sstevel@tonic-gate 				if (j + offset <= 0 && tok < 0)
1606*0Sstevel@tonic-gate /*
1607*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1608*0Sstevel@tonic-gate  *	This message is passed to error() function.
1609*0Sstevel@tonic-gate  *	Do not translate $%d.
1610*0Sstevel@tonic-gate  */
1611*0Sstevel@tonic-gate 					error(gettext(
1612*0Sstevel@tonic-gate 					"must specify type of $%d"),
1613*0Sstevel@tonic-gate 					j + offset);
1614*0Sstevel@tonic-gate 				if (tok < 0)
1615*0Sstevel@tonic-gate 					tok = fdtype(prdptr[nprod][j+offset]);
1616*0Sstevel@tonic-gate 				(void) fprintf(faction,
1617*0Sstevel@tonic-gate 					".%ws", typeset[tok]);
1618*0Sstevel@tonic-gate 			}
1619*0Sstevel@tonic-gate 			goto swt;
1620*0Sstevel@tonic-gate 		}
1621*0Sstevel@tonic-gate 		(void) putwc(L'$', faction);
1622*0Sstevel@tonic-gate 		if (s < 0)
1623*0Sstevel@tonic-gate 			(void) putwc(L'-', faction);
1624*0Sstevel@tonic-gate 		goto swt;
1625*0Sstevel@tonic-gate 	case L'}':
1626*0Sstevel@tonic-gate 		if (--brac)
1627*0Sstevel@tonic-gate 			goto lcopy;
1628*0Sstevel@tonic-gate 		(void) putwc(c, faction);
1629*0Sstevel@tonic-gate 		return;
1630*0Sstevel@tonic-gate 	case L'/':	/* look for comments */
1631*0Sstevel@tonic-gate 		(void) putwc(c, faction);
1632*0Sstevel@tonic-gate 		c = getwc(finput);
1633*0Sstevel@tonic-gate 		if (c != L'*')
1634*0Sstevel@tonic-gate 			goto swt;
1635*0Sstevel@tonic-gate 		/* it really is a comment */
1636*0Sstevel@tonic-gate 		(void) putwc(c, faction);
1637*0Sstevel@tonic-gate 		c = getwc(finput);
1638*0Sstevel@tonic-gate 		while (c != EOF) {
1639*0Sstevel@tonic-gate 			while (c == L'*') {
1640*0Sstevel@tonic-gate 				(void) putwc(c, faction);
1641*0Sstevel@tonic-gate 				if ((c = getwc(finput)) == L'/')
1642*0Sstevel@tonic-gate 					goto lcopy;
1643*0Sstevel@tonic-gate 			}
1644*0Sstevel@tonic-gate 			(void) putwc(c, faction);
1645*0Sstevel@tonic-gate 			if (c == L'\n')
1646*0Sstevel@tonic-gate 				++lineno;
1647*0Sstevel@tonic-gate 			c = getwc(finput);
1648*0Sstevel@tonic-gate 		}
1649*0Sstevel@tonic-gate 		error("EOF inside comment");
1650*0Sstevel@tonic-gate 		/* FALLTHRU */
1651*0Sstevel@tonic-gate 	case L'\'':	/* character constant */
1652*0Sstevel@tonic-gate 	case L'"':	/* character string */
1653*0Sstevel@tonic-gate 		match = c;
1654*0Sstevel@tonic-gate 		(void) putwc(c, faction);
1655*0Sstevel@tonic-gate 		while ((c = getwc(finput)) != EOF) {
1656*0Sstevel@tonic-gate 			if (c == L'\\') {
1657*0Sstevel@tonic-gate 				(void) putwc(c, faction);
1658*0Sstevel@tonic-gate 				c = getwc(finput);
1659*0Sstevel@tonic-gate 				if (c == L'\n')
1660*0Sstevel@tonic-gate 					++lineno;
1661*0Sstevel@tonic-gate 			} else if (c == match)
1662*0Sstevel@tonic-gate 				goto lcopy;
1663*0Sstevel@tonic-gate 			else if (c == L'\n')
1664*0Sstevel@tonic-gate /*
1665*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1666*0Sstevel@tonic-gate  *	This message is passed to error() function.
1667*0Sstevel@tonic-gate  *	This error message is issued when
1668*0Sstevel@tonic-gate  *	quoted string has multiple lines.
1669*0Sstevel@tonic-gate  */
1670*0Sstevel@tonic-gate 				error(gettext(
1671*0Sstevel@tonic-gate 				"newline in string or char. const."));
1672*0Sstevel@tonic-gate 			(void) putwc(c, faction);
1673*0Sstevel@tonic-gate 		}
1674*0Sstevel@tonic-gate 		error(gettext(
1675*0Sstevel@tonic-gate 		"EOF in string or character constant"));
1676*0Sstevel@tonic-gate 		/* FALLTHRU */
1677*0Sstevel@tonic-gate 	case EOF:
1678*0Sstevel@tonic-gate /*
1679*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1680*0Sstevel@tonic-gate  *	This message is passed to error() function.
1681*0Sstevel@tonic-gate  *	Check how 'action' is translated in yacc mapage/document.
1682*0Sstevel@tonic-gate  */
1683*0Sstevel@tonic-gate 		error(gettext(
1684*0Sstevel@tonic-gate 		"action does not terminate"));
1685*0Sstevel@tonic-gate 		/* FALLTHRU */
1686*0Sstevel@tonic-gate 	case L'\n':
1687*0Sstevel@tonic-gate 		++lineno;
1688*0Sstevel@tonic-gate 		goto lcopy;
1689*0Sstevel@tonic-gate 	}
1690*0Sstevel@tonic-gate lcopy:
1691*0Sstevel@tonic-gate 	(void) putwc(c, faction);
1692*0Sstevel@tonic-gate 	/*
1693*0Sstevel@tonic-gate 	 * Save the possible identifier name.
1694*0Sstevel@tonic-gate 	 * Used to print out a warning message.
1695*0Sstevel@tonic-gate 	 */
1696*0Sstevel@tonic-gate 	if (id_idx >= NAMESIZE) {
1697*0Sstevel@tonic-gate 		/*
1698*0Sstevel@tonic-gate 		 * Error. Silently ignore.
1699*0Sstevel@tonic-gate 		 */
1700*0Sstevel@tonic-gate 		;
1701*0Sstevel@tonic-gate 	}
1702*0Sstevel@tonic-gate 	/*
1703*0Sstevel@tonic-gate 	 * If c has a possibility to be a
1704*0Sstevel@tonic-gate 	 * part of identifier, save it.
1705*0Sstevel@tonic-gate 	 */
1706*0Sstevel@tonic-gate 	else if (iswalnum(c) || c == L'_') {
1707*0Sstevel@tonic-gate 		id_name[id_idx++] = c;
1708*0Sstevel@tonic-gate 		id_name[id_idx] = 0;
1709*0Sstevel@tonic-gate 	} else {
1710*0Sstevel@tonic-gate 		id_idx = 0;
1711*0Sstevel@tonic-gate 		id_name[id_idx] = 0;
1712*0Sstevel@tonic-gate 	}
1713*0Sstevel@tonic-gate 	goto loop;
1714*0Sstevel@tonic-gate }
1715*0Sstevel@tonic-gate 
1716*0Sstevel@tonic-gate static void
1717*0Sstevel@tonic-gate lhsfill(s)	/* new rule, dump old (if exists), restart strings */
1718*0Sstevel@tonic-gate wchar_t *s;
1719*0Sstevel@tonic-gate {
1720*0Sstevel@tonic-gate 	static int lhs_len = LHS_TEXT_LEN;
1721*0Sstevel@tonic-gate 	int s_lhs = wslen(s);
1722*0Sstevel@tonic-gate 	if (s_lhs >= lhs_len) {
1723*0Sstevel@tonic-gate 		lhs_len = s_lhs + 2;
1724*0Sstevel@tonic-gate 		lhstext = (wchar_t *)
1725*0Sstevel@tonic-gate 			realloc((char *)lhstext, sizeof (wchar_t)*lhs_len);
1726*0Sstevel@tonic-gate 		if (lhstext == NULL)
1727*0Sstevel@tonic-gate /*
1728*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1729*0Sstevel@tonic-gate  *	This message is passed to error() function.
1730*0Sstevel@tonic-gate  *	LHS -- Left Hand Side.
1731*0Sstevel@tonic-gate  */
1732*0Sstevel@tonic-gate 			error(gettext(
1733*0Sstevel@tonic-gate 			"couldn't expanded LHS length"));
1734*0Sstevel@tonic-gate 	}
1735*0Sstevel@tonic-gate 	rhsfill((wchar_t *)0);
1736*0Sstevel@tonic-gate 	(void) wscpy(lhstext, s); /* don't worry about too long of a name */
1737*0Sstevel@tonic-gate }
1738*0Sstevel@tonic-gate 
1739*0Sstevel@tonic-gate static void
1740*0Sstevel@tonic-gate rhsfill(s)
1741*0Sstevel@tonic-gate wchar_t *s;	/* either name or 0 */
1742*0Sstevel@tonic-gate {
1743*0Sstevel@tonic-gate 	static wchar_t *loc;	/* next free location in rhstext */
1744*0Sstevel@tonic-gate 	static int rhs_len = RHS_TEXT_LEN;
1745*0Sstevel@tonic-gate 	static int used = 0;
1746*0Sstevel@tonic-gate 	int s_rhs = (s == NULL ? 0 : wslen(s));
1747*0Sstevel@tonic-gate 	register wchar_t *p;
1748*0Sstevel@tonic-gate 
1749*0Sstevel@tonic-gate 	if (!s)	/* print out and erase old text */
1750*0Sstevel@tonic-gate 	{
1751*0Sstevel@tonic-gate 		if (*lhstext)		/* there was an old rule - dump it */
1752*0Sstevel@tonic-gate 			lrprnt();
1753*0Sstevel@tonic-gate 		(loc = rhstext)[0] = 0;
1754*0Sstevel@tonic-gate 		return;
1755*0Sstevel@tonic-gate 	}
1756*0Sstevel@tonic-gate 	/* add to stuff in rhstext */
1757*0Sstevel@tonic-gate 	p = s;
1758*0Sstevel@tonic-gate 
1759*0Sstevel@tonic-gate 	used = loc - rhstext;
1760*0Sstevel@tonic-gate 	if ((s_rhs + 3) >= (rhs_len - used)) {
1761*0Sstevel@tonic-gate 		static wchar_t *textbase;
1762*0Sstevel@tonic-gate 		textbase = rhstext;
1763*0Sstevel@tonic-gate 		rhs_len += s_rhs + RHS_TEXT_LEN;
1764*0Sstevel@tonic-gate 		rhstext = (wchar_t *)
1765*0Sstevel@tonic-gate 			realloc((char *)rhstext, sizeof (wchar_t)*rhs_len);
1766*0Sstevel@tonic-gate 		if (rhstext == NULL)
1767*0Sstevel@tonic-gate /*
1768*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1769*0Sstevel@tonic-gate  *	This message is passed to error() function.
1770*0Sstevel@tonic-gate  *	RHS -- Right Hand Side.
1771*0Sstevel@tonic-gate  */
1772*0Sstevel@tonic-gate 			error(gettext(
1773*0Sstevel@tonic-gate 			"couldn't expanded RHS length"));
1774*0Sstevel@tonic-gate 		loc = loc - textbase + rhstext;
1775*0Sstevel@tonic-gate 	}
1776*0Sstevel@tonic-gate 
1777*0Sstevel@tonic-gate 	*loc++ = L' ';
1778*0Sstevel@tonic-gate 	if (*s == L' ') /* special quoted symbol */
1779*0Sstevel@tonic-gate 	{
1780*0Sstevel@tonic-gate 		*loc++ = L'\'';	/* add first quote */
1781*0Sstevel@tonic-gate 		p++;
1782*0Sstevel@tonic-gate 	}
1783*0Sstevel@tonic-gate 	while (*loc = *p++)
1784*0Sstevel@tonic-gate 		if (loc++ > &rhstext[ RHS_TEXT_LEN ] - 3)
1785*0Sstevel@tonic-gate 			break;
1786*0Sstevel@tonic-gate 
1787*0Sstevel@tonic-gate 	if (*s == L' ')
1788*0Sstevel@tonic-gate 		*loc++ = L'\'';
1789*0Sstevel@tonic-gate 	*loc = 0;		/* terminate the string */
1790*0Sstevel@tonic-gate }
1791*0Sstevel@tonic-gate 
1792*0Sstevel@tonic-gate static void
1793*0Sstevel@tonic-gate lrprnt()	/* print out the left and right hand sides */
1794*0Sstevel@tonic-gate {
1795*0Sstevel@tonic-gate 	wchar_t *rhs;
1796*0Sstevel@tonic-gate 	wchar_t *m_rhs = NULL;
1797*0Sstevel@tonic-gate 
1798*0Sstevel@tonic-gate 	if (!*rhstext)		/* empty rhs - print usual comment */
1799*0Sstevel@tonic-gate 		rhs = L" /* empty */";
1800*0Sstevel@tonic-gate 	else {
1801*0Sstevel@tonic-gate 		int idx1; /* tmp idx used to find if there are d_quotes */
1802*0Sstevel@tonic-gate 		int idx2; /* tmp idx used to generate escaped string */
1803*0Sstevel@tonic-gate 		wchar_t *p;
1804*0Sstevel@tonic-gate 		/*
1805*0Sstevel@tonic-gate 		 * Check if there are any double quote in RHS.
1806*0Sstevel@tonic-gate 		 */
1807*0Sstevel@tonic-gate 		for (idx1 = 0; rhstext[idx1] != 0; idx1++) {
1808*0Sstevel@tonic-gate 			if (rhstext[idx1] == L'"') {
1809*0Sstevel@tonic-gate 				/*
1810*0Sstevel@tonic-gate 				 * A double quote is found.
1811*0Sstevel@tonic-gate 				 */
1812*0Sstevel@tonic-gate 				idx2 = wslen(rhstext)*2;
1813*0Sstevel@tonic-gate 				p = m_rhs = (wchar_t *)
1814*0Sstevel@tonic-gate 					malloc((idx2 + 1)*sizeof (wchar_t));
1815*0Sstevel@tonic-gate 				if (m_rhs == NULL)
1816*0Sstevel@tonic-gate /*
1817*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1818*0Sstevel@tonic-gate  *	This message is passed to error() function.
1819*0Sstevel@tonic-gate  *	RHS - Right Hand Side.
1820*0Sstevel@tonic-gate  *
1821*0Sstevel@tonic-gate  *	You may just translate this as:
1822*0Sstevel@tonic-gate  *	'Could not allocate internally used memory.'
1823*0Sstevel@tonic-gate  */
1824*0Sstevel@tonic-gate 					error(gettext(
1825*0Sstevel@tonic-gate 					"Couldn't allocate memory for RHS."));
1826*0Sstevel@tonic-gate 				/*
1827*0Sstevel@tonic-gate 				 * Copy string
1828*0Sstevel@tonic-gate 				 */
1829*0Sstevel@tonic-gate 				for (idx2 = 0; rhstext[idx2] != 0; idx2++) {
1830*0Sstevel@tonic-gate 					/*
1831*0Sstevel@tonic-gate 					 * Check if this quote is escaped or not
1832*0Sstevel@tonic-gate 					 */
1833*0Sstevel@tonic-gate 					if (rhstext[idx2] == L'"') {
1834*0Sstevel@tonic-gate 						int tmp_l = idx2-1;
1835*0Sstevel@tonic-gate 						int cnt = 0;
1836*0Sstevel@tonic-gate 						while (tmp_l >= 0 &&
1837*0Sstevel@tonic-gate 						rhstext[tmp_l] == '\\') {
1838*0Sstevel@tonic-gate 							cnt++;
1839*0Sstevel@tonic-gate 							tmp_l--;
1840*0Sstevel@tonic-gate 						}
1841*0Sstevel@tonic-gate 						/*
1842*0Sstevel@tonic-gate 						 * If quote is not escaped,
1843*0Sstevel@tonic-gate 						 * then escape it.
1844*0Sstevel@tonic-gate 						 */
1845*0Sstevel@tonic-gate 						if (cnt%2 == 0)
1846*0Sstevel@tonic-gate 							*p++ = L'\\';
1847*0Sstevel@tonic-gate 					}
1848*0Sstevel@tonic-gate 					*p++ = rhstext[idx2];
1849*0Sstevel@tonic-gate 				}
1850*0Sstevel@tonic-gate 				*p = 0;
1851*0Sstevel@tonic-gate 				/*
1852*0Sstevel@tonic-gate 				 * Break from the loop
1853*0Sstevel@tonic-gate 				 */
1854*0Sstevel@tonic-gate 				break;
1855*0Sstevel@tonic-gate 			}
1856*0Sstevel@tonic-gate 		}
1857*0Sstevel@tonic-gate 		if (m_rhs == NULL)
1858*0Sstevel@tonic-gate 			rhs = rhstext;
1859*0Sstevel@tonic-gate 		else
1860*0Sstevel@tonic-gate 			rhs = m_rhs;
1861*0Sstevel@tonic-gate 	}
1862*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "\t\"%ws :%ws\",\n", lhstext, rhs);
1863*0Sstevel@tonic-gate 	if (m_rhs)
1864*0Sstevel@tonic-gate 		free(m_rhs);
1865*0Sstevel@tonic-gate }
1866*0Sstevel@tonic-gate 
1867*0Sstevel@tonic-gate 
1868*0Sstevel@tonic-gate static void
1869*0Sstevel@tonic-gate beg_debug()	/* dump initial sequence for fdebug file */
1870*0Sstevel@tonic-gate {
1871*0Sstevel@tonic-gate 	(void) fprintf(fdebug,
1872*0Sstevel@tonic-gate 		"typedef struct\n");
1873*0Sstevel@tonic-gate 	(void) fprintf(fdebug,
1874*0Sstevel@tonic-gate 		"#ifdef __cplusplus\n\tyytoktype\n");
1875*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "#endif\n{\n");
1876*0Sstevel@tonic-gate 	(void) fprintf(fdebug,
1877*0Sstevel@tonic-gate 		"#ifdef __cplusplus\nconst\n#endif\n");
1878*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "char *t_name; int t_val; } yytoktype;\n");
1879*0Sstevel@tonic-gate 	(void) fprintf(fdebug,
1880*0Sstevel@tonic-gate 		"#ifndef YYDEBUG\n#\tdefine YYDEBUG\t%d", gen_testing);
1881*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "\t/*%sallow debugging */\n#endif\n\n",
1882*0Sstevel@tonic-gate 		gen_testing ? " " : " don't ");
1883*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "#if YYDEBUG\n\nyytoktype yytoks[] =\n{\n");
1884*0Sstevel@tonic-gate }
1885*0Sstevel@tonic-gate 
1886*0Sstevel@tonic-gate 
1887*0Sstevel@tonic-gate static void
1888*0Sstevel@tonic-gate end_toks()	/* finish yytoks array, get ready for yyred's strings */
1889*0Sstevel@tonic-gate {
1890*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "\t\"-unknown-\",\t-1\t/* ends search */\n");
1891*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "};\n\n");
1892*0Sstevel@tonic-gate 	(void) fprintf(fdebug,
1893*0Sstevel@tonic-gate 		"#ifdef __cplusplus\nconst\n#endif\n");
1894*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "char * yyreds[] =\n{\n");
1895*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "\t\"-no such reduction-\",\n");
1896*0Sstevel@tonic-gate }
1897*0Sstevel@tonic-gate 
1898*0Sstevel@tonic-gate 
1899*0Sstevel@tonic-gate static void
1900*0Sstevel@tonic-gate end_debug()	/* finish yyred array, close file */
1901*0Sstevel@tonic-gate {
1902*0Sstevel@tonic-gate 	lrprnt();		/* dump last lhs, rhs */
1903*0Sstevel@tonic-gate 	(void) fprintf(fdebug, "};\n#endif /* YYDEBUG */\n");
1904*0Sstevel@tonic-gate 	(void) fclose(fdebug);
1905*0Sstevel@tonic-gate }
1906*0Sstevel@tonic-gate 
1907*0Sstevel@tonic-gate 
1908*0Sstevel@tonic-gate /*
1909*0Sstevel@tonic-gate  * 2/29/88 -
1910*0Sstevel@tonic-gate  * The normal length for token sizes is NAMESIZE - If a token is
1911*0Sstevel@tonic-gate  * seen that has a longer length, expand "tokname" by NAMESIZE.
1912*0Sstevel@tonic-gate  */
1913*0Sstevel@tonic-gate static void
1914*0Sstevel@tonic-gate exp_tokname()
1915*0Sstevel@tonic-gate {
1916*0Sstevel@tonic-gate 	toksize += NAMESIZE;
1917*0Sstevel@tonic-gate 	tokname = (wchar_t *)
1918*0Sstevel@tonic-gate 		realloc((char *)tokname, sizeof (wchar_t) * toksize);
1919*0Sstevel@tonic-gate }
1920*0Sstevel@tonic-gate 
1921*0Sstevel@tonic-gate 
1922*0Sstevel@tonic-gate /*
1923*0Sstevel@tonic-gate  * 2/29/88 -
1924*0Sstevel@tonic-gate  *
1925*0Sstevel@tonic-gate  */
1926*0Sstevel@tonic-gate static void
1927*0Sstevel@tonic-gate exp_prod()
1928*0Sstevel@tonic-gate {
1929*0Sstevel@tonic-gate 	int i;
1930*0Sstevel@tonic-gate 	nprodsz += NPROD;
1931*0Sstevel@tonic-gate 
1932*0Sstevel@tonic-gate 	prdptr = (int **) realloc((char *)prdptr, sizeof (int *) * (nprodsz+2));
1933*0Sstevel@tonic-gate 	levprd  = (int *)  realloc((char *)levprd, sizeof (int) * (nprodsz+2));
1934*0Sstevel@tonic-gate 	had_act = (wchar_t *)
1935*0Sstevel@tonic-gate 		realloc((char *)had_act, sizeof (wchar_t) * (nprodsz+2));
1936*0Sstevel@tonic-gate 	for (i = nprodsz-NPROD; i < nprodsz+2; ++i)
1937*0Sstevel@tonic-gate 		had_act[i] = 0;
1938*0Sstevel@tonic-gate 
1939*0Sstevel@tonic-gate 	if ((*prdptr == NULL) || (levprd == NULL) || (had_act == NULL))
1940*0Sstevel@tonic-gate /*
1941*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1942*0Sstevel@tonic-gate  *	This message is passed to error() function.
1943*0Sstevel@tonic-gate  *
1944*0Sstevel@tonic-gate  *	You may just translate this as:
1945*0Sstevel@tonic-gate  *	'Could not allocate internally used memory.'
1946*0Sstevel@tonic-gate  */
1947*0Sstevel@tonic-gate 		error(gettext(
1948*0Sstevel@tonic-gate 		"couldn't expand productions"));
1949*0Sstevel@tonic-gate }
1950*0Sstevel@tonic-gate 
1951*0Sstevel@tonic-gate /*
1952*0Sstevel@tonic-gate  * 2/29/88 -
1953*0Sstevel@tonic-gate  * Expand the number of terminals.  Initially there are NTERMS;
1954*0Sstevel@tonic-gate  * each time space runs out, the size is increased by NTERMS.
1955*0Sstevel@tonic-gate  * The total size, however, cannot exceed MAXTERMS because of
1956*0Sstevel@tonic-gate  * the way LOOKSETS(struct looksets) is set up.
1957*0Sstevel@tonic-gate  * Tables affected:
1958*0Sstevel@tonic-gate  *	tokset, toklev : increased to ntoksz
1959*0Sstevel@tonic-gate  *
1960*0Sstevel@tonic-gate  *	tables with initial dimensions of TEMPSIZE must be changed if
1961*0Sstevel@tonic-gate  *	(ntoksz + NNONTERM) >= TEMPSIZE : temp1[]
1962*0Sstevel@tonic-gate  */
1963*0Sstevel@tonic-gate static void
1964*0Sstevel@tonic-gate exp_ntok()
1965*0Sstevel@tonic-gate {
1966*0Sstevel@tonic-gate 	ntoksz += NTERMS;
1967*0Sstevel@tonic-gate 
1968*0Sstevel@tonic-gate 	tokset = (TOKSYMB *) realloc((char *)tokset, sizeof (TOKSYMB) * ntoksz);
1969*0Sstevel@tonic-gate 	toklev = (int *) realloc((char *)toklev, sizeof (int) * ntoksz);
1970*0Sstevel@tonic-gate 
1971*0Sstevel@tonic-gate 	if ((tokset == NULL) || (toklev == NULL))
1972*0Sstevel@tonic-gate /*
1973*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1974*0Sstevel@tonic-gate  *	This message is passed to error() function.
1975*0Sstevel@tonic-gate  *	Do not translate NTERMS.
1976*0Sstevel@tonic-gate  *
1977*0Sstevel@tonic-gate  *	You may just translate this as:
1978*0Sstevel@tonic-gate  *	'Could not allocate internally used memory.'
1979*0Sstevel@tonic-gate  */
1980*0Sstevel@tonic-gate 		error(gettext(
1981*0Sstevel@tonic-gate 		"couldn't expand NTERMS"));
1982*0Sstevel@tonic-gate }
1983*0Sstevel@tonic-gate 
1984*0Sstevel@tonic-gate 
1985*0Sstevel@tonic-gate static void
1986*0Sstevel@tonic-gate exp_nonterm()
1987*0Sstevel@tonic-gate {
1988*0Sstevel@tonic-gate 	nnontersz += NNONTERM;
1989*0Sstevel@tonic-gate 
1990*0Sstevel@tonic-gate 	nontrst = (NTSYMB *)
1991*0Sstevel@tonic-gate 		realloc((char *)nontrst, sizeof (TOKSYMB) * nnontersz);
1992*0Sstevel@tonic-gate 	if (nontrst == NULL)
1993*0Sstevel@tonic-gate /*
1994*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
1995*0Sstevel@tonic-gate  *	This message is passed to error() function.
1996*0Sstevel@tonic-gate  *	Do not translate NTERMS.
1997*0Sstevel@tonic-gate  *
1998*0Sstevel@tonic-gate  *	You may just translate this as:
1999*0Sstevel@tonic-gate  *	'Could not allocate internally used memory.'
2000*0Sstevel@tonic-gate  */
2001*0Sstevel@tonic-gate 		error(gettext(
2002*0Sstevel@tonic-gate 		"couldn't expand NNONTERM"));
2003*0Sstevel@tonic-gate }
2004*0Sstevel@tonic-gate 
2005*0Sstevel@tonic-gate void
2006*0Sstevel@tonic-gate exp_mem(flag)
2007*0Sstevel@tonic-gate int flag;
2008*0Sstevel@tonic-gate {
2009*0Sstevel@tonic-gate 	int i;
2010*0Sstevel@tonic-gate 	static int *membase;
2011*0Sstevel@tonic-gate 	new_memsize += MEMSIZE;
2012*0Sstevel@tonic-gate 
2013*0Sstevel@tonic-gate 	membase = tracemem;
2014*0Sstevel@tonic-gate 	tracemem = (int *)
2015*0Sstevel@tonic-gate 		realloc((char *)tracemem, sizeof (int) * new_memsize);
2016*0Sstevel@tonic-gate 	if (tracemem == NULL)
2017*0Sstevel@tonic-gate /*
2018*0Sstevel@tonic-gate  * TRANSLATION_NOTE  -- This is a message from yacc.
2019*0Sstevel@tonic-gate  *	This message is passed to error() function.
2020*0Sstevel@tonic-gate  *
2021*0Sstevel@tonic-gate  *	You may just translate this as:
2022*0Sstevel@tonic-gate  *	'Could not allocate internally used memory.'
2023*0Sstevel@tonic-gate  */
2024*0Sstevel@tonic-gate 		error(gettext(
2025*0Sstevel@tonic-gate 		"couldn't expand mem table"));
2026*0Sstevel@tonic-gate 	if (flag) {
2027*0Sstevel@tonic-gate 		for (i = 0; i <= nprod; ++i)
2028*0Sstevel@tonic-gate 			prdptr[i] = prdptr[i] - membase + tracemem;
2029*0Sstevel@tonic-gate 		mem = mem - membase + tracemem;
2030*0Sstevel@tonic-gate 	} else {
2031*0Sstevel@tonic-gate 		size += MEMSIZE;
2032*0Sstevel@tonic-gate 		temp1 = (int *)realloc((char *)temp1, sizeof (int)*size);
2033*0Sstevel@tonic-gate 		optimmem = optimmem - membase + tracemem;
2034*0Sstevel@tonic-gate 	}
2035*0Sstevel@tonic-gate }
2036*0Sstevel@tonic-gate 
2037*0Sstevel@tonic-gate static int
2038*0Sstevel@tonic-gate findchtok(chlit)
2039*0Sstevel@tonic-gate int chlit;
2040*0Sstevel@tonic-gate /*
2041*0Sstevel@tonic-gate  * findchtok(chlit) returns the token number for a character literal
2042*0Sstevel@tonic-gate  * chlit that is "bigger" than 255 -- the max char value that the
2043*0Sstevel@tonic-gate  * original yacc was build for.  This yacc treate them as though
2044*0Sstevel@tonic-gate  * an ordinary token.
2045*0Sstevel@tonic-gate  */
2046*0Sstevel@tonic-gate {
2047*0Sstevel@tonic-gate 	int	i;
2048*0Sstevel@tonic-gate #ifdef	NOLIBW
2049*0Sstevel@tonic-gate 	return (chlit); /* assume always singlebyte char */
2050*0Sstevel@tonic-gate #else /* !NOLIBW */
2051*0Sstevel@tonic-gate 
2052*0Sstevel@tonic-gate 	if (chlit < 0xff)
2053*0Sstevel@tonic-gate 		return (chlit); /* single-byte char */
2054*0Sstevel@tonic-gate 	for (i = 0; i < nmbchars; ++i) {
2055*0Sstevel@tonic-gate 		if (mbchars->character == chlit)
2056*0Sstevel@tonic-gate 			return (mbchars->tvalue);
2057*0Sstevel@tonic-gate 	}
2058*0Sstevel@tonic-gate 
2059*0Sstevel@tonic-gate 	/* Not found.  Register it! */
2060*0Sstevel@tonic-gate 	if (++nmbchars > nmbcharsz) { /* Make sure there's enough space */
2061*0Sstevel@tonic-gate 		nmbcharsz += NMBCHARSZ;
2062*0Sstevel@tonic-gate 		mbchars = (MBCLIT *)
2063*0Sstevel@tonic-gate 		    realloc((char *)mbchars, sizeof (MBCLIT)*nmbcharsz);
2064*0Sstevel@tonic-gate 		if (mbchars == NULL)
2065*0Sstevel@tonic-gate 			error(gettext(
2066*0Sstevel@tonic-gate 			"too many character literals"));
2067*0Sstevel@tonic-gate 	}
2068*0Sstevel@tonic-gate 	mbchars[nmbchars-1].character = chlit;
2069*0Sstevel@tonic-gate 	return (mbchars[nmbchars-1].tvalue = extval++);
2070*0Sstevel@tonic-gate 	/* Return the newly assigned token. */
2071*0Sstevel@tonic-gate #endif /* !NOLIBW */
2072*0Sstevel@tonic-gate }
2073*0Sstevel@tonic-gate 
2074*0Sstevel@tonic-gate /*
2075*0Sstevel@tonic-gate  * When -p is specified, symbol prefix for
2076*0Sstevel@tonic-gate  *	yy{parse, lex, error}(),
2077*0Sstevel@tonic-gate  *	yy{lval, val, char, debug, errflag, nerrs}
2078*0Sstevel@tonic-gate  * are defined to the specified name.
2079*0Sstevel@tonic-gate  */
2080*0Sstevel@tonic-gate static void
2081*0Sstevel@tonic-gate put_prefix_define(char *pre)
2082*0Sstevel@tonic-gate {
2083*0Sstevel@tonic-gate 	char *syms[] = {
2084*0Sstevel@tonic-gate 		/* Functions */
2085*0Sstevel@tonic-gate 		"parse",
2086*0Sstevel@tonic-gate 		"lex",
2087*0Sstevel@tonic-gate 		"error",
2088*0Sstevel@tonic-gate 		/* Variables */
2089*0Sstevel@tonic-gate 		"lval",
2090*0Sstevel@tonic-gate 		"val",
2091*0Sstevel@tonic-gate 		"char",
2092*0Sstevel@tonic-gate 		"debug",
2093*0Sstevel@tonic-gate 		"errflag",
2094*0Sstevel@tonic-gate 		"nerrs",
2095*0Sstevel@tonic-gate 		NULL};
2096*0Sstevel@tonic-gate 	int i;
2097*0Sstevel@tonic-gate 
2098*0Sstevel@tonic-gate 	for (i = 0; syms[i]; i++)
2099*0Sstevel@tonic-gate 		fprintf(ftable, "#define\tyy%s\t%s%s\n",
2100*0Sstevel@tonic-gate 			syms[i], pre, syms[i]);
2101*0Sstevel@tonic-gate }
2102