Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix multiple problems with optional block bypass at end of rule #1546

Merged
merged 5 commits into from
Dec 28, 2016

Conversation

sharwell
Copy link
Member

  • Add tests for scenarios presented in the original bug
  • Fix DefaultErrorStrategy.sync not handling falling off decision rule the same way as adaptivePredict
  • Fix code generation for LL1OptionalBlock

Fixes #1545

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 antlr#1545
@@ -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) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ This is sub-optimal but should work fine. Someone familiar with the Swift syntax should reply with a comment indicating how to cache the result of nextTokens in a local variable like I've done for each of the other targets.

@parrt
Copy link
Member

parrt commented Dec 24, 2016

@sharwell looks like some tests are failing. I'll try to look soon.

@@ -414,7 +414,7 @@

/**
grammar T;
a : 'a' 'b'* ;
a : 'a' 'b'* EOF ;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 The original behavior of the test was retained by ensuring the 'b'* loop didn't look all the way to the end of a.

@@ -436,7 +436,7 @@

/**
grammar T;
a : 'a' ('b'|'z'{<Pass()>})*;
a : 'a' ('b'|'z'{<Pass()>})* EOF ;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 The original behavior of the test was retained by ensuring the closure loop didn't look all the way to the end of a.

@@ -135,7 +135,7 @@
public static class InvalidEmptyInput extends BaseParserTestDescriptor {
public String input = "";
public String output = null;
public String errors = "line 1:0 missing ID at '<EOF>'\n";
public String errors = "line 1:0 mismatched input '<EOF>' expecting ID\n";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@parrt This behavior change was caused by removing the la == TokenConstants.EOF check in DefaultErrorStrategy.sync. Do you have a preference regarding the handling?

We know by the time this check was reached that neither EPSILON nor the LL(1)
symbol are in the lookahead set from the current state. Since EPSILON is not
included, the state cannot see to the end of the rule and thus nextTokens
contains the complete set of valid LL(1) symbols from the current state. It is
therefore impossible for the LL(1) symbol to be "expected" when considering
lookahead with full context.
@parrt
Copy link
Member

parrt commented Dec 28, 2016

Thanks @sharwell !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants