fix #3042 in JavaScript runtime

This commit is contained in:
Eric Vergnaud 2021-01-23 17:32:06 +08:00
parent a9f11612dd
commit 329f1301ea
2 changed files with 26 additions and 14 deletions

View File

@ -128,17 +128,17 @@ class LL1Analyzer {
return;
}
if (ctx !== PredictionContext.EMPTY) {
// run thru all possible stack tops in ctx
for(let i=0; i<ctx.length; i++) {
const returnState = this.atn.states[ctx.getReturnState(i)];
const removed = calledRuleStack.contains(returnState.ruleIndex);
try {
calledRuleStack.remove(returnState.ruleIndex);
const removed = calledRuleStack.contains(s.ruleIndex);
try {
calledRuleStack.remove(s.ruleIndex);
// run thru all possible stack tops in ctx
for (let i = 0; i < ctx.length; i++) {
const returnState = this.atn.states[ctx.getReturnState(i)];
this._LOOK(returnState, stopState, ctx.getParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
} finally {
if (removed) {
calledRuleStack.add(returnState.ruleIndex);
}
}
}finally {
if (removed) {
calledRuleStack.add(s.ruleIndex);
}
}
return;

View File

@ -55,6 +55,8 @@ class DefaultErrorStrategy extends ErrorStrategy {
*/
this.lastErrorIndex = -1;
this.lastErrorStates = null;
this.nextTokensContext = null;
this.nextTokenState = 0;
}
/**
@ -216,11 +218,21 @@ class DefaultErrorStrategy extends ErrorStrategy {
if (this.inErrorRecoveryMode(recognizer)) {
return;
}
const s = recognizer._interp.atn.states[recognizer.state]
const la = recognizer.getTokenStream().LA(1)
const s = recognizer._interp.atn.states[recognizer.state];
const la = recognizer.getTokenStream().LA(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
const nextTokens = recognizer.atn.nextTokens(s)
if (nextTokens.contains(Token.EPSILON) || nextTokens.contains(la)) {
const nextTokens = recognizer.atn.nextTokens(s);
if(nextTokens.contains(la)) {
this.nextTokensContext = null;
this.nextTokenState = ATNState.INVALID_STATE_NUMBER;
return;
} else if (nextTokens.contains(Token.EPSILON)) {
if(self.nextTokensContext === null) {
// It's possible the next token won't match information tracked
// by sync is restricted for performance.
this.nextTokensContext = recognizer._ctx;
this.nextTokensState = recognizer._stateNumber;
}
return;
}
switch (s.stateType) {