diagnoseEntry2 method
void
diagnoseEntry2(
- int marker_kind,
- int error_token
)
Implementation
void diagnoseEntry2(int marker_kind, int error_token) {
var action = IntTuple(1 << 18);
var startTime = currentTimeMillis();
var errorCount = 0;
//
// Compute sequence of actions that leads us to the
// error_token.
//
if (stateStack.isEmpty) {
reallocateStacks();
}
tempStackTop = 0;
tempStack[tempStackTop] = START_STATE;
tokStream.reset();
int current_token, current_kind;
if (marker_kind == 0) {
current_token = tokStream.getToken();
current_kind = tokStream.getKind(current_token);
} else {
current_token = tokStream.peek();
current_kind = marker_kind;
}
parseUpToError(action, current_kind, error_token);
//
// Start parsing
//
stateStackTop = 0;
stateStack[stateStackTop] = START_STATE;
tempStackTop = stateStackTop;
ArrayList.copy(tempStack, 0, stateStack, 0, tempStackTop + 1);
tokStream.reset();
if (marker_kind == 0) {
current_token = tokStream.getToken();
current_kind = tokStream.getKind(current_token);
} else {
current_token = tokStream.peek();
current_kind = marker_kind;
}
locationStack[stateStackTop] = current_token;
//
// Process a terminal
//
int act;
do {
//
// Synchronize state stacks and update the location stack
//
var prev_pos = -1;
prevStackTop = -1;
var next_pos = -1;
nextStackTop = -1;
var pos = stateStackTop;
tempStackTop = stateStackTop - 1;
ArrayList.copy(stateStack, 0, tempStack, 0, stateStackTop + 1);
var action_index = 0;
act = action.get(action_index++); // tAction(act, current_kind);
//
// When a reduce action is encountered, we compute all REDUCE
// and associated goto actions induced by the current token.
// Eventually, a SHIFT, SHIFT-REDUCE, ACCEPT or ERROR action is
// computed...
//
while (act <= NUM_RULES) {
do {
tempStackTop -= (rhs(act) - 1);
act = ntAction(tempStack[tempStackTop], lhs(act));
} while (act <= NUM_RULES);
//
// ... Update the maximum useful position of the
// (STATE_)STACK, push goto state into stack, and
// compute next action on current symbol ...
//
if (tempStackTop + 1 >= stateStack.length) reallocateStacks();
pos = pos < tempStackTop ? pos : tempStackTop;
tempStack[tempStackTop + 1] = act;
act = action.get(action_index++); // tAction(act, current_kind);
}
//
// At this point, we have a shift, shift-reduce, accept or error
// action. STACK contains the configuration of the state stack
// prior to executing any action on current_token. next_stack contains
// the configuration of the state stack after executing all
// reduce actions induced by current_token. The variable pos indicates
// the highest position in STACK that is still useful after the
// reductions are executed.
//
while (act > ERROR_ACTION ||
act < ACCEPT_ACTION) // SHIFT-REDUCE action or SHIFT action ?
{
//
// if the parser needs to stop processing,
// it may do so here.
//
if (monitor != null && monitor!.isCancelled()) {
return;
}
nextStackTop = tempStackTop + 1;
for (var i = next_pos + 1; i <= nextStackTop; i++) {
nextStack[i] = tempStack[i];
}
for (var k = pos + 1; k <= nextStackTop; k++) {
locationStack[k] = locationStack[stateStackTop];
}
//
// If we have a shift-reduce, process it as well as
// the goto-reduce actions that follow it.
//
if (act > ERROR_ACTION) {
act -= ERROR_ACTION;
do {
nextStackTop -= (rhs(act) - 1);
act = ntAction(nextStack[nextStackTop], lhs(act));
} while (act <= NUM_RULES);
pos = pos < nextStackTop ? pos : nextStackTop;
}
if (nextStackTop + 1 >= stateStack.length) reallocateStacks();
tempStackTop = nextStackTop;
nextStack[++nextStackTop] = act;
next_pos = nextStackTop;
//
// Simulate the parser through the next token without
// destroying STACK or next_stack.
//
current_token = tokStream.getToken();
current_kind = tokStream.getKind(current_token);
act = action.get(action_index++); // tAction(act, current_kind);
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 > next_pos
? tempStack[tempStackTop]
: nextStack[tempStackTop]);
act = ntAction(act, lhs_symbol);
} while (act <= NUM_RULES);
//
// ... Update the maximum useful position of the
// (STATE_)STACK, push GOTO state into stack, and
// compute next action on current symbol ...
//
if (tempStackTop + 1 >= stateStack.length) reallocateStacks();
next_pos = next_pos < tempStackTop ? next_pos : tempStackTop;
tempStack[tempStackTop + 1] = act;
act = action.get(action_index++); // tAction(act, current_kind);
}
//
// No error was detected, Read next token into
// PREVTOK element, advance CURRENT_TOKEN pointer and
// update stacks.
//
if (act != ERROR_ACTION) {
prevStackTop = stateStackTop;
for (var i = prev_pos + 1; i <= prevStackTop; i++) {
prevStack[i] = stateStack[i];
}
prev_pos = pos;
stateStackTop = nextStackTop;
for (var k = pos + 1; k <= stateStackTop; k++) {
stateStack[k] = nextStack[k];
}
locationStack[stateStackTop] = current_token;
pos = next_pos;
}
}
//
// At this stage, either we have an ACCEPT or an ERROR
// action.
//
if (act == ERROR_ACTION) {
//
// An error was detected.
//
errorCount += 1;
//
// Check time and error limits after the first error encountered
// Exit if number of errors exceeds maxError or if maxTime reached
//
if (errorCount > 1) {
if (maxErrors > 0 && errorCount > maxErrors) break;
if (maxTime > 0 && currentTimeMillis() - startTime > maxTime) break;
}
var candidate = errorRecovery(current_token);
//
// if the parser needs to stop processing,
// it may do so here.
//
if (monitor != null && monitor!.isCancelled()) return;
act = stateStack[stateStackTop];
//
// If the recovery was successful on a nonterminal candidate,
// parse through that candidate and "read" the next token.
//
if (candidate.symbol == 0) {
break;
} else if (candidate.symbol > NT_OFFSET) {
var lhs_symbol = candidate.symbol - NT_OFFSET;
act = ntAction(act, lhs_symbol);
while (act <= NUM_RULES) {
stateStackTop -= (rhs(act) - 1);
act = ntAction(stateStack[stateStackTop], lhs(act));
}
stateStack[++stateStackTop] = act;
current_token = tokStream.getToken();
current_kind = tokStream.getKind(current_token);
locationStack[stateStackTop] = current_token;
} else {
current_kind = candidate.symbol;
locationStack[stateStackTop] = candidate.location;
}
//
// At this stage, we have a recovery configuration. See how
// far we can go with it.
//
var next_token = tokStream.peek();
tempStackTop = stateStackTop;
ArrayList.copy(stateStack, 0, tempStack, 0, stateStackTop + 1);
error_token = parseForError(current_kind);
//
// If an error was found, compute the sequence of actions that reaches
// the error token. Otherwise, claim victory...
//
if (error_token != 0) {
tokStream.reset(next_token);
tempStackTop = stateStackTop;
ArrayList.copy(stateStack, 0, tempStack, 0, stateStackTop + 1);
parseUpToError(action, current_kind, error_token);
tokStream.reset(next_token);
} else {
act = ACCEPT_ACTION;
}
}
} while (act != ACCEPT_ACTION);
return;
}