touched up rex.c

This commit is contained in:
hyung-hwan 2010-05-11 07:15:55 +00:00
parent b0a03e0b4d
commit 57c56594a5
5 changed files with 282 additions and 245 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: lda.h 323 2010-04-05 12:50:01Z hyunghwan.chung $ * $Id: lda.h 327 2010-05-10 13:15:55Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -344,16 +344,30 @@ void qse_lda_clear (
qse_lda_t* lda qse_lda_t* lda
); );
void qse_lda_walk ( /**
* The qse_lda_walk() function calls the @a walker function for each
* element in the array beginning from the first. The @a walker function
* should return one of #QSE_LDA_WALK_FORWARD, #QSE_LDA_WALK_BACKWARD,
* #QSE_LDA_WALK_STOP.
* @return number of calls to the @a walker fucntion made
*/
qse_size_t qse_lda_walk (
qse_lda_t* lda, qse_lda_t* lda,
qse_lda_walker_t walker, qse_lda_walker_t walker,
void* arg void* ctx
); );
void qse_lda_rwalk ( /**
* The qse_lda_rwalk() function calls the @a walker function for each
* element in the array beginning from the last. The @a walker function
* should return one of #QSE_LDA_WALK_FORWARD, #QSE_LDA_WALK_BACKWARD,
* #QSE_LDA_WALK_STOP.
* @return number of calls to the @a walker fucntion made
*/
qse_size_t qse_lda_rwalk (
qse_lda_t* lda, qse_lda_t* lda,
qse_lda_walker_t walker, qse_lda_walker_t walker,
void* arg void* ctx
); );
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* $Id: map.h 287 2009-09-15 10:01:02Z hyunghwan.chung $ * $Id: map.h 327 2010-05-10 13:15:55Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -323,43 +323,32 @@ void qse_map_setscale (
); );
/******/ /******/
/****f* Common/qse_map_getcopier /**
* NAME * The qse_map_getcopier() function gets a data copier.
* qse_map_getcopier - get a data copier
* PARAMETERS
* * id - QSE_MAP_KEY or QSE_MAP_VAL
* SYNOPSIS
*/ */
qse_map_copier_t qse_map_getcopier ( qse_map_copier_t qse_map_getcopier (
qse_map_t* map, qse_map_t* map,
qse_map_id_t id qse_map_id_t id /**< QSE_MAP_KEY or QSE_MAP_VAL */
); );
/*****/
/****f* Common/qse_map_setcopier /**
* NAME * The qse_map_setcopier() function specifies how to clone an element.
* qse_map_setcopier - specify how to clone an element
*
* DESCRIPTION
* A special copier QSE_MAP_COPIER_INLINE is provided. This copier enables * A special copier QSE_MAP_COPIER_INLINE is provided. This copier enables
* you to copy the data inline to the internal node. No freeer is invoked * you to copy the data inline to the internal node. No freeer is invoked
* when the node is freeed. * when the node is freeed.
* *
* You may set the copier to QSE_NULL to perform no special operation * You may set the copier to QSE_NULL to perform no special operation
* when the data pointer is rememebered. * when the data pointer is rememebered.
*
* SYNOPSIS
*/ */
void qse_map_setcopier ( void qse_map_setcopier (
qse_map_t* map /* a map */, qse_map_t* map, /**< a map */
qse_map_id_t id /* QSE_MAP_KEY or QSE_MAP_VAL */, qse_map_id_t id, /**< QSE_MAP_KEY or QSE_MAP_VAL */
qse_map_copier_t copier /* an element copier */ qse_map_copier_t copier /**< element copier */
); );
/******/
qse_map_freeer_t qse_map_getfreeer ( qse_map_freeer_t qse_map_getfreeer (
qse_map_t* map /* a map */, qse_map_t* map, /**< map */
qse_map_id_t id /* QSE_MAP_KEY or QSE_MAP_VAL */ qse_map_id_t id /**< QSE_MAP_KEY or QSE_MAP_VAL */
); );
/** /**
@ -494,10 +483,10 @@ void qse_map_clear (
); );
/* traverse a map */ /* traverse a map */
void qse_map_walk ( qse_size_t qse_map_walk (
qse_map_t* map /* a map */, qse_map_t* map /* a map */,
qse_map_walker_t walker /* the pointer to the function for each pair */, qse_map_walker_t walker /* the pointer to the function for each pair */,
void* arg /* a pointer to user-specific data */ void* ctx /* a pointer to user-specific data */
); );
/* get the pointer to the first pair in the map. */ /* get the pointer to the first pair in the map. */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: lda.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ * $Id: lda.c 327 2010-05-10 13:15:55Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -514,59 +514,69 @@ void qse_lda_clear (lda_t* lda)
lda->size = 0; lda->size = 0;
} }
void qse_lda_walk (lda_t* lda, walker_t walker, void* arg) size_t qse_lda_walk (lda_t* lda, walker_t walker, void* ctx)
{ {
qse_lda_walk_t w = QSE_LDA_WALK_FORWARD; qse_lda_walk_t w = QSE_LDA_WALK_FORWARD;
size_t i = 0; size_t i = 0, nwalks = 0;
if (lda->size <= 0) return; if (lda->size <= 0) return 0;
while (1) while (1)
{ {
if (lda->node[i] != QSE_NULL) if (lda->node[i] != QSE_NULL)
w = walker (lda, i, arg); {
w = walker (lda, i, ctx);
nwalks++;
}
if (w == QSE_LDA_WALK_STOP) return; if (w == QSE_LDA_WALK_STOP) break;
if (w == QSE_LDA_WALK_FORWARD) if (w == QSE_LDA_WALK_FORWARD)
{ {
i++; i++;
if (i >= lda->size) return; if (i >= lda->size) break;
} }
if (w == QSE_LDA_WALK_BACKWARD) if (w == QSE_LDA_WALK_BACKWARD)
{ {
if (i <= 0) return; if (i <= 0) break;
i--; i--;
} }
} }
return nwalks;
} }
void qse_lda_rwalk (lda_t* lda, walker_t walker, void* arg) size_t qse_lda_rwalk (lda_t* lda, walker_t walker, void* ctx)
{ {
qse_lda_walk_t w = QSE_LDA_WALK_BACKWARD; qse_lda_walk_t w = QSE_LDA_WALK_BACKWARD;
size_t i; size_t i, nwalks = 0;
if (lda->size <= 0) return; if (lda->size <= 0) return 0;
i = lda->size - 1; i = lda->size - 1;
while (1) while (1)
{ {
if (lda->node[i] != QSE_NULL) if (lda->node[i] != QSE_NULL)
w = walker (lda, i, arg); {
w = walker (lda, i, ctx);
nwalks++;
}
if (w == QSE_LDA_WALK_STOP) return; if (w == QSE_LDA_WALK_STOP) break;
if (w == QSE_LDA_WALK_FORWARD) if (w == QSE_LDA_WALK_FORWARD)
{ {
i++; i++;
if (i >= lda->size) return; if (i >= lda->size) break;
} }
if (w == QSE_LDA_WALK_BACKWARD) if (w == QSE_LDA_WALK_BACKWARD)
{ {
if (i <= 0) return; if (i <= 0) break;
i--; i--;
} }
} }
return nwalks;
} }
size_t qse_lda_pushstack (lda_t* lda, void* dptr, size_t dlen) size_t qse_lda_pushstack (lda_t* lda, void* dptr, size_t dlen)

View File

@ -1,5 +1,5 @@
/* /*
* $Id: map.c 289 2009-09-16 06:35:29Z hyunghwan.chung $ * $Id: map.c 327 2010-05-10 13:15:55Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -572,9 +572,9 @@ void qse_map_clear (map_t* map)
} }
void qse_map_walk (map_t* map, walker_t walker, void* arg) size_t qse_map_walk (map_t* map, walker_t walker, void* arg)
{ {
size_t i; size_t i, nwalks = 0;
pair_t* pair, * next; pair_t* pair, * next;
for (i = 0; i < map->capa; i++) for (i = 0; i < map->capa; i++)
@ -584,10 +584,14 @@ void qse_map_walk (map_t* map, walker_t walker, void* arg)
while (pair != QSE_NULL) while (pair != QSE_NULL)
{ {
next = NEXT(pair); next = NEXT(pair);
if (walker(map, pair, arg) == QSE_MAP_WALK_STOP) return; if (walker(map, pair, arg) == QSE_MAP_WALK_STOP)
return nwalks;
nwalks++;
pair = next; pair = next;
} }
} }
return nwalks;
} }
pair_t* qse_map_getfirstpair (map_t* map, size_t* buckno) pair_t* qse_map_getfirstpair (map_t* map, size_t* buckno)

View File

@ -1,5 +1,5 @@
/* /*
* $Id: rex.c 326 2010-05-09 13:44:39Z hyunghwan.chung $ * $Id: rex.c 327 2010-05-10 13:15:55Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -910,6 +910,36 @@ static qse_rex_node_t* comp_atom (comp_t* com)
return atom; return atom;
} }
#if 0
static qse_rex_node_t* zero_or_more (comp_t* c, qse_rex_node_t* atom)
{
qse_rex_node_t* b;
b = newbranchnode (c, QSE_NULL, atom);
if (b == QSE_NULL) return QSE_NULL;
atom->occ.min = 1;
atom->occ.max = 1;
atom->next = b;
return b;
}
static qse_rex_node_t* one_or_more (comp_t* c, qse_rex_node_t* atom)
{
qse_rex_node_t* b;
b = newbranchnode (c, atom, QSE_NULL);
atom->occ.min = 1;
atom->occ.max = 1;
atom->next = b;
TODO: return b as the tail....
return atom;
}
#endif
static qse_rex_node_t* pseudo_group (comp_t* c, qse_rex_node_t* atom) static qse_rex_node_t* pseudo_group (comp_t* c, qse_rex_node_t* atom)
{ {
qse_rex_node_t* g, *ge, * b; qse_rex_node_t* g, *ge, * b;
@ -962,20 +992,41 @@ static qse_rex_node_t* comp_branch (comp_t* c, pair_t* pair)
{ {
qse_rex_node_t* atom = comp_atom (c); qse_rex_node_t* atom = comp_atom (c);
if (atom == QSE_NULL) return QSE_NULL; if (atom == QSE_NULL) return QSE_NULL;
if (atom->occ.min <= 0) if (atom->occ.min <= 0)
{ {
/* #if 0
* Given an atom, this function encloses it with a pseudogroup if (atom->occ.max >= OCC_MAX)
* head and a psuedo-group tail. the pseudogroup head is {
* followed by a branch that conntects to the pseudogroup tail /*
* and the atom given. The atom given gets connected to the * +-----------next--+
* pseudogroup tail. * v |
* Head -> BR -> Tail * BR --alter----> ORG(atom)
* -> ORG(atom) -> Tail * |
*/ * +----next------------------->
atom = pseudo_group (c, atom); *
*/
atom = zero_or_more (c, atom);
}
else
{
#endif
/*
* Given an atom, enclose it with a
* pseudogroup head and a psuedogroup
* tail. the head is followed by a
* branch that conntects to the tail
* and the atom given. The atom given
* gets connected to the tail.
* Head -> BR -> Tail
* -> ORG(atom) -> Tail
*/
atom = pseudo_group (c, atom);
}
if (atom == QSE_NULL) return QSE_NULL; if (atom == QSE_NULL) return QSE_NULL;
#if 0
} }
#endif
if (pair->tail == QSE_NULL) if (pair->tail == QSE_NULL)
{ {
@ -1340,22 +1391,21 @@ static int addcands (
exec_t* e, group_t* group, qse_rex_node_t* prevnode, exec_t* e, group_t* group, qse_rex_node_t* prevnode,
qse_rex_node_t* candnode, const qse_char_t* mptr) qse_rex_node_t* candnode, const qse_char_t* mptr)
{ {
qse_rex_node_t* curcand = candnode;
warpback: warpback:
#ifndef DONOT_SKIP_NOP
/* skip all NOP nodes */ /* skip all NOP nodes */
while (candnode != QSE_NULL && candnode->id == QSE_REX_NODE_NOP) while (curcand != QSE_NULL && curcand->id == QSE_REX_NODE_NOP)
candnode = candnode->next; curcand = curcand->next;
#endif
/* nothing to add */ /* nothing to add */
if (candnode == QSE_NULL) return 0; if (curcand == QSE_NULL) return 0;
switch (candnode->id) switch (curcand->id)
{ {
case QSE_REX_NODE_END: case QSE_REX_NODE_END:
{ {
/*qse_printf (QSE_T("== ADDING THE END(MATCH) NODE MEANING MATCH FOUND == \n"));*/
if (e->matchend == QSE_NULL || mptr >= e->matchend) if (e->matchend == QSE_NULL || mptr >= e->matchend)
e->matchend = mptr; e->matchend = mptr;
e->nmatches++; e->nmatches++;
@ -1373,52 +1423,33 @@ warpback:
if (gx == QSE_NULL) return -1; if (gx == QSE_NULL) return -1;
} }
#if 0
refupgroupstack (group);
refupgroupstack (gx);
n = addcands (e, group,
prevnode, candnode->next, mptr);
if (n >= 0)
{
n = addcands (e, gx,
prevnode, candnode->u.b.alter, mptr);
}
refdowngroupstack (gx, e->rex->mmgr);
refdowngroupstack (group, e->rex->mmgr);
if (n <= -1) return -1;
break;
#endif
refupgroupstack (gx); refupgroupstack (gx);
n = addcands (e, gx, n = addcands (e, gx,
prevnode, candnode->u.b.alter, mptr); prevnode, curcand->u.b.alter, mptr);
refdowngroupstack (gx, e->rex->mmgr); refdowngroupstack (gx, e->rex->mmgr);
if (n <= -1) return -1; if (n <= -1) return -1;
candnode = candnode->next; curcand = curcand->next;
goto warpback; goto warpback;
} }
case QSE_REX_NODE_GROUP: case QSE_REX_NODE_GROUP:
{ {
int n;
qse_rex_node_t* front; qse_rex_node_t* front;
group_t* gx; group_t* gx;
#ifdef XTRA_DEBUG #ifdef XTRA_DEBUG
qse_printf (QSE_T("DEBUG: GROUP %p(pseudo=%d) PREV %p\n"), qse_printf (QSE_T("DEBUG: GROUP %p(pseudo=%d) PREV %p\n"),
candnode, candnode->u.g.pseudo, prevnode); curcand, curcand->u.g.pseudo, prevnode);
#endif #endif
if (candnode->u.g.pseudo) if (curcand->u.g.pseudo)
{ {
candnode = candnode->u.g.head; curcand = curcand->u.g.head;
goto warpback; goto warpback;
} }
/* skip all NOP nodes */ /* skip all NOP nodes */
front = candnode->u.g.head; front = curcand->u.g.head;
while (front->id == QSE_REX_NODE_NOP) while (front->id == QSE_REX_NODE_NOP)
front = front->next; front = front->next;
@ -1429,22 +1460,18 @@ warpback:
* regardless of its occurrence. * regardless of its occurrence.
* however, this will never be reached * however, this will never be reached
* as it has been removed in comp() */ * as it has been removed in comp() */
candnode = candnode->next; curcand = curcand->next;
goto warpback; goto warpback;
} }
gx = groupstackpush (e, group, candnode); gx = groupstackpush (e, group, curcand);
if (gx == QSE_NULL) return -1; if (gx == QSE_NULL) return -1;
/* add the first node in the group to /* add the first node in the group to
* the candidate array */ * the candidate array */
refupgroupstack (gx); group = gx;
n = addcands (e, gx, prevnode, front, mptr); curcand = front;
refdowngroupstack (gx, e->rex->mmgr); goto warpback;
if (n <= -1) return -1;
break;
} }
case QSE_REX_NODE_GROUPEND: case QSE_REX_NODE_GROUPEND:
@ -1456,12 +1483,12 @@ warpback:
#ifdef XTRA_DEBUG #ifdef XTRA_DEBUG
qse_printf (QSE_T("DEBUG: GROUPEND %p(pseudo=%d) PREV %p\n"), qse_printf (QSE_T("DEBUG: GROUPEND %p(pseudo=%d) PREV %p\n"),
candnode, candnode->u.ge.pseudo, prevnode); curcand, curcand->u.ge.pseudo, prevnode);
#endif #endif
if (candnode->u.ge.pseudo) if (curcand->u.ge.pseudo)
{ {
candnode = candnode->u.ge.group->next; curcand = curcand->u.ge.group->next;
goto warpback; goto warpback;
} }
@ -1469,7 +1496,7 @@ warpback:
group != QSE_NULL && group->next != QSE_NULL, group != QSE_NULL && group->next != QSE_NULL,
"GROUPEND must be paired up with GROUP"); "GROUPEND must be paired up with GROUP");
if (prevnode == candnode) if (prevnode == curcand)
{ {
/* consider a pattern like (x*)*. /* consider a pattern like (x*)*.
* when GROUPEND is reached, an 'if' block * when GROUPEND is reached, an 'if' block
@ -1488,7 +1515,7 @@ warpback:
occ = top->occ; occ = top->occ;
node = top->node; node = top->node;
QSE_ASSERTX (node == candnode->u.ge.group, QSE_ASSERTX (node == curcand->u.ge.group,
"The GROUP node in the group stack must be the " "The GROUP node in the group stack must be the "
"one pairing up with the GROUPEND node." "one pairing up with the GROUPEND node."
); );
@ -1539,7 +1566,7 @@ warpback:
prevnode->id == QSE_REX_NODE_GROUPEND) prevnode->id == QSE_REX_NODE_GROUPEND)
n = addcands (e, gx, prevnode, node->next, mptr); n = addcands (e, gx, prevnode, node->next, mptr);
else else
n = addcands (e, gx, candnode, node->next, mptr); n = addcands (e, gx, curcand, node->next, mptr);
refdowngroupstack (gx, e->rex->mmgr); refdowngroupstack (gx, e->rex->mmgr);
if (n <= -1) return -1; if (n <= -1) return -1;
@ -1548,18 +1575,9 @@ warpback:
if (occ < node->occ.max) if (occ < node->occ.max)
{ {
/* repeat itself. */ /* repeat itself. */
/* BEGIN avoid recursion */ prevnode = curcand;
#if 0 curcand = node->u.g.head;
refupgroupstack (group);
n = addcands (e, group, prevnode, node->u.g.head, mptr);
refdowngroupstack (group, e->rex->mmgr);
if (n <= -1) return -1;
#endif
prevnode = candnode;
candnode = node->u.g.head;
goto warpback; goto warpback;
/* END avoid recursion */
} }
break; break;
@ -1570,7 +1588,7 @@ warpback:
int n; int n;
if (group) refupgroupstack (group); if (group) refupgroupstack (group);
n = addsimplecand (e, group, candnode, 1, mptr); n = addsimplecand (e, group, curcand, 1, mptr);
if (group) refdowngroupstack (group, e->rex->mmgr); if (group) refdowngroupstack (group, e->rex->mmgr);
if (n <= -1) return -1; if (n <= -1) return -1;
@ -1664,152 +1682,142 @@ static int charset_matched (exec_t* e, qse_rex_node_t* node, qse_char_t c)
return matched; return matched;
} }
static int match (exec_t* e) static qse_lda_walk_t walk_cands_for_match (
qse_lda_t* lda, qse_size_t index, void* ctx)
{ {
qse_size_t i; exec_t* e = (exec_t*)ctx;
cand_t* cand = QSE_LDA_DPTR(lda,index);
qse_rex_node_t* node = cand->node;
const qse_char_t* nmptr = QSE_NULL;
QSE_ASSERT (QSE_LDA_SIZE(&e->cand.set[e->cand.active]) > 0); switch (node->id)
for (i = 0; i < QSE_LDA_SIZE(&e->cand.set[e->cand.active]); i++)
{ {
cand_t* cand = QSE_LDA_DPTR(&e->cand.set[e->cand.active],i); case QSE_REX_NODE_BOL:
qse_rex_node_t* node = cand->node; if (cand->mptr == e->str.ptr)
const qse_char_t* nmptr = QSE_NULL; {
/* the next match pointer remains
switch (node->id) * the same as ^ matches a position,
{ * not a character. */
#ifdef DONOT_SKIP_NOP
case QSE_REX_NODE_NOP:
nmptr = cand->mptr; nmptr = cand->mptr;
break; #ifdef XTRA_DEBUG
#endif qse_printf (QSE_T("DEBUG: matched <^>\n"));
#endif
}
break;
case QSE_REX_NODE_BOL: case QSE_REX_NODE_EOL:
if (cand->mptr == e->str.ptr) if (cand->mptr >= e->str.end)
{ {
/* the next match pointer remains /* the next match pointer remains
* the same as ^ matches a position, * the same as $ matches a position,
* not a character. */ * not a character. */
nmptr = cand->mptr; nmptr = cand->mptr;
#ifdef XTRA_DEBUG #ifdef XTRA_DEBUG
qse_printf (QSE_T("DEBUG: matched <^>\n")); qse_printf (QSE_T("DEBUG: matched <$>\n"));
#endif #endif
} }
break; break;
case QSE_REX_NODE_EOL: case QSE_REX_NODE_ANY:
if (cand->mptr >= e->str.end) if (cand->mptr < e->sub.end)
{ {
/* the next match pointer remains /* advance the match pointer to the
* the same as $ matches a position, * next chracter.*/
* not a character. */ nmptr = cand->mptr + 1;
nmptr = cand->mptr; #ifdef XTRA_DEBUG
#ifdef XTRA_DEBUG qse_printf (QSE_T("DEBUG: matched <.>\n"));
qse_printf (QSE_T("DEBUG: matched <$>\n")); #endif
#endif }
} break;
break;
case QSE_REX_NODE_ANY: case QSE_REX_NODE_CHAR:
if (cand->mptr < e->sub.end) {
if (cand->mptr < e->sub.end)
{
int equal;
equal =(e->rex->option & QSE_REX_IGNORECASE)?
(QSE_TOUPPER(node->u.c) == QSE_TOUPPER(*cand->mptr)):
(node->u.c == *cand->mptr) ;
if (equal)
{ {
/* advance the match pointer to the /* advance the match pointer to the
* next chracter.*/ * next chracter.*/
nmptr = cand->mptr + 1; nmptr = cand->mptr + 1;
#ifdef XTRA_DEBUG
qse_printf (QSE_T("DEBUG: matched <.>\n"));
#endif
} }
break; #ifdef XTRA_DEBUG
qse_printf (QSE_T("DEBUG: matched %c\n"), node->u.c);
case QSE_REX_NODE_CHAR: #endif
{
if (cand->mptr < e->sub.end)
{
int equal;
equal =(e->rex->option & QSE_REX_IGNORECASE)?
(QSE_TOUPPER(node->u.c) == QSE_TOUPPER(*cand->mptr)):
(node->u.c == *cand->mptr) ;
if (equal)
{
/* advance the match pointer to the
* next chracter.*/
nmptr = cand->mptr + 1;
}
#ifdef XTRA_DEBUG
qse_printf (QSE_T("DEBUG: matched %c\n"), node->u.c);
#endif
}
break;
}
case QSE_REX_NODE_CSET:
{
if (cand->mptr < e->sub.end &&
charset_matched(e, node, *cand->mptr))
{
/* advance the match pointer
* to the next chracter.*/
nmptr = cand->mptr + 1;
}
break;
}
default:
{
QSE_ASSERTX (0,
"SHOUL NEVER HAPPEN - node ID must be"
"one of QSE_REX_NODE_BOL, "
"QSE_REX_NODE_EOL, "
"QSE_REX_NODE_ANY, "
"QSE_REX_NODE_CHAR, "
"QSE_REX_NODE_CSET, "
"QSE_REX_NODE_NOP");
break;
} }
break;
} }
if (nmptr != QSE_NULL) case QSE_REX_NODE_CSET:
{ {
int n; if (cand->mptr < e->sub.end &&
charset_matched(e, node, *cand->mptr))
if (cand->occ >= node->occ.min)
{ {
group_t* gx; /* advance the match pointer
* to the next chracter.*/
if (cand->occ < node->occ.max && cand->group != QSE_NULL) nmptr = cand->mptr + 1;
{
gx = dupgroupstack (e, cand->group);
if (gx == QSE_NULL) return -1;
}
else gx = cand->group;
/* move on to the next candidate */
refupgroupstack (gx);
n = addcands (e, gx, node, node->next, nmptr);
refdowngroupstack (gx, e->rex->mmgr);
if (n <= -1) return -1;
} }
if (cand->occ < node->occ.max) break;
{ }
/* repeat itself more */
refupgroupstack (cand->group);
n = addsimplecand (e, cand->group, node, cand->occ+1, nmptr);
refdowngroupstack (cand->group, e->rex->mmgr);
if (n <= -1) return -1; default:
} {
QSE_ASSERTX (0,
"SHOULD NEVER HAPPEN - node ID must be"
"one of QSE_REX_NODE_BOL, "
"QSE_REX_NODE_EOL, "
"QSE_REX_NODE_ANY, "
"QSE_REX_NODE_CHAR, "
"QSE_REX_NODE_CSET, "
"QSE_REX_NODE_NOP");
break;
} }
} }
return 0; if (nmptr != QSE_NULL)
{
int n;
if (cand->occ >= node->occ.min)
{
group_t* gx;
if (cand->occ < node->occ.max && cand->group != QSE_NULL)
{
gx = dupgroupstack (e, cand->group);
if (gx == QSE_NULL) return QSE_LDA_WALK_STOP;
}
else gx = cand->group;
/* move on to the next candidate */
refupgroupstack (gx);
n = addcands (e, gx, node, node->next, nmptr);
refdowngroupstack (gx, e->rex->mmgr);
if (n <= -1) return QSE_LDA_WALK_STOP;
}
if (cand->occ < node->occ.max)
{
/* repeat itself more */
refupgroupstack (cand->group);
n = addsimplecand (
e, cand->group,
node, cand->occ + 1, nmptr);
refdowngroupstack (cand->group, e->rex->mmgr);
if (n <= -1) return QSE_LDA_WALK_STOP;
}
}
return QSE_LDA_WALK_FORWARD;
} }
static int exec (exec_t* e) static int exec (exec_t* e)
@ -1828,7 +1836,7 @@ static int exec (exec_t* e)
/* the first node must be the START node */ /* the first node must be the START node */
QSE_ASSERT (e->rex->code->id == QSE_REX_NODE_START); QSE_ASSERT (e->rex->code->id == QSE_REX_NODE_START);
/* addcands() collects a set of candidates into the pending set */ /* collect an initial set of candidates into the pending set */
n = addcands ( n = addcands (
e, /* execution structure */ e, /* execution structure */
QSE_NULL, /* doesn't belong to any groups yet */ QSE_NULL, /* doesn't belong to any groups yet */
@ -1840,6 +1848,8 @@ static int exec (exec_t* e)
do do
{ {
qse_size_t ncands_active;
/* swap the pending and active set indices. /* swap the pending and active set indices.
* the pending set becomes active after which the match() * the pending set becomes active after which the match()
* function tries each candidate in it. New candidates * function tries each candidate in it. New candidates
@ -1849,7 +1859,8 @@ static int exec (exec_t* e)
e->cand.pending = e->cand.active; e->cand.pending = e->cand.active;
e->cand.active = tmp; e->cand.active = tmp;
if (QSE_LDA_SIZE(&e->cand.set[e->cand.active]) <= 0) ncands_active = QSE_LDA_SIZE(&e->cand.set[e->cand.active]);
if (ncands_active <= 0)
{ {
/* we can't go on with no candidates in the /* we can't go on with no candidates in the
* active set. */ * active set. */
@ -1863,7 +1874,7 @@ static int exec (exec_t* e)
{ {
int i; int i;
qse_printf (QSE_T("SET=")); qse_printf (QSE_T("SET="));
for (i = 0; i < QSE_LDA_SIZE(&e->cand.set[e->cand.active]); i++) for (i = 0; i < ncands_active; i++)
{ {
cand_t* cand = QSE_LDA_DPTR(&e->cand.set[e->cand.active],i); cand_t* cand = QSE_LDA_DPTR(&e->cand.set[e->cand.active],i);
qse_rex_node_t* node = cand->node; qse_rex_node_t* node = cand->node;
@ -1881,7 +1892,15 @@ static int exec (exec_t* e)
} }
#endif #endif
if (match (e) <= -1) return -1; if (qse_lda_walk (
&e->cand.set[e->cand.active],
walk_cands_for_match, e) != ncands_active)
{
/* if the number of walks is different the number of
* candidates, traversal must have been aborted for
* an error. */
return -1;
}
} }
while (1); while (1);
@ -1910,6 +1929,7 @@ static int comp_cand (qse_lda_t* lda,
{ {
cand_t* c1 = (cand_t*)dptr1; cand_t* c1 = (cand_t*)dptr1;
cand_t* c2 = (cand_t*)dptr2; cand_t* c2 = (cand_t*)dptr2;
//qse_printf (QSE_T("%p(%d) %p(%d), %p %p, %d %d\n"), c1->node,c1->node->id, c2->node,c1->node->id, c1->mptr, c2->mptr, (int)c1->occ, (int)c2->occ);
return (c1->node == c2->node && return (c1->node == c2->node &&
c1->mptr == c2->mptr && c1->mptr == c2->mptr &&
c1->occ == c2->occ)? 0: 1; c1->occ == c2->occ)? 0: 1;