scopeTrialCheck method
Implementation
void scopeTrialCheck(
PrimaryRepairInfo repair, List<int> stack, int stack_top, int indx) {
StateInfo? info;
for (var i = stateSeen[stack_top]; i != NIL; i = info.next) {
info = statePool[i];
if (null == info) {
break;
}
if (info.state == stack[stack_top]) return;
}
var old_state_pool_top = statePoolTop++;
if (statePoolTop >= statePool.length) {
ArrayList.copy(statePool, 0,
statePool = List.filled(statePoolTop * 2, null), 0, statePoolTop);
}
statePool[old_state_pool_top] =
StateInfo(stack[stack_top], stateSeen[stack_top]);
stateSeen[stack_top] = old_state_pool_top;
var action = IntTuple(1 << 3);
for (var i = 0; i < SCOPE_SIZE; i++) {
//
// Compute the action (or set of actions in case of conflicts) that
// can be executed on the scope lookahead symbol. Save the action(s)
// in the action tuple.
//
action.reset();
var act = tAction(stack[stack_top], scopeLa(i));
if (act > ACCEPT_ACTION && act < ERROR_ACTION) // conflicting actions?
{
do {
action.add(baseAction(act++));
} while (baseAction(act) != 0);
} else {
action.add(act);
}
//
// For each action defined on the scope lookahead symbol,
// try scope recovery.
//
for (var action_index = 0; action_index < action.size(); action_index++) {
tokStream.reset(buffer[repair.bufferPosition]);
tempStackTop = stack_top - 1;
var max_pos = stack_top;
act = action.get(action_index);
while (act <= NUM_RULES) {
//
// ... Process all goto-reduce actions following
// reduction, until a goto action is computed ...
//
do {
var lhs_symbol = lhs(act);
tempStackTop -= (rhs(act) - 1);
act = (tempStackTop > max_pos
? tempStack[tempStackTop]
: stack[tempStackTop]);
act = ntAction(act, lhs_symbol);
} while (act <= NUM_RULES);
if (tempStackTop + 1 >= stateStack.length) return;
max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
tempStack[tempStackTop + 1] = act;
act = tAction(act, scopeLa(i));
}
//
// If the lookahead symbol is parsable, then we check
// whether or not we have a match between the scope
// prefix and the transition symbols corresponding to
// the states on top of the stack.
//
if (act != ERROR_ACTION) {
int j, k = scopePrefix(i);
for (j = tempStackTop + 1;
j >= (max_pos + 1) && inSymbol(tempStack[j]) == scopeRhs(k);
j--) {
k++;
}
if (j == max_pos) {
for (j = max_pos;
j >= 1 && inSymbol(stack[j]) == scopeRhs(k);
j--) {
k++;
}
}
//
// If the prefix matches, check whether the state
// newly exposed on top of the stack, (after the
// corresponding prefix states are popped from the
// stack), is in the set of "source states" for the
// scope in question and that it is at a position
// below the threshold indicated by MARKED_POS.
//
var marked_pos = (max_pos < stack_top ? max_pos + 1 : stack_top);
if (scopeRhs(k) == 0 && j < marked_pos) // match?
{
var stack_position = j;
for (j = scopeStateSet(i);
stack[stack_position] != scopeState(j) && scopeState(j) != 0;
j++) {
;
}
//
// If the top state is valid for scope recovery,
// the left-hand side of the scope is used as
// starting symbol and we calculate how far the
// parser can advance within the forward context
// after parsing the left-hand symbol.
//
if (scopeState(j) != 0) // state was found
{
var previous_distance = repair.distance,
distance = parseCheck(stack, stack_position,
scopeLhs(i) + NT_OFFSET, repair.bufferPosition);
//
// if the recovery is not successful, we
// update the stack with all actions induced
// by the left-hand symbol, and recursively
// call SCOPE_TRIAL_CHECK to try again.
// Otherwise, the recovery is successful. If
// the new distance is greater than the
// initial SCOPE_DISTANCE, we update
// SCOPE_DISTANCE and set scope_stack_top to INDX
// to indicate the number of scopes that are
// to be applied for a succesful recovery.
// NOTE that this procedure cannot get into
// an infinite loop, since each prefix match
// is guaranteed to take us to a lower point
// within the stack.
//
if ((distance - repair.bufferPosition + 1) < MIN_DISTANCE) {
var top = stack_position;
act = ntAction(stack[top], scopeLhs(i));
while (act <= NUM_RULES) {
top -= (rhs(act) - 1);
act = ntAction(stack[top], lhs(act));
}
top++;
j = act;
act = stack[top]; // save
stack[top] = j; // swap
scopeTrialCheck(repair, stack, top, indx + 1);
stack[top] = act; // restore
} else if (distance > repair.distance) {
scopeStackTop = indx;
repair.distance = distance;
}
//
// If no other recovery possibility is left (due to
// backtracking and we are at the end of the input,
// then we favor a scope recovery over all other kinds
// of recovery.
//
if ( // TODO: main_configuration_stack.size() == 0 && // no other bactracking possibilities left
tokStream.getKind(buffer[repair.bufferPosition]) ==
EOFT_SYMBOL &&
repair.distance == previous_distance) {
scopeStackTop = indx;
repair.distance = MAX_DISTANCE;
}
//
// If this scope recovery has beaten the
// previous distance, then we have found a
// better recovery (or this recovery is one
// of a list of scope recoveries). Record
// its information at the proper location
// (INDX) in SCOPE_INDEX and SCOPE_STACK.
//
if (repair.distance > previous_distance) {
scopeIndex[indx] = i;
scopePosition[indx] = stack_position;
return;
}
}
}
}
}
}
}