[BACK]Return to ecs.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / lex

Annotation of src/usr.bin/lex/ecs.c, Revision 1.6

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