xref: /onnv-gate/usr/src/cmd/sgs/lex/common/sub3.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 2005 Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  * Use is subject to license terms.
26*0Sstevel@tonic-gate  */
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /*
31*0Sstevel@tonic-gate  * sub3.c ... ALE enhancement.
32*0Sstevel@tonic-gate  * Since a typical Asian language has a huge character set, it is not
33*0Sstevel@tonic-gate  * ideal to index an array by a character code itself, which requires
34*0Sstevel@tonic-gate  * as large as 2**16 entries per array.
35*0Sstevel@tonic-gate  * To get arround this problem, we identify a set of characters that
36*0Sstevel@tonic-gate  * causes the same transition on all states and call it character group.
37*0Sstevel@tonic-gate  * Every character in a same character group has a unique number called
38*0Sstevel@tonic-gate  * character group id.  A function yycgid(c) maps the character c (in process
39*0Sstevel@tonic-gate  * code) to the id.  This mapping is determined by analyzing all regular
40*0Sstevel@tonic-gate  * expressions in the lex program.
41*0Sstevel@tonic-gate  *
42*0Sstevel@tonic-gate  */
43*0Sstevel@tonic-gate #include	<stdlib.h>
44*0Sstevel@tonic-gate #include	<widec.h>
45*0Sstevel@tonic-gate #include	<search.h>
46*0Sstevel@tonic-gate #include	"ldefs.c"
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate /*
49*0Sstevel@tonic-gate  * "lchar" stands for linearized character.  It is a variant of
50*0Sstevel@tonic-gate  * process code.  AT&T's 16-bit process code has a drawback in which
51*0Sstevel@tonic-gate  * for three three process code C, D and E where C <= D <= E,
52*0Sstevel@tonic-gate  * codeset(C)==codeset(E) does not mean codeset(D)==codeset(C).
53*0Sstevel@tonic-gate  * In other words, four codesets alternates as the magnitude
54*0Sstevel@tonic-gate  * of character increases.
55*0Sstevel@tonic-gate  * The lchar representation holds this property:
56*0Sstevel@tonic-gate  *   If three lchar C', D' and E' have the relationship C' < D' <  E' and
57*0Sstevel@tonic-gate  *   codeset(C') == codeset(E') then D' is guaranteed to belong to
58*0Sstevel@tonic-gate  *   the same codeset as C' and E'.
59*0Sstevel@tonic-gate  * lchar is implemented as 32 bit entities and the function linearize()
60*0Sstevel@tonic-gate  * that maps a wchar_t to lchar is defined below.  There is no
61*0Sstevel@tonic-gate  * reverse function for it though.
62*0Sstevel@tonic-gate  * The 32-bit process code by AT&T, used only for Taiwanese version at the
63*0Sstevel@tonic-gate  * time of wrting, has no such problem and we use it as it is.
64*0Sstevel@tonic-gate  */
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate lchar	yycgidtbl[MAXNCG] = {
67*0Sstevel@tonic-gate 	0, 		/* For ease of computation of the id. */
68*0Sstevel@tonic-gate 	'\n', 		/* Newline is always special because '.' exclude it. */
69*0Sstevel@tonic-gate 	0x000000ff, 	/* The upper limit of codeset 0. */
70*0Sstevel@tonic-gate 	0x20ffffff,	/* The upper limit of codeset 2. */
71*0Sstevel@tonic-gate 	0x40ffffff	/* The upper limit of codeset 3. */
72*0Sstevel@tonic-gate /*	0x60ffffff	   The upper limit of codeset 1. */
73*0Sstevel@tonic-gate 	/* Above assumes the number of significant bits of wchar_t is <= 24. */
74*0Sstevel@tonic-gate };
75*0Sstevel@tonic-gate int	ncgidtbl = 5; /* # elements in yycgidtbl. */
76*0Sstevel@tonic-gate int	ncg; /* Should set to ncgidtbl*2; this is the largest value yycgid() */
77*0Sstevel@tonic-gate 		/* returns plus 1. */
78*0Sstevel@tonic-gate 
79*0Sstevel@tonic-gate static void setsymbol(int i);
80*0Sstevel@tonic-gate 
81*0Sstevel@tonic-gate /*
82*0Sstevel@tonic-gate  * For given 16-bit wchar_t (See NOTE), lchar is computed as illustrated below:
83*0Sstevel@tonic-gate  *
84*0Sstevel@tonic-gate  * 	wc: axxxxxxbyyyyyyy
85*0Sstevel@tonic-gate  *
86*0Sstevel@tonic-gate  * returns: 0ab0000000000000axxxxxxxbyyyyyyy
87*0Sstevel@tonic-gate  *
88*0Sstevel@tonic-gate  * linearize() doesn't do any if compiled with 32-bit wchar_t, use of
89*0Sstevel@tonic-gate  * which is flagged with LONG_WCHAR_T macro.
90*0Sstevel@tonic-gate  * NOTE:
91*0Sstevel@tonic-gate  * The implementation is highly depends on the process code representation.
92*0Sstevel@tonic-gate  * This function should be modified when 32-bit process code is used.
93*0Sstevel@tonic-gate  * There is no need to keep 'a' and 'b' bits in the lower half of lchar.
94*0Sstevel@tonic-gate  * You can actually omit these and squeeze the xxxxxx part one bit right.
95*0Sstevel@tonic-gate  * We don't do that here just in sake of speed.
96*0Sstevel@tonic-gate  */
97*0Sstevel@tonic-gate lchar
98*0Sstevel@tonic-gate linearize(wchar_t wc)
99*0Sstevel@tonic-gate {
100*0Sstevel@tonic-gate #ifdef LONG_WCHAR_T
101*0Sstevel@tonic-gate 	return ((lchar)wc); /* Don't do anything. */
102*0Sstevel@tonic-gate #else
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	lchar	prefix;
105*0Sstevel@tonic-gate 	switch (wc&0x8080) {
106*0Sstevel@tonic-gate 	case 0x0000: prefix = 0x00000000; break;
107*0Sstevel@tonic-gate 	case 0x0080: prefix = 0x20000000; break;
108*0Sstevel@tonic-gate 	case 0x8000: prefix = 0x40000000; break;
109*0Sstevel@tonic-gate 	case 0x8080: prefix = 0x60000000; break;
110*0Sstevel@tonic-gate 	}
111*0Sstevel@tonic-gate 	return (prefix|wc);
112*0Sstevel@tonic-gate #endif
113*0Sstevel@tonic-gate }
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate /* compare liniear characters pointed to by pc1 and pc2 */
116*0Sstevel@tonic-gate int
117*0Sstevel@tonic-gate cmplc(const void *arg1, const void *arg2)
118*0Sstevel@tonic-gate {
119*0Sstevel@tonic-gate 	lchar *pc1 = (lchar *)arg1;
120*0Sstevel@tonic-gate 	lchar *pc2 = (lchar *)arg2;
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate 	if (*pc1 > *pc2)
123*0Sstevel@tonic-gate 		return (1);
124*0Sstevel@tonic-gate 	else if (*pc1 == *pc2)
125*0Sstevel@tonic-gate 		return (0);
126*0Sstevel@tonic-gate 	else
127*0Sstevel@tonic-gate 		return (-1);
128*0Sstevel@tonic-gate }
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate void
131*0Sstevel@tonic-gate remch(wchar_t c)
132*0Sstevel@tonic-gate {
133*0Sstevel@tonic-gate 	lchar	lc = linearize(c);
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	/*
136*0Sstevel@tonic-gate 	 * User-friendliness consideration:
137*0Sstevel@tonic-gate 	 * Make sure no EUC chars are used in reg. exp.
138*0Sstevel@tonic-gate 	 */
139*0Sstevel@tonic-gate 	if (!handleeuc) {
140*0Sstevel@tonic-gate 		if (!isascii(c))
141*0Sstevel@tonic-gate 		    if (iswprint(c))
142*0Sstevel@tonic-gate 			warning(
143*0Sstevel@tonic-gate "Non-ASCII character '%wc' in pattern; use -w or -e lex option.", c);
144*0Sstevel@tonic-gate 		    else warning(
145*0Sstevel@tonic-gate "Non-ASCII character of value %#x in pattern; use -w or -e lex option.", c);
146*0Sstevel@tonic-gate 		/* In any case, we don't need to construct ncgidtbl[]. */
147*0Sstevel@tonic-gate 		return;
148*0Sstevel@tonic-gate 	}
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 	lsearch(&lc, yycgidtbl,
151*0Sstevel@tonic-gate 		(size_t *)&ncgidtbl, sizeof (lchar), cmplc);
152*0Sstevel@tonic-gate }
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate void
155*0Sstevel@tonic-gate sortcgidtbl(void)
156*0Sstevel@tonic-gate {
157*0Sstevel@tonic-gate 	if (!handleeuc)
158*0Sstevel@tonic-gate 		return;
159*0Sstevel@tonic-gate 	qsort(yycgidtbl, ncgidtbl, sizeof (lchar), cmplc);
160*0Sstevel@tonic-gate }
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate /*
163*0Sstevel@tonic-gate  * int yycgid(wchar_t c)
164*0Sstevel@tonic-gate  *	Takes c and returns its character group id, determind by the
165*0Sstevel@tonic-gate  *	following algorithm.  The program also uses the binary search
166*0Sstevel@tonic-gate  *	algorithm, generalized from Knuth (6.2.1) Algorithm B.
167*0Sstevel@tonic-gate  *
168*0Sstevel@tonic-gate  *	This function computes the "character group id" based on
169*0Sstevel@tonic-gate  *	a table yycgidtbl of which each lchar entry is pre-sorted
170*0Sstevel@tonic-gate  *	in ascending sequence  The number of valid entries is given
171*0Sstevel@tonic-gate  *	by YYNCGIDTBL.  There is no duplicate entries in yycgidtbl.
172*0Sstevel@tonic-gate  *		const int YYNCGIDTBL;
173*0Sstevel@tonic-gate  *		lchar	yycgidtbl[YYNCGIDTBL];
174*0Sstevel@tonic-gate  *
175*0Sstevel@tonic-gate  *	yycgidtbl[0] is guaranteed to have zero.
176*0Sstevel@tonic-gate  *
177*0Sstevel@tonic-gate  *	For given c, yycgid(c) returns:
178*0Sstevel@tonic-gate  *		2*i	iff yycgidtbl[i] == lc
179*0Sstevel@tonic-gate  *		2*i+1	iff yycgidtbl[i] < lc < yycgidtbl[i+1]
180*0Sstevel@tonic-gate  *		YYNCGIDTBL*2-1
181*0Sstevel@tonic-gate  *			iff yycgidtbl[YYNCGIDTBL-1] < lc
182*0Sstevel@tonic-gate  *	where lc=linearize(c).
183*0Sstevel@tonic-gate  *
184*0Sstevel@tonic-gate  *	Some interesting properties.:
185*0Sstevel@tonic-gate  *	1.  For any c, 0 <= yycgid(c) <= 2*YYNCGIDTBL-1
186*0Sstevel@tonic-gate  *	2.  yycgid(c) == 0  iff  c == 0.
187*0Sstevel@tonic-gate  *	3.  For any wchar_t c and d, if linearize(c) < linearize(d) then
188*0Sstevel@tonic-gate  *	    yycgid(c) <= yycgid(d).
189*0Sstevel@tonic-gate  *	4.  For any wchar_t c and d, if yycgid(c) < yycgid(d) then
190*0Sstevel@tonic-gate  *	    linearize(c) < linearize(d).
191*0Sstevel@tonic-gate  */
192*0Sstevel@tonic-gate #define	YYNCGIDTBL ncgidtbl
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate int
195*0Sstevel@tonic-gate yycgid(wchar_t c)
196*0Sstevel@tonic-gate {
197*0Sstevel@tonic-gate 	int first = 0;
198*0Sstevel@tonic-gate 	int last = YYNCGIDTBL - 1;
199*0Sstevel@tonic-gate 	lchar lc;
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate 	/*
202*0Sstevel@tonic-gate 	 * In ASCII compat. mode, each character forms a "group" and the
203*0Sstevel@tonic-gate 	 * group-id is itself...
204*0Sstevel@tonic-gate 	 */
205*0Sstevel@tonic-gate 	if (!handleeuc)
206*0Sstevel@tonic-gate 		return (c);
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 	lc = linearize(c);
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate 	/* An exceptional case: yycgidtbl[YYNCGIDTBL-1] < lc */
211*0Sstevel@tonic-gate 	if (yycgidtbl[YYNCGIDTBL - 1] < lc)
212*0Sstevel@tonic-gate 		return (YYNCGIDTBL*2 - 1);
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate 	while (last >= 0) {
215*0Sstevel@tonic-gate 		int i = (first+last)/2;
216*0Sstevel@tonic-gate 		if (lc == yycgidtbl[i])
217*0Sstevel@tonic-gate 		    return (2*i);	/* lc  exactly matches an element. */
218*0Sstevel@tonic-gate 		else if (yycgidtbl[i] < lc) {
219*0Sstevel@tonic-gate 			if (lc < yycgidtbl[i+1])
220*0Sstevel@tonic-gate 			    return (2*i+1); /* lc is in between two elements. */
221*0Sstevel@tonic-gate 			else
222*0Sstevel@tonic-gate 			    first = i + 1;
223*0Sstevel@tonic-gate 		} else
224*0Sstevel@tonic-gate 		    last = i - 1;
225*0Sstevel@tonic-gate 	}
226*0Sstevel@tonic-gate 	error(
227*0Sstevel@tonic-gate 	"system error in yycgid():binary search failed for c=0x%04x\n", c);
228*0Sstevel@tonic-gate 	return (0);
229*0Sstevel@tonic-gate }
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate /*
232*0Sstevel@tonic-gate  * repbycgid --- replaces each character in the parsing tree by its
233*0Sstevel@tonic-gate  * character group id.   This, however, should be called even in
234*0Sstevel@tonic-gate  * the ASCII compat. mode to process DOT nodes and to call cclinter()
235*0Sstevel@tonic-gate  * for the DOT and CCL nodes.
236*0Sstevel@tonic-gate  */
237*0Sstevel@tonic-gate void
238*0Sstevel@tonic-gate repbycgid(void)
239*0Sstevel@tonic-gate {
240*0Sstevel@tonic-gate 	int i, c;
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	for (i = 0; i < tptr; ++i) {
243*0Sstevel@tonic-gate 		c = name[i];
244*0Sstevel@tonic-gate 		if (!ISOPERATOR(c)) {
245*0Sstevel@tonic-gate 		/* If not an operator, it must be a char.  */
246*0Sstevel@tonic-gate 		    name[i] = yycgid((wchar_t)c); /* So replace it. */
247*0Sstevel@tonic-gate #ifdef DEBUG
248*0Sstevel@tonic-gate 		    if (debug) {
249*0Sstevel@tonic-gate 			    printf("name[%d]:'%c'->%d;\n", i, c, name[i]);
250*0Sstevel@tonic-gate 		    }
251*0Sstevel@tonic-gate #endif
252*0Sstevel@tonic-gate 		} else if (c == RSTR) {
253*0Sstevel@tonic-gate 			c = right[i];
254*0Sstevel@tonic-gate 			right[i] = yycgid((wchar_t)c);
255*0Sstevel@tonic-gate #ifdef DEBUG
256*0Sstevel@tonic-gate 		    if (debug) {
257*0Sstevel@tonic-gate 			    printf(
258*0Sstevel@tonic-gate 			    "name[%d].right:'%c'->%d;\n", i, c, right[i]);
259*0Sstevel@tonic-gate 		    }
260*0Sstevel@tonic-gate #endif
261*0Sstevel@tonic-gate 		} else if ((c == RCCL) || (c == RNCCL)) {
262*0Sstevel@tonic-gate 			CHR cc, *s;
263*0Sstevel@tonic-gate 			int j;
264*0Sstevel@tonic-gate 			CHR ccltoken[CCLSIZE];
265*0Sstevel@tonic-gate 			CHR *ccp;
266*0Sstevel@tonic-gate 			int m;
267*0Sstevel@tonic-gate 			/*
268*0Sstevel@tonic-gate 			 * This node represetns a character class RE [ccccc]
269*0Sstevel@tonic-gate 			 * s points to the string of characters that forms
270*0Sstevel@tonic-gate 			 * the class and/or a special prefix notation
271*0Sstevel@tonic-gate 			 * <RANGE>XY which corresponds to the RE X-Y,
272*0Sstevel@tonic-gate 			 * characters in the range of X and Y.  Here,
273*0Sstevel@tonic-gate 			 * X <= Y is guranteed.
274*0Sstevel@tonic-gate 			 * We transform these characters into a string
275*0Sstevel@tonic-gate 			 * of sorted character group ids.
276*0Sstevel@tonic-gate 			 *
277*0Sstevel@tonic-gate 			 * There is another mechanism of packing tables
278*0Sstevel@tonic-gate 			 * that is inherited from the ASCII lex.  Call of
279*0Sstevel@tonic-gate 			 * cclinter() is required for this packing.
280*0Sstevel@tonic-gate 			 * This used to be done as yylex() reads the lex
281*0Sstevel@tonic-gate 			 * rules but we have to do this here because the
282*0Sstevel@tonic-gate 			 * transition table is made to work on the char-group
283*0Sstevel@tonic-gate 			 * ids and the mapping cannot be determined until
284*0Sstevel@tonic-gate 			 * the entire file is read.
285*0Sstevel@tonic-gate 			 */
286*0Sstevel@tonic-gate #ifdef DEBUG
287*0Sstevel@tonic-gate 			if (debug) {
288*0Sstevel@tonic-gate 				printf("name[%d]:R[N]CCL of \"", i);
289*0Sstevel@tonic-gate 				strpt(left[i]);
290*0Sstevel@tonic-gate 				printf(" -> {");
291*0Sstevel@tonic-gate 			}
292*0Sstevel@tonic-gate #endif
293*0Sstevel@tonic-gate 			/* Prepare symbol[] for cclinter(). */
294*0Sstevel@tonic-gate 			for (j = 0; j < ncg; ++j)
295*0Sstevel@tonic-gate 				symbol[j] = FALSE;
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate 			s = (CHR *) left[i];
298*0Sstevel@tonic-gate 			while (cc = *s++) {
299*0Sstevel@tonic-gate 				if (cc == RANGE) {
300*0Sstevel@tonic-gate 					int	low, high, i;
301*0Sstevel@tonic-gate 					/*
302*0Sstevel@tonic-gate 					 * Special form: <RANGE>XY
303*0Sstevel@tonic-gate 					 * This means the range X-Y.
304*0Sstevel@tonic-gate 					 * We mark all symbols[]
305*0Sstevel@tonic-gate 					 * elements for yycgid(X) thru
306*0Sstevel@tonic-gate 					 * yycgid(Y), inclusively.
307*0Sstevel@tonic-gate 					 */
308*0Sstevel@tonic-gate 					low = yycgid(*s++);
309*0Sstevel@tonic-gate 					high = yycgid(*s++);
310*0Sstevel@tonic-gate 					for (i = low; i <= high; ++i)
311*0Sstevel@tonic-gate 					    setsymbol(i);
312*0Sstevel@tonic-gate 				} else {
313*0Sstevel@tonic-gate 					setsymbol(yycgid(cc));
314*0Sstevel@tonic-gate 				}
315*0Sstevel@tonic-gate 			}
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 			/* Now make a transformed string of cgids. */
318*0Sstevel@tonic-gate 			s = ccptr;
319*0Sstevel@tonic-gate 			m = 0;
320*0Sstevel@tonic-gate 			for (j = 0; j < ncg; ++j)
321*0Sstevel@tonic-gate 			    if (symbol[j]) {
322*0Sstevel@tonic-gate 				    ccltoken[m++] = (CHR)j;
323*0Sstevel@tonic-gate #ifdef DEBUG
324*0Sstevel@tonic-gate 				    if (debug) printf("%d, ", j);
325*0Sstevel@tonic-gate #endif
326*0Sstevel@tonic-gate 			    }
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate #ifdef DEBUG
329*0Sstevel@tonic-gate 			if (debug) printf("}\n");
330*0Sstevel@tonic-gate #endif
331*0Sstevel@tonic-gate 			ccltoken[m] = 0;
332*0Sstevel@tonic-gate 			ccp = ccl;
333*0Sstevel@tonic-gate 			while (ccp < ccptr && scomp(ccltoken, ccp) != 0)
334*0Sstevel@tonic-gate 				ccp++;
335*0Sstevel@tonic-gate 			if (ccp < ccptr) {  /* character class found in ccl */
336*0Sstevel@tonic-gate 			    left[i] = (int)ccp;
337*0Sstevel@tonic-gate 			} else { /* not in ccl, add it */
338*0Sstevel@tonic-gate 			    left[i] = (int)ccptr;
339*0Sstevel@tonic-gate 			    scopy(ccltoken, ccptr);
340*0Sstevel@tonic-gate 			    ccptr += slength(ccltoken) + 1;
341*0Sstevel@tonic-gate 			    if (ccptr > ccl + CCLSIZE)
342*0Sstevel@tonic-gate 				error("Too many large character classes");
343*0Sstevel@tonic-gate 			}
344*0Sstevel@tonic-gate 			cclinter(c == RCCL);
345*0Sstevel@tonic-gate 		} else if (c == DOT) {
346*0Sstevel@tonic-gate 			if (psave == 0) { /* First DOT node. */
347*0Sstevel@tonic-gate 				int j, nlid;
348*0Sstevel@tonic-gate 				/*
349*0Sstevel@tonic-gate 				 * Make symbol[k]=TRUE for all k
350*0Sstevel@tonic-gate 				 *  except k == yycgid('\n').
351*0Sstevel@tonic-gate 				 */
352*0Sstevel@tonic-gate 				nlid = yycgid('\n');
353*0Sstevel@tonic-gate 				psave = ccptr;
354*0Sstevel@tonic-gate 				for (j = 1; j < ncg; ++j) {
355*0Sstevel@tonic-gate 					if (j == nlid) {
356*0Sstevel@tonic-gate 						symbol[j] = FALSE;
357*0Sstevel@tonic-gate 					} else {
358*0Sstevel@tonic-gate 						symbol[j] = TRUE;
359*0Sstevel@tonic-gate 						*ccptr++ = (CHR) j;
360*0Sstevel@tonic-gate 					}
361*0Sstevel@tonic-gate 				}
362*0Sstevel@tonic-gate 				*ccptr++ = 0;
363*0Sstevel@tonic-gate 				if (ccptr > ccl + CCLSIZE)
364*0Sstevel@tonic-gate 				    error("Too many large character classes");
365*0Sstevel@tonic-gate 			}
366*0Sstevel@tonic-gate 			/* Mimic mn1(RCCL,psave)... */
367*0Sstevel@tonic-gate 			name[i] = RCCL;
368*0Sstevel@tonic-gate 			left[i] = (int)psave;
369*0Sstevel@tonic-gate 			cclinter(1);
370*0Sstevel@tonic-gate 		}
371*0Sstevel@tonic-gate 	}
372*0Sstevel@tonic-gate #ifdef DEBUG
373*0Sstevel@tonic-gate 	if (debug) {
374*0Sstevel@tonic-gate 		printf("treedump after repbycgid().\n");
375*0Sstevel@tonic-gate 		treedump();
376*0Sstevel@tonic-gate 	}
377*0Sstevel@tonic-gate #endif
378*0Sstevel@tonic-gate }
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate static void
381*0Sstevel@tonic-gate setsymbol(int i)
382*0Sstevel@tonic-gate {
383*0Sstevel@tonic-gate 	if (i > sizeof (symbol))
384*0Sstevel@tonic-gate 		error("setsymbol: (SYSERR) %d out of range", i);
385*0Sstevel@tonic-gate 	symbol[i] = TRUE;
386*0Sstevel@tonic-gate }
387