1*d9805213SSascha Wildner /* ecs - equivalence class routines */
2*d9805213SSascha Wildner
3*d9805213SSascha Wildner /* Copyright (c) 1990 The Regents of the University of California. */
4*d9805213SSascha Wildner /* All rights reserved. */
5*d9805213SSascha Wildner
6*d9805213SSascha Wildner /* This code is derived from software contributed to Berkeley by */
7*d9805213SSascha Wildner /* Vern Paxson. */
8*d9805213SSascha Wildner
9*d9805213SSascha Wildner /* The United States Government has rights in this work pursuant */
10*d9805213SSascha Wildner /* to contract no. DE-AC03-76SF00098 between the United States */
11*d9805213SSascha Wildner /* Department of Energy and the University of California. */
12*d9805213SSascha Wildner
13*d9805213SSascha Wildner /* This file is part of flex */
14*d9805213SSascha Wildner
15*d9805213SSascha Wildner /* Redistribution and use in source and binary forms, with or without */
16*d9805213SSascha Wildner /* modification, are permitted provided that the following conditions */
17*d9805213SSascha Wildner /* are met: */
18*d9805213SSascha Wildner
19*d9805213SSascha Wildner /* 1. Redistributions of source code must retain the above copyright */
20*d9805213SSascha Wildner /* notice, this list of conditions and the following disclaimer. */
21*d9805213SSascha Wildner /* 2. Redistributions in binary form must reproduce the above copyright */
22*d9805213SSascha Wildner /* notice, this list of conditions and the following disclaimer in the */
23*d9805213SSascha Wildner /* documentation and/or other materials provided with the distribution. */
24*d9805213SSascha Wildner
25*d9805213SSascha Wildner /* Neither the name of the University nor the names of its contributors */
26*d9805213SSascha Wildner /* may be used to endorse or promote products derived from this software */
27*d9805213SSascha Wildner /* without specific prior written permission. */
28*d9805213SSascha Wildner
29*d9805213SSascha Wildner /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
30*d9805213SSascha Wildner /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
31*d9805213SSascha Wildner /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
32*d9805213SSascha Wildner /* PURPOSE. */
33*d9805213SSascha Wildner
34*d9805213SSascha Wildner
35*d9805213SSascha Wildner #include "flexdef.h"
36*d9805213SSascha Wildner
37*d9805213SSascha Wildner /* ccl2ecl - convert character classes to set of equivalence classes */
38*d9805213SSascha Wildner
ccl2ecl(void)39*d9805213SSascha Wildner void ccl2ecl (void)
40*d9805213SSascha Wildner {
41*d9805213SSascha Wildner int i, ich, newlen, cclp, ccls, cclmec;
42*d9805213SSascha Wildner
43*d9805213SSascha Wildner for (i = 1; i <= lastccl; ++i) {
44*d9805213SSascha Wildner /* We loop through each character class, and for each character
45*d9805213SSascha Wildner * in the class, add the character's equivalence class to the
46*d9805213SSascha Wildner * new "character" class we are creating. Thus when we are all
47*d9805213SSascha Wildner * done, character classes will really consist of collections
48*d9805213SSascha Wildner * of equivalence classes
49*d9805213SSascha Wildner */
50*d9805213SSascha Wildner
51*d9805213SSascha Wildner newlen = 0;
52*d9805213SSascha Wildner cclp = cclmap[i];
53*d9805213SSascha Wildner
54*d9805213SSascha Wildner for (ccls = 0; ccls < ccllen[i]; ++ccls) {
55*d9805213SSascha Wildner ich = ccltbl[cclp + ccls];
56*d9805213SSascha Wildner cclmec = ecgroup[ich];
57*d9805213SSascha Wildner
58*d9805213SSascha Wildner if (cclmec > 0) {
59*d9805213SSascha Wildner /* Note: range 1..256 is mapped to 1..255,0 */
60*d9805213SSascha Wildner ccltbl[cclp + newlen] = (unsigned char) cclmec;
61*d9805213SSascha Wildner ++newlen;
62*d9805213SSascha Wildner }
63*d9805213SSascha Wildner }
64*d9805213SSascha Wildner
65*d9805213SSascha Wildner ccllen[i] = newlen;
66*d9805213SSascha Wildner }
67*d9805213SSascha Wildner }
68*d9805213SSascha Wildner
69*d9805213SSascha Wildner
70*d9805213SSascha Wildner /* cre8ecs - associate equivalence class numbers with class members
71*d9805213SSascha Wildner *
72*d9805213SSascha Wildner * fwd is the forward linked-list of equivalence class members. bck
73*d9805213SSascha Wildner * is the backward linked-list, and num is the number of class members.
74*d9805213SSascha Wildner *
75*d9805213SSascha Wildner * Returned is the number of classes.
76*d9805213SSascha Wildner */
77*d9805213SSascha Wildner
cre8ecs(int fwd[],int bck[],int num)78*d9805213SSascha Wildner int cre8ecs (int fwd[], int bck[], int num)
79*d9805213SSascha Wildner {
80*d9805213SSascha Wildner int i, j, numcl;
81*d9805213SSascha Wildner
82*d9805213SSascha Wildner numcl = 0;
83*d9805213SSascha Wildner
84*d9805213SSascha Wildner /* Create equivalence class numbers. From now on, ABS( bck(x) )
85*d9805213SSascha Wildner * is the equivalence class number for object x. If bck(x)
86*d9805213SSascha Wildner * is positive, then x is the representative of its equivalence
87*d9805213SSascha Wildner * class.
88*d9805213SSascha Wildner */
89*d9805213SSascha Wildner for (i = 1; i <= num; ++i)
90*d9805213SSascha Wildner if (bck[i] == NIL) {
91*d9805213SSascha Wildner bck[i] = ++numcl;
92*d9805213SSascha Wildner for (j = fwd[i]; j != NIL; j = fwd[j])
93*d9805213SSascha Wildner bck[j] = -numcl;
94*d9805213SSascha Wildner }
95*d9805213SSascha Wildner
96*d9805213SSascha Wildner return numcl;
97*d9805213SSascha Wildner }
98*d9805213SSascha Wildner
99*d9805213SSascha Wildner
100*d9805213SSascha Wildner /* mkeccl - update equivalence classes based on character class xtions
101*d9805213SSascha Wildner *
102*d9805213SSascha Wildner * synopsis
103*d9805213SSascha Wildner * unsigned char ccls[];
104*d9805213SSascha Wildner * int lenccl, fwd[llsiz], bck[llsiz], llsiz, NUL_mapping;
105*d9805213SSascha Wildner * void mkeccl( unsigned char ccls[], int lenccl, int fwd[llsiz], int bck[llsiz],
106*d9805213SSascha Wildner * int llsiz, int NUL_mapping );
107*d9805213SSascha Wildner *
108*d9805213SSascha Wildner * ccls contains the elements of the character class, lenccl is the
109*d9805213SSascha Wildner * number of elements in the ccl, fwd is the forward link-list of equivalent
110*d9805213SSascha Wildner * characters, bck is the backward link-list, and llsiz size of the link-list.
111*d9805213SSascha Wildner *
112*d9805213SSascha Wildner * NUL_mapping is the value which NUL (0) should be mapped to.
113*d9805213SSascha Wildner */
114*d9805213SSascha Wildner
mkeccl(unsigned char ccls[],int lenccl,int fwd[],int bck[],int llsiz,int NUL_mapping)115*d9805213SSascha Wildner void mkeccl (unsigned char ccls[], int lenccl, int fwd[], int bck[], int llsiz, int NUL_mapping)
116*d9805213SSascha Wildner {
117*d9805213SSascha Wildner int cclp, oldec, newec;
118*d9805213SSascha Wildner int cclm, i, j;
119*d9805213SSascha Wildner static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */
120*d9805213SSascha Wildner
121*d9805213SSascha Wildner /* Note that it doesn't matter whether or not the character class is
122*d9805213SSascha Wildner * negated. The same results will be obtained in either case.
123*d9805213SSascha Wildner */
124*d9805213SSascha Wildner
125*d9805213SSascha Wildner cclp = 0;
126*d9805213SSascha Wildner
127*d9805213SSascha Wildner while (cclp < lenccl) {
128*d9805213SSascha Wildner cclm = ccls[cclp];
129*d9805213SSascha Wildner
130*d9805213SSascha Wildner if (NUL_mapping && cclm == 0)
131*d9805213SSascha Wildner cclm = NUL_mapping;
132*d9805213SSascha Wildner
133*d9805213SSascha Wildner oldec = bck[cclm];
134*d9805213SSascha Wildner newec = cclm;
135*d9805213SSascha Wildner
136*d9805213SSascha Wildner j = cclp + 1;
137*d9805213SSascha Wildner
138*d9805213SSascha Wildner for (i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i]) { /* look for the symbol in the character class */
139*d9805213SSascha Wildner for (; j < lenccl; ++j) {
140*d9805213SSascha Wildner int ccl_char;
141*d9805213SSascha Wildner
142*d9805213SSascha Wildner if (NUL_mapping && ccls[j] == 0)
143*d9805213SSascha Wildner ccl_char = NUL_mapping;
144*d9805213SSascha Wildner else
145*d9805213SSascha Wildner ccl_char = ccls[j];
146*d9805213SSascha Wildner
147*d9805213SSascha Wildner if (ccl_char > i)
148*d9805213SSascha Wildner break;
149*d9805213SSascha Wildner
150*d9805213SSascha Wildner if (ccl_char == i && !cclflags[j]) {
151*d9805213SSascha Wildner /* We found an old companion of cclm
152*d9805213SSascha Wildner * in the ccl. Link it into the new
153*d9805213SSascha Wildner * equivalence class and flag it as
154*d9805213SSascha Wildner * having been processed.
155*d9805213SSascha Wildner */
156*d9805213SSascha Wildner
157*d9805213SSascha Wildner bck[i] = newec;
158*d9805213SSascha Wildner fwd[newec] = i;
159*d9805213SSascha Wildner newec = i;
160*d9805213SSascha Wildner /* Set flag so we don't reprocess. */
161*d9805213SSascha Wildner cclflags[j] = 1;
162*d9805213SSascha Wildner
163*d9805213SSascha Wildner /* Get next equivalence class member. */
164*d9805213SSascha Wildner /* continue 2 */
165*d9805213SSascha Wildner goto next_pt;
166*d9805213SSascha Wildner }
167*d9805213SSascha Wildner }
168*d9805213SSascha Wildner
169*d9805213SSascha Wildner /* Symbol isn't in character class. Put it in the old
170*d9805213SSascha Wildner * equivalence class.
171*d9805213SSascha Wildner */
172*d9805213SSascha Wildner
173*d9805213SSascha Wildner bck[i] = oldec;
174*d9805213SSascha Wildner
175*d9805213SSascha Wildner if (oldec != NIL)
176*d9805213SSascha Wildner fwd[oldec] = i;
177*d9805213SSascha Wildner
178*d9805213SSascha Wildner oldec = i;
179*d9805213SSascha Wildner
180*d9805213SSascha Wildner next_pt:;
181*d9805213SSascha Wildner }
182*d9805213SSascha Wildner
183*d9805213SSascha Wildner if (bck[cclm] != NIL || oldec != bck[cclm]) {
184*d9805213SSascha Wildner bck[cclm] = NIL;
185*d9805213SSascha Wildner fwd[oldec] = NIL;
186*d9805213SSascha Wildner }
187*d9805213SSascha Wildner
188*d9805213SSascha Wildner fwd[newec] = NIL;
189*d9805213SSascha Wildner
190*d9805213SSascha Wildner /* Find next ccl member to process. */
191*d9805213SSascha Wildner
192*d9805213SSascha Wildner for (++cclp; cclp < lenccl && cclflags[cclp]; ++cclp) {
193*d9805213SSascha Wildner /* Reset "doesn't need processing" flag. */
194*d9805213SSascha Wildner cclflags[cclp] = 0;
195*d9805213SSascha Wildner }
196*d9805213SSascha Wildner }
197*d9805213SSascha Wildner }
198*d9805213SSascha Wildner
199*d9805213SSascha Wildner
200*d9805213SSascha Wildner /* mkechar - create equivalence class for single character */
201*d9805213SSascha Wildner
mkechar(int tch,int fwd[],int bck[])202*d9805213SSascha Wildner void mkechar (int tch, int fwd[], int bck[])
203*d9805213SSascha Wildner {
204*d9805213SSascha Wildner /* If until now the character has been a proper subset of
205*d9805213SSascha Wildner * an equivalence class, break it away to create a new ec
206*d9805213SSascha Wildner */
207*d9805213SSascha Wildner
208*d9805213SSascha Wildner if (fwd[tch] != NIL)
209*d9805213SSascha Wildner bck[fwd[tch]] = bck[tch];
210*d9805213SSascha Wildner
211*d9805213SSascha Wildner if (bck[tch] != NIL)
212*d9805213SSascha Wildner fwd[bck[tch]] = fwd[tch];
213*d9805213SSascha Wildner
214*d9805213SSascha Wildner fwd[tch] = NIL;
215*d9805213SSascha Wildner bck[tch] = NIL;
216*d9805213SSascha Wildner }
217