secondaryPhase method
Implementation
RepairCandidate secondaryPhase(int error_token) {
var repair = SecondaryRepairInfo(),
misplaced_repair = SecondaryRepairInfo();
//
// If the next_stack is available, try misplaced and secondary
// recovery on it first.
//
var next_last_index = 0;
if (nextStackTop >= 0) {
int save_location;
buffer[2] = error_token;
buffer[1] = tokStream.getPrevious(buffer[2]);
buffer[0] = tokStream.getPrevious(buffer[1]);
for (var k = 3; k < BUFF_UBOUND; k++) {
buffer[k] = tokStream.getNext(buffer[k - 1]);
}
buffer[BUFF_UBOUND] = tokStream.badToken(); // elmt not available
//
// If we are at the end of the input stream, compute the
// index position of the first EOFT symbol (last useful
// index).
//
for (next_last_index = MAX_DISTANCE - 1;
next_last_index >= 1 &&
tokStream.getKind(buffer[next_last_index]) == EOFT_SYMBOL;
next_last_index--) {
;
}
next_last_index = next_last_index + 1;
save_location = locationStack[nextStackTop];
locationStack[nextStackTop] = buffer[2];
misplaced_repair.numDeletions = nextStackTop;
misplacementRecovery(
misplaced_repair, nextStack, nextStackTop, next_last_index, true);
if (misplaced_repair.recoveryOnNextStack) misplaced_repair.distance++;
repair.numDeletions = nextStackTop + BUFF_UBOUND;
secondaryRecovery(repair, nextStack, nextStackTop, next_last_index, true);
if (repair.recoveryOnNextStack) repair.distance++;
locationStack[nextStackTop] = save_location;
} else // next_stack not available, initialize ...
{
misplaced_repair.numDeletions = stateStackTop;
repair.numDeletions = stateStackTop + BUFF_UBOUND;
}
//
// Try secondary recovery on the "stack" configuration.
//
buffer[3] = error_token;
buffer[2] = tokStream.getPrevious(buffer[3]);
buffer[1] = tokStream.getPrevious(buffer[2]);
buffer[0] = tokStream.getPrevious(buffer[1]);
for (var k = 4; k < BUFF_SIZE; k++) {
buffer[k] = tokStream.getNext(buffer[k - 1]);
}
int last_index;
for (last_index = MAX_DISTANCE - 1;
last_index >= 1 && tokStream.getKind(buffer[last_index]) == EOFT_SYMBOL;
last_index--) {
;
}
last_index++;
misplacementRecovery(
misplaced_repair, stateStack, stateStackTop, last_index, false);
secondaryRecovery(repair, stateStack, stateStackTop, last_index, false);
//
// If a successful misplaced recovery was found, compare it with
// the most successful secondary recovery. If the misplaced
// recovery either deletes fewer symbols or parse-checks further
// then it is chosen.
//
if (misplaced_repair.distance > MIN_DISTANCE) {
if (misplaced_repair.numDeletions <= repair.numDeletions ||
(misplaced_repair.distance - misplaced_repair.numDeletions) >=
(repair.distance - repair.numDeletions)) {
repair.code = MISPLACED_CODE;
repair.stackPosition = misplaced_repair.stackPosition;
repair.bufferPosition = 2;
repair.numDeletions = misplaced_repair.numDeletions;
repair.distance = misplaced_repair.distance;
repair.recoveryOnNextStack = misplaced_repair.recoveryOnNextStack;
}
}
//
// If the successful recovery was on next_stack, update: stack,
// buffer, location_stack and last_index.
//
if (repair.recoveryOnNextStack) {
stateStackTop = nextStackTop;
ArrayList.copy(nextStack, 0, stateStack, 0, stateStackTop + 1);
buffer[2] = error_token;
buffer[1] = tokStream.getPrevious(buffer[2]);
buffer[0] = tokStream.getPrevious(buffer[1]);
for (var k = 3; k < BUFF_UBOUND; k++) {
buffer[k] = tokStream.getNext(buffer[k - 1]);
}
buffer[BUFF_UBOUND] = tokStream.badToken(); // elmt not available
locationStack[nextStackTop] = buffer[2];
last_index = next_last_index;
}
//
// Next, try scope recoveries after deletion of one, two, three,
// four ... buffer_position tokens from the input stream.
//
if (repair.code == SECONDARY_CODE || repair.code == DELETION_CODE) {
var scope_repair = PrimaryRepairInfo();
for (scope_repair.bufferPosition = 2;
scope_repair.bufferPosition <= repair.bufferPosition &&
repair.code != SCOPE_CODE;
scope_repair.bufferPosition++) {
scopeTrial(scope_repair, stateStack, stateStackTop);
var j = (scope_repair.distance == MAX_DISTANCE
? last_index
: scope_repair.distance),
k = scope_repair.bufferPosition - 1;
if ((scope_repair.distance - k) > MIN_DISTANCE &&
(j - k) > (repair.distance - repair.numDeletions)) {
var i = scopeIndex[scopeStackTop]; // upper bound
repair.code = SCOPE_CODE;
repair.symbol = scopeLhs(i) + NT_OFFSET;
repair.stackPosition = stateStackTop;
repair.bufferPosition = scope_repair.bufferPosition;
}
}
}
//
// If a successful repair was not found, quit! Otherwise, issue
// diagnosis and adjust configuration...
//
var candidate = RepairCandidate();
if (repair.code == 0) return candidate;
secondaryDiagnosis(repair);
//
// Update buffer based on number of elements that are deleted.
//
switch (repair.code) {
case MISPLACED_CODE:
candidate.location = buffer[2];
candidate.symbol = tokStream.getKind(buffer[2]);
tokStream.reset(tokStream.getNext(buffer[2]));
break;
case DELETION_CODE:
candidate.location = buffer[repair.bufferPosition];
candidate.symbol = tokStream.getKind(buffer[repair.bufferPosition]);
tokStream.reset(tokStream.getNext(buffer[repair.bufferPosition]));
break;
default: // SCOPE_CODE || SECONDARY_CODE
candidate.symbol = repair.symbol;
candidate.location = buffer[repair.bufferPosition];
tokStream.reset(buffer[repair.bufferPosition]);
break;
}
return candidate;
}