mirror of
https://git.savannah.gnu.org/git/gperf.git
synced 2025-12-02 13:09:22 +00:00
Make the backtracking look like a standard Prolog box.
This commit is contained in:
@@ -993,6 +993,16 @@ Search::find_asso_values ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Backtracking according to the standard Prolog call pattern:
|
||||||
|
|
||||||
|
+------------------+
|
||||||
|
-------CALL------>| |-------RETURN------>
|
||||||
|
| |
|
||||||
|
<------FAIL-------| |<------REDO---------
|
||||||
|
+------------------+
|
||||||
|
|
||||||
|
A CALL and RETURN increase the stack pointer, FAIL and REDO decrease it.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
/* Current stack pointer. */
|
/* Current stack pointer. */
|
||||||
StackEntry *sp = &stack[0];
|
StackEntry *sp = &stack[0];
|
||||||
@@ -1014,7 +1024,8 @@ Search::find_asso_values ()
|
|||||||
/* Remaining number of iterations. */
|
/* Remaining number of iterations. */
|
||||||
int iter;
|
int iter;
|
||||||
|
|
||||||
STARTOUTERLOOP:
|
/* ==== CALL ==== */
|
||||||
|
CALL:
|
||||||
|
|
||||||
/* Next keyword from the list. */
|
/* Next keyword from the list. */
|
||||||
curr = sp->_curr;
|
curr = sp->_curr;
|
||||||
@@ -1092,7 +1103,7 @@ Search::find_asso_values ()
|
|||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
}
|
}
|
||||||
goto RECURSE_COLLISION;
|
goto RECURSE_COLLISION;
|
||||||
BACKTRACK_COLLISION: ;
|
BACKTRACK_COLLISION:
|
||||||
if (option[DEBUG])
|
if (option[DEBUG])
|
||||||
{
|
{
|
||||||
fprintf (stderr, "back to collision on keyword #%d, prior = \"%.*s\", curr = \"%.*s\" hash = %d\n",
|
fprintf (stderr, "back to collision on keyword #%d, prior = \"%.*s\", curr = \"%.*s\" hash = %d\n",
|
||||||
@@ -1126,36 +1137,43 @@ Search::find_asso_values ()
|
|||||||
iterations);
|
iterations);
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
BACKTRACK_NO_COLLISION:
|
|
||||||
if (sp != stack)
|
|
||||||
{
|
|
||||||
sp--;
|
|
||||||
curr = sp->_curr;
|
|
||||||
prior = sp->_prior;
|
|
||||||
if (prior == NULL)
|
|
||||||
goto BACKTRACK_NO_COLLISION;
|
|
||||||
union_set = sp->_union_set;
|
|
||||||
union_set_length = sp->_union_set_length;
|
|
||||||
union_index = sp->_union_index;
|
|
||||||
c = sp->_c;
|
|
||||||
original_asso_value = sp->_original_asso_value;
|
|
||||||
iter = sp->_iter;
|
|
||||||
goto BACKTRACK_COLLISION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No solution found after an exhaustive search!
|
|
||||||
We should ideally turn off option[FAST] and, if that doesn't help,
|
|
||||||
multiply _asso_value_max by 2. */
|
|
||||||
fprintf (stderr,
|
|
||||||
"\nBig failure, always got duplicate hash code values.\n");
|
|
||||||
if (option[POSITIONS])
|
|
||||||
fprintf (stderr, "try options -m or -r, or use new key positions.\n\n");
|
|
||||||
else
|
|
||||||
fprintf (stderr, "try options -m or -r.\n\n");
|
|
||||||
exit (1);
|
|
||||||
}
|
}
|
||||||
goto RECURSE_NO_COLLISION;
|
else
|
||||||
|
{
|
||||||
|
/* Nothing to do, just recurse. */
|
||||||
|
goto RECURSE_NO_COLLISION;
|
||||||
|
BACKTRACK_NO_COLLISION: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==== FAIL ==== */
|
||||||
|
if (sp != stack)
|
||||||
|
{
|
||||||
|
sp--;
|
||||||
|
/* ==== REDO ==== */
|
||||||
|
curr = sp->_curr;
|
||||||
|
prior = sp->_prior;
|
||||||
|
if (prior == NULL)
|
||||||
|
goto BACKTRACK_NO_COLLISION;
|
||||||
|
union_set = sp->_union_set;
|
||||||
|
union_set_length = sp->_union_set_length;
|
||||||
|
union_index = sp->_union_index;
|
||||||
|
c = sp->_c;
|
||||||
|
original_asso_value = sp->_original_asso_value;
|
||||||
|
iter = sp->_iter;
|
||||||
|
goto BACKTRACK_COLLISION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No solution found after an exhaustive search!
|
||||||
|
We should ideally turn off option[FAST] and, if that doesn't help,
|
||||||
|
multiply _asso_value_max by 2. */
|
||||||
|
fprintf (stderr,
|
||||||
|
"\nBig failure, always got duplicate hash code values.\n");
|
||||||
|
if (option[POSITIONS])
|
||||||
|
fprintf (stderr, "try options -m or -r, or use new key positions.\n\n");
|
||||||
|
else
|
||||||
|
fprintf (stderr, "try options -m or -r.\n\n");
|
||||||
|
exit (1);
|
||||||
|
|
||||||
RECURSE_COLLISION:
|
RECURSE_COLLISION:
|
||||||
/*sp->_union_set = union_set;*/ // redundant
|
/*sp->_union_set = union_set;*/ // redundant
|
||||||
sp->_union_set_length = union_set_length;
|
sp->_union_set_length = union_set_length;
|
||||||
@@ -1166,9 +1184,10 @@ Search::find_asso_values ()
|
|||||||
RECURSE_NO_COLLISION:
|
RECURSE_NO_COLLISION:
|
||||||
/*sp->_curr = curr;*/ // redundant
|
/*sp->_curr = curr;*/ // redundant
|
||||||
sp->_prior = prior;
|
sp->_prior = prior;
|
||||||
|
/* ==== RETURN ==== */
|
||||||
sp++;
|
sp++;
|
||||||
if (sp - stack < _list_len)
|
if (sp - stack < _list_len)
|
||||||
goto STARTOUTERLOOP;
|
goto CALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deallocate stack. */
|
/* Deallocate stack. */
|
||||||
|
|||||||
Reference in New Issue
Block a user