version 1.6, 2003/06/04 17:34:44 |
version 1.7, 2015/11/19 19:43:40 |
|
|
|
|
/* ecs - equivalence class routines */ |
/* ecs - equivalence class routines */ |
|
|
/*- |
/* Copyright (c) 1990 The Regents of the University of California. */ |
* Copyright (c) 1990 The Regents of the University of California. |
/* All rights reserved. */ |
* All rights reserved. |
|
* |
|
* This code is derived from software contributed to Berkeley by |
|
* Vern Paxson. |
|
* |
|
* The United States Government has rights in this work pursuant |
|
* to contract no. DE-AC03-76SF00098 between the United States |
|
* Department of Energy and the University of California. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* |
|
* Neither the name of the University nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
* PURPOSE. |
|
*/ |
|
|
|
/* $Header$ */ |
/* This code is derived from software contributed to Berkeley by */ |
|
/* Vern Paxson. */ |
|
|
|
/* The United States Government has rights in this work pursuant */ |
|
/* to contract no. DE-AC03-76SF00098 between the United States */ |
|
/* Department of Energy and the University of California. */ |
|
|
|
/* This file is part of flex */ |
|
|
|
/* Redistribution and use in source and binary forms, with or without */ |
|
/* modification, are permitted provided that the following conditions */ |
|
/* are met: */ |
|
|
|
/* 1. Redistributions of source code must retain the above copyright */ |
|
/* notice, this list of conditions and the following disclaimer. */ |
|
/* 2. Redistributions in binary form must reproduce the above copyright */ |
|
/* notice, this list of conditions and the following disclaimer in the */ |
|
/* documentation and/or other materials provided with the distribution. */ |
|
|
|
/* Neither the name of the University nor the names of its contributors */ |
|
/* may be used to endorse or promote products derived from this software */ |
|
/* without specific prior written permission. */ |
|
|
|
/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ |
|
/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ |
|
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ |
|
/* PURPOSE. */ |
|
|
|
|
#include "flexdef.h" |
#include "flexdef.h" |
|
|
/* ccl2ecl - convert character classes to set of equivalence classes */ |
/* ccl2ecl - convert character classes to set of equivalence classes */ |
|
|
void ccl2ecl() |
void ccl2ecl () |
{ |
{ |
int i, ich, newlen, cclp, ccls, cclmec; |
int i, ich, newlen, cclp, ccls, cclmec; |
|
|
for ( i = 1; i <= lastccl; ++i ) |
for (i = 1; i <= lastccl; ++i) { |
{ |
|
/* We loop through each character class, and for each character |
/* We loop through each character class, and for each character |
* in the class, add the character's equivalence class to the |
* in the class, add the character's equivalence class to the |
* new "character" class we are creating. Thus when we are all |
* new "character" class we are creating. Thus when we are all |
|
|
newlen = 0; |
newlen = 0; |
cclp = cclmap[i]; |
cclp = cclmap[i]; |
|
|
for ( ccls = 0; ccls < ccllen[i]; ++ccls ) |
for (ccls = 0; ccls < ccllen[i]; ++ccls) { |
{ |
|
ich = ccltbl[cclp + ccls]; |
ich = ccltbl[cclp + ccls]; |
cclmec = ecgroup[ich]; |
cclmec = ecgroup[ich]; |
|
|
if ( cclmec > 0 ) |
if (cclmec > 0) { |
{ |
|
ccltbl[cclp + newlen] = cclmec; |
ccltbl[cclp + newlen] = cclmec; |
++newlen; |
++newlen; |
} |
|
} |
} |
|
} |
|
|
ccllen[i] = newlen; |
ccllen[i] = newlen; |
} |
|
} |
} |
|
} |
|
|
|
|
/* cre8ecs - associate equivalence class numbers with class members |
/* cre8ecs - associate equivalence class numbers with class members |
|
|
* Returned is the number of classes. |
* Returned is the number of classes. |
*/ |
*/ |
|
|
int cre8ecs( fwd, bck, num ) |
int cre8ecs (fwd, bck, num) |
int fwd[], bck[], num; |
int fwd[], bck[], num; |
{ |
{ |
int i, j, numcl; |
int i, j, numcl; |
|
|
numcl = 0; |
numcl = 0; |
|
|
|
|
* is positive, then x is the representative of its equivalence |
* is positive, then x is the representative of its equivalence |
* class. |
* class. |
*/ |
*/ |
for ( i = 1; i <= num; ++i ) |
for (i = 1; i <= num; ++i) |
if ( bck[i] == NIL ) |
if (bck[i] == NIL) { |
{ |
|
bck[i] = ++numcl; |
bck[i] = ++numcl; |
for ( j = fwd[i]; j != NIL; j = fwd[j] ) |
for (j = fwd[i]; j != NIL; j = fwd[j]) |
bck[j] = -numcl; |
bck[j] = -numcl; |
} |
} |
|
|
return numcl; |
return numcl; |
} |
} |
|
|
|
|
/* mkeccl - update equivalence classes based on character class xtions |
/* mkeccl - update equivalence classes based on character class xtions |
|
|
* NUL_mapping is the value which NUL (0) should be mapped to. |
* NUL_mapping is the value which NUL (0) should be mapped to. |
*/ |
*/ |
|
|
void mkeccl( ccls, lenccl, fwd, bck, llsiz, NUL_mapping ) |
void mkeccl (ccls, lenccl, fwd, bck, llsiz, NUL_mapping) |
Char ccls[]; |
Char ccls[]; |
int lenccl, fwd[], bck[], llsiz, NUL_mapping; |
int lenccl, fwd[], bck[], llsiz, NUL_mapping; |
{ |
{ |
int cclp, oldec, newec; |
int cclp, oldec, newec; |
int cclm, i, j; |
int cclm, i, j; |
static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */ |
static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */ |
|
|
/* Note that it doesn't matter whether or not the character class is |
/* Note that it doesn't matter whether or not the character class is |
|
|
|
|
cclp = 0; |
cclp = 0; |
|
|
while ( cclp < lenccl ) |
while (cclp < lenccl) { |
{ |
|
cclm = ccls[cclp]; |
cclm = ccls[cclp]; |
|
|
if ( NUL_mapping && cclm == 0 ) |
if (NUL_mapping && cclm == 0) |
cclm = NUL_mapping; |
cclm = NUL_mapping; |
|
|
oldec = bck[cclm]; |
oldec = bck[cclm]; |
|
|
|
|
j = cclp + 1; |
j = cclp + 1; |
|
|
for ( i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i] ) |
for (i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i]) { /* look for the symbol in the character class */ |
{ /* look for the symbol in the character class */ |
for (; j < lenccl; ++j) { |
for ( ; j < lenccl; ++j ) |
|
{ |
|
int ccl_char; |
int ccl_char; |
|
|
if ( NUL_mapping && ccls[j] == 0 ) |
if (NUL_mapping && ccls[j] == 0) |
ccl_char = NUL_mapping; |
ccl_char = NUL_mapping; |
else |
else |
ccl_char = ccls[j]; |
ccl_char = ccls[j]; |
|
|
if ( ccl_char > i ) |
if (ccl_char > i) |
break; |
break; |
|
|
if ( ccl_char == i && ! cclflags[j] ) |
if (ccl_char == i && !cclflags[j]) { |
{ |
|
/* We found an old companion of cclm |
/* We found an old companion of cclm |
* in the ccl. Link it into the new |
* in the ccl. Link it into the new |
* equivalence class and flag it as |
* equivalence class and flag it as |
|
|
/* Get next equivalence class member. */ |
/* Get next equivalence class member. */ |
/* continue 2 */ |
/* continue 2 */ |
goto next_pt; |
goto next_pt; |
} |
|
} |
} |
|
} |
|
|
/* Symbol isn't in character class. Put it in the old |
/* Symbol isn't in character class. Put it in the old |
* equivalence class. |
* equivalence class. |
|
|
|
|
bck[i] = oldec; |
bck[i] = oldec; |
|
|
if ( oldec != NIL ) |
if (oldec != NIL) |
fwd[oldec] = i; |
fwd[oldec] = i; |
|
|
oldec = i; |
oldec = i; |
|
|
next_pt: ; |
next_pt:; |
} |
} |
|
|
if ( bck[cclm] != NIL || oldec != bck[cclm] ) |
if (bck[cclm] != NIL || oldec != bck[cclm]) { |
{ |
|
bck[cclm] = NIL; |
bck[cclm] = NIL; |
fwd[oldec] = NIL; |
fwd[oldec] = NIL; |
} |
} |
|
|
fwd[newec] = NIL; |
fwd[newec] = NIL; |
|
|
/* Find next ccl member to process. */ |
/* Find next ccl member to process. */ |
|
|
for ( ++cclp; cclflags[cclp] && cclp < lenccl; ++cclp ) |
for (++cclp; cclflags[cclp] && cclp < lenccl; ++cclp) { |
{ |
|
/* Reset "doesn't need processing" flag. */ |
/* Reset "doesn't need processing" flag. */ |
cclflags[cclp] = 0; |
cclflags[cclp] = 0; |
} |
|
} |
} |
} |
} |
|
} |
|
|
|
|
/* mkechar - create equivalence class for single character */ |
/* mkechar - create equivalence class for single character */ |
|
|
void mkechar( tch, fwd, bck ) |
void mkechar (tch, fwd, bck) |
int tch, fwd[], bck[]; |
int tch, fwd[], bck[]; |
{ |
{ |
/* If until now the character has been a proper subset of |
/* If until now the character has been a proper subset of |
* an equivalence class, break it away to create a new ec |
* an equivalence class, break it away to create a new ec |
*/ |
*/ |
|
|
if ( fwd[tch] != NIL ) |
if (fwd[tch] != NIL) |
bck[fwd[tch]] = bck[tch]; |
bck[fwd[tch]] = bck[tch]; |
|
|
if ( bck[tch] != NIL ) |
if (bck[tch] != NIL) |
fwd[bck[tch]] = fwd[tch]; |
fwd[bck[tch]] = fwd[tch]; |
|
|
fwd[tch] = NIL; |
fwd[tch] = NIL; |
bck[tch] = NIL; |
bck[tch] = NIL; |
} |
} |