Fix DefaultErrorStrategy.sync handling of end of rule

This change updates the default sync() strategy to match the strategy used
for selecting an alternative when prediction leaves the decision rule prior
to reaching a syntax error.

Closes #1545
This commit is contained in:
Sam Harwell 2016-12-23 16:23:31 -06:00
parent 7a83cd4910
commit 8b21cc3dfb
8 changed files with 21 additions and 8 deletions

View File

@ -265,7 +265,8 @@ namespace Antlr4.Runtime
ITokenStream tokens = ((ITokenStream)recognizer.InputStream);
int la = tokens.LA(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
if (recognizer.Atn.NextTokens(s).Contains(la) || la == TokenConstants.EOF)
var nextTokens = recognizer.Atn.NextTokens(s);
if (nextTokens.Contains(TokenConstants.EPSILON) || nextTokens.Contains(la))
{
return;
}

View File

@ -100,7 +100,8 @@ void DefaultErrorStrategy::sync(Parser *recognizer) {
size_t la = tokens->LA(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
if (recognizer->getATN().nextTokens(s).contains(la) || la == Token::EOF) {
auto nextTokens = recognizer->getATN().nextTokens(s);
if (nextTokens.contains(Token::EPSILON) || nextTokens.contains(la)) {
return;
}

View File

@ -218,7 +218,8 @@ func (d *DefaultErrorStrategy) Sync(recognizer Parser) {
la := recognizer.GetTokenStream().LA(1)
// try cheaper subset first might get lucky. seems to shave a wee bit off
if la == TokenEOF || recognizer.GetATN().NextTokens(s, nil).contains(la) {
nextTokens := recognizer.GetATN().NextTokens(s, nil)
if nextTokens.contains(TokenEpsilon) || nextTokens.contains(la) {
return
}
// Return but don't end recovery. only do that upon valid token Match

View File

@ -224,7 +224,10 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
int la = tokens.LA(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
if ( recognizer.getATN().nextTokens(s).contains(la) || la==Token.EOF ) return;
IntervalSet nextTokens = recognizer.getATN().nextTokens(s);
if (nextTokens.contains(Token.EPSILON) || nextTokens.contains(la)) {
return;
}
// Return but don't end recovery. only do that upon valid token match
if (recognizer.isExpectedToken(la)) {

View File

@ -223,7 +223,8 @@ DefaultErrorStrategy.prototype.sync = function(recognizer) {
var s = recognizer._interp.atn.states[recognizer.state];
var la = recognizer.getTokenStream().LA(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
if (la===Token.EOF || recognizer.atn.nextTokens(s).contains(la)) {
var nextTokens = recognizer.atn.nextTokens(s);
if (nextTokens.contains(Token.EPSILON) || nextTokens.contains(la)) {
return;
}
// Return but don't end recovery. only do that upon valid token match

View File

@ -202,7 +202,8 @@ class DefaultErrorStrategy(ErrorStrategy):
s = recognizer._interp.atn.states[recognizer.state]
la = recognizer.getTokenStream().LA(1)
# try cheaper subset first; might get lucky. seems to shave a wee bit off
if la==Token.EOF or la in recognizer.atn.nextTokens(s):
nextTokens = recognizer.atn.nextTokens(s)
if Token.EPSILON in nextTokens or la in nextTokens:
return
# Return but don't end recovery. only do that upon valid token match

View File

@ -207,7 +207,8 @@ class DefaultErrorStrategy(ErrorStrategy):
s = recognizer._interp.atn.states[recognizer.state]
la = recognizer.getTokenStream().LA(1)
# try cheaper subset first; might get lucky. seems to shave a wee bit off
if la==Token.EOF or la in recognizer.atn.nextTokens(s):
nextTokens = recognizer.atn.nextTokens(s)
if Token.EPSILON in nextTokens or la in nextTokens:
return
# Return but don't end recovery. only do that upon valid token match

View File

@ -226,7 +226,11 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
// try cheaper subset first; might get lucky. seems to shave a wee bit off
//let set : IntervalSet = recognizer.getATN().nextTokens(s)
if try recognizer.getATN().nextTokens(s).contains(la) || la == CommonToken.EOF {
if try recognizer.getATN().nextTokens(s).contains(CommonToken.EPSILON) {
return
}
if try recognizer.getATN().nextTokens(s).contains(la) {
return
}