checkPrimaryDistance method
Implementation
void checkPrimaryDistance(
PrimaryRepairInfo repair, List<int> stck, int stack_top) {
//
// First, try scope recovery.
//
var scope_repair = PrimaryRepairInfo(repair);
scopeTrial(scope_repair, stck, stack_top);
if (scope_repair.distance > repair.distance) repair.copy(scope_repair);
//
// Next, try merging the error token with its successor.
//
var symbol = mergeCandidate(stck[stack_top], repair.bufferPosition);
if (symbol != 0) {
var j = parseCheck(stck, stack_top, symbol, repair.bufferPosition + 2);
if ((j > repair.distance) ||
(j == repair.distance && repair.misspellIndex < 10)) {
repair.misspellIndex = 10;
repair.symbol = symbol;
repair.distance = j;
repair.code = MERGE_CODE;
}
}
//
// Next, try deletion of the error token.
//
var j = parseCheck(
stck,
stack_top,
tokStream.getKind(buffer[repair.bufferPosition + 1]),
repair.bufferPosition + 2);
var k = (tokStream.getKind(buffer[repair.bufferPosition]) == EOLT_SYMBOL &&
tokStream.afterEol(buffer[repair.bufferPosition + 1])
? 10
: 0);
if (j > repair.distance ||
(j == repair.distance && k > repair.misspellIndex)) {
repair.misspellIndex = k;
repair.code = DELETION_CODE;
repair.distance = j;
}
//
// Update the error configuration by simulating all reduce and
// goto actions induced by the error token. Then assign the top
// most state of the new configuration to next_state.
//
var next_state = stck[stack_top], max_pos = stack_top;
tempStackTop = stack_top - 1;
tokStream.reset(buffer[repair.bufferPosition + 1]);
var tok = tokStream.getKind(buffer[repair.bufferPosition]),
act = tAction(next_state, tok);
while (act <= NUM_RULES) {
do {
var lhs_symbol = lhs(act);
tempStackTop -= (rhs(act) - 1);
act = (tempStackTop > max_pos
? tempStack[tempStackTop]
: stck[tempStackTop]);
act = ntAction(act, lhs_symbol);
} while (act <= NUM_RULES);
max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
tempStack[tempStackTop + 1] = act;
next_state = act;
act = tAction(next_state, tok);
}
//
// Next, place the list of candidates in proper order.
//
var root = 0;
for (var i = asi(next_state); asr(i) != 0; i++) {
symbol = asr(i);
if (symbol != EOFT_SYMBOL && symbol != ERROR_SYMBOL) {
if (root == 0) {
list[symbol] = symbol;
} else {
list[symbol] = list[root];
list[root] = symbol;
}
root = symbol;
}
}
if (stck[stack_top] != next_state) {
for (var i = asi(stck[stack_top]); asr(i) != 0; i++) {
symbol = asr(i);
if (symbol != EOFT_SYMBOL &&
symbol != ERROR_SYMBOL &&
list[symbol] == 0) {
if (root == 0) {
list[symbol] = symbol;
} else {
list[symbol] = list[root];
list[root] = symbol;
}
root = symbol;
}
}
}
var head = list[root];
list[root] = 0;
root = head;
//
// Next, try insertion for each possible candidate available in
// the current state, except EOFT and ERROR_SYMBOL.
//
symbol = root;
while (symbol != 0) {
var m = parseCheck(stck, stack_top, symbol, repair.bufferPosition),
n = (symbol == EOLT_SYMBOL &&
tokStream.afterEol(buffer[repair.bufferPosition])
? 10
: 0);
if (m > repair.distance ||
(m == repair.distance && n > repair.misspellIndex)) {
repair.misspellIndex = n;
repair.distance = m;
repair.symbol = symbol;
repair.code = INSERTION_CODE;
}
symbol = list[symbol];
}
//
// Next, Try substitution for each possible candidate available
// in the current state, except EOFT and ERROR_SYMBOL.
//
symbol = root;
while (symbol != 0) {
var m = parseCheck(stck, stack_top, symbol, repair.bufferPosition + 1),
n = (symbol == EOLT_SYMBOL &&
tokStream.afterEol(buffer[repair.bufferPosition + 1])
? 10
: misspell(symbol, buffer[repair.bufferPosition]));
if (m > repair.distance ||
(m == repair.distance && n > repair.misspellIndex)) {
repair.misspellIndex = n;
repair.distance = m;
repair.symbol = symbol;
repair.code = SUBSTITUTION_CODE;
}
var s = symbol;
symbol = list[symbol];
list[s] = 0; // reset element
}
//
// Next, we try to insert a nonterminal candidate in front of the
// error token, or substituting a nonterminal candidate for the
// error token. Precedence is given to insertion.
//
for (var nt_index = nasi(stck[stack_top]);
nasr(nt_index) != 0;
nt_index++) {
symbol = nasr(nt_index) + NT_OFFSET;
var n = parseCheck(stck, stack_top, symbol, repair.bufferPosition + 1);
if (n > repair.distance) {
repair.misspellIndex = 0;
repair.distance = n;
repair.symbol = symbol;
repair.code = INVALID_CODE;
}
n = parseCheck(stck, stack_top, symbol, repair.bufferPosition);
if (n > repair.distance ||
(n == repair.distance && repair.code == INVALID_CODE)) {
repair.misspellIndex = 0;
repair.distance = n;
repair.symbol = symbol;
repair.code = INSERTION_CODE;
}
}
return;
}