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

javascript parser fails too early on incomplete statement in function body #3727

Open
meraedit opened this issue Sep 25, 2023 · 6 comments
Open

Comments

@meraedit
Copy link
Contributor

For
function onAction (event) { event. }

The parser (generated for the Javascript grammar) reports 3 syntax errors instead of 1:
Pb#SYNTAX_ERROR 0[33..34]:no viable alternative at input 'function onAction(event) { event.}'
Pb#SYNTAX_ERROR 0[25..26]:no viable alternative at input '{'
Pb#SYNTAX_ERROR 0[33..34]:mismatched input '}' expecting {'#', 'null', BooleanLiteral, 'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while', 'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'as', 'from', 'of', 'class', 'enum', 'extends', 'super', 'const', 'export', 'import', 'async', 'await', 'yield', 'implements', StrictLet, NonStrictLet, 'private', 'public', 'interface', 'package', 'protected', 'static', Identifier}
I think it should report only the last one.
It doesn't recognize the function declaration, although up to the { the code is correct and it could recognize that we have a function declaration and a function body.

Not sure how to change the sync/recover methods of the ErrorStrategy, or how can this issue be fixed.

@kaby76
Copy link
Contributor

kaby76 commented Sep 26, 2023

For all targets of the javascript/javascript/ grammar that have been ported (CSharp, Go, Java, JavaScript, Python3, and just now after updating Cpp locally), I get only one message. I use the default error strategy. The code is generated using trgen, with Antlr 4.13.1.

$ bash run.sh x
line 1:35 mismatched input '}' expecting {'#', 'null', BooleanLiteral, 'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while', 'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'as', 'from', 'class', 'enum', 'extends', 'super', 'const', 'export', 'import', 'async', 'await', 'yield', 'implements', StrictLet, NonStrictLet, 'private', 'public', 'interface', 'package', 'protected', 'static', Identifier}
Cpp 0 x fail 0.012024
Total Time: 0.015235
09/26-06:17:31 ~/issues/g4-3728/javascript/javascript/Generated-Cpp
$ cat x
function onAction (event) { event. }09/26-06:17:40 ~/issues/g4-3728/javascript/javascript/Generated-Cpp
$

Even the old tester outputs only one message. That uses Antlr 4.11.1.

09/26-06:22:04 ~/issues/g4-3728/javascript/javascript
$ mvn clean test
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< org.antlr.grammars:javascript >--------------------
[INFO] Building JavaScript grammar 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ javascript ---
[INFO] Deleting C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\target
[INFO]
[INFO] --- antlr4-maven-plugin:4.11.1:antlr4 (default) @ javascript ---
[INFO] ANTLR 4: Processing source directory C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript
[INFO] Processing grammar: JavaScriptLexer.g4
[INFO] Processing grammar: JavaScriptParser.g4
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ javascript ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.11.0:compile (default-compile) @ javascript ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 8 source files with javac [debug target 11] to target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ javascript ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.11.0:testCompile (default-testCompile) @ javascript ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ javascript ---
[INFO] No tests to run.
[INFO]
[INFO] --- antlr4test-maven-plugin:1.22:test (default) @ javascript ---
[INFO] Evaluating Scenario: Default Scenario
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\ArrowFunctions.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\AsyncAwait.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\Classes.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\ClassInNonGlobalStrict.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\Constants.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\DestructuringAssignment.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\EnhancedObjectProperties.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\EnhancedRegularExpression.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\Export.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\ExtendedLiterals.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\ExtendedParameterHandling.js
[INFO] Parsing :C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\foobar.js
line 1:35 mismatched input '}' expecting {'#', 'null', BooleanLiteral, 'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while', 'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'as', 'from', 'class', 'enum', 'extends', 'super', 'const', 'export', 'import', 'async', 'await', 'yield', 'implements', StrictLet, NonStrictLet, 'private', 'public', 'interface', 'package', 'protected', 'static', Identifier}
com.khubla.antlr.antlr4test.AssertErrorsException: found 1 errors, but missing file foobar.js.errors
        at com.khubla.antlr.antlr4test.AssertErrorsErrorListener.assertErrors(AssertErrorsErrorListener.java:64)
        at com.khubla.antlr.antlr4test.ScenarioExecutor.testGrammar(ScenarioExecutor.java:174)
        at com.khubla.antlr.antlr4test.ScenarioExecutor.testGrammars(ScenarioExecutor.java:229)
        at com.khubla.antlr.antlr4test.GrammarTestMojo.testScenarios(GrammarTestMojo.java:360)
        at com.khubla.antlr.antlr4test.GrammarTestMojo.execute(GrammarTestMojo.java:179)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute(MojoExecutor.java:301)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:211)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:165)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:157)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:121)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:127)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:294)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:960)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:293)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:196)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
Caused by: java.io.FileNotFoundException: C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\foobar.js.errors (The system cannot find the file specified)
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
        at com.khubla.antlr.antlr4test.FileUtil.getNonEmptyLines(FileUtil.java:91)
        at com.khubla.antlr.antlr4test.AssertErrorsErrorListener.assertErrors(AssertErrorsErrorListener.java:62)
        ... 27 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.312 s
[INFO] Finished at: 2023-09-26T06:22:28-04:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.khubla.antlr:antlr4test-maven-plugin:1.22:test (default) on project javascript: Unable execute mojo: found 1 errors, but missing file foobar.js.errors: C:\msys64\home\Kenne\issues\g4-3728\javascript\javascript\examples\foobar.js.errors (The system cannot find the file specified) -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
09/26-06:22:28 ~/issues/g4-3728/javascript/javascript
$

What Antlr4 version and target are you using?

@meraedit
Copy link
Contributor Author

meraedit commented Sep 27, 2023

We are using Antlr 4.12.0
For the master branch (javascript/javascript/ grammar) it works correctly, so it detects 1 error, the mismatched input '}'.

But for 4.12.0 or 4.13.0 it detects 3 errors for function onAction (event) { event. }
and it shows some warnings when running mvn clean test:
ANTLR Tool version 4.12.0 used for code generation does not match the current runtime version 4.11.1
ANTLR Runtime version 4.12.0 used for parser compilation does not match the current runtime version 4.11.1
ANTLR Tool version 4.12.0 used for code generation does not match the current runtime version 4.11.1
ANTLR Runtime version 4.12.0 used for parser compilation does not match the current runtime version 4.11.1

So it looks like master is also using antlr 4.11.1?
2da46b1#diff-9c5fb3d1b7e3b0f54bc5c4182965c4fe1f9023d449017cece3005d3f90e8e4d8R19
However, if I change the antlr version in the pom.xml to 4.13.0 on master, then it works correctly even though it shows those warnings about 4.11.1...

@kaby76
Copy link
Contributor

kaby76 commented Sep 27, 2023

The Antlr Maven tester--which is obsolete--sets the version that the code is compiled against. For version 1.22 of the plugin, the runtime is 4.11.1. Separately, the tool version is specified in the top-level pom.xml. It should be the value that the tester runtime uses, 4.11.1. These values should not be updated unless there are releases of both the tool and the tester so that version skews cannot occur.

Yes, we have new version of the Antlr tool, but the tester is still stuck at 4.11.1. There is an Issue asking for a new version, but that was a while ago. And, it hasn't been published since last year. The problem is that the testers are compiled against a specific version of Antlr. Instead, tools like these should use dynamic loads and calls, so any version of the Antlr .jar can be used.

Instead, I suggest using trgen. Attached is a .zip file with a driver for Linux. Generated-Java.zip. I modified the "build.sh" file in the generated code to use 4.12.0 instead, and I still only get one error message, the same as with other versions.

(Note, there's a version required for the grammar in the desc.xml, but I added it because of the Go target, which only started working with 4.13.0, and it is only informational at this point. The grammar should work for other versions of Antlr.)

@meraedit
Copy link
Contributor Author

This seems to be fixed by #3387
The errors are back as soon as I add the functionDeclaration to the anonymousFunction rule

anonymousFunction
    : functionDeclaration 

@meraedit
Copy link
Contributor Author

meraedit commented Nov 3, 2023

This problem is back if we add an optional identifier to the anonymous function production in order to support function expressions like examples/FunctionExpression.js

var x = (function test(){})()

So the anonymousFunction becomes:

anonymousFunction
    : Async? Function_ '*'? identifier? '(' formalParameterList? ')' functionBody    # AnonymousFunctionDecl

Then the weird thing is that a function declaration with one error in the function body (see examples/FunctionDeclaration.js) is not parsed as a function declaration and it has 3 errors instead of 1.

Could it be that the recovery algorithm doesn't work well because the grammar is now ambiguous?
Is there a way to fix this problem in the grammar?

@meraedit meraedit reopened this Nov 3, 2023
@kaby76
Copy link
Contributor

kaby76 commented Nov 3, 2023

I was thinking the same thing, that the recovery does not work well with ambiguous grammars. But, then, I checked parsing for function onAction (event) { } and there is no ambiguity detected. The parse tree for that is:


( program
  ( sourceElements
    ( sourceElement
      ( statement
        ( functionDeclaration
          ( Function_
            (  text:'function' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) 
          ( identifier
            ( Attribute Before Value ' ' chnl:HIDDEN
            ) 
            ( Identifier
              (  text:'onAction' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) ) 
          ( Attribute Before Value ' ' chnl:HIDDEN
          ) 
          ( OpenParen
            (  text:'(' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) 
          ( formalParameterList
            ( formalParameterArg
              ( assignable
                ( identifier
                  ( Identifier
                    (  text:'event' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) ) ) ) ) 
          ( CloseParen
            (  text:')' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) 
          ( functionBody
            ( Attribute Before Value ' ' chnl:HIDDEN
            ) 
            ( OpenBrace
              (  text:'{' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
            ) ) 
            ( Attribute Before Value '  ' chnl:HIDDEN
            ) 
            ( CloseBrace
              (  text:'}' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
  ) ) ) ) ) ) ) 
  ( EOF
    (  text:'' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
) ) ) 

For a syntactically valid functionBody example, consider function onAction (event) { event.sdf; }. The parse tree would be:


( program
  ( sourceElements
    ( sourceElement
      ( statement
        ( functionDeclaration
          ( Function_
            (  text:'function' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) 
          ( identifier
            ( Attribute Before Value ' ' chnl:HIDDEN
            ) 
            ( Identifier
              (  text:'onAction' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) ) 
          ( Attribute Before Value ' ' chnl:HIDDEN
          ) 
          ( OpenParen
            (  text:'(' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) 
          ( formalParameterList
            ( formalParameterArg
              ( assignable
                ( identifier
                  ( Identifier
                    (  text:'event' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) ) ) ) ) 
          ( CloseParen
            (  text:')' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
          ) ) 
          ( functionBody
            ( Attribute Before Value ' ' chnl:HIDDEN
            ) 
            ( OpenBrace
              (  text:'{' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
            ) ) 
            ( sourceElements
              ( sourceElement
                ( statement
                  ( expressionStatement
                    ( expressionSequence
                      ( singleExpression
                        ( singleExpression
                          ( identifier
                            ( Attribute Before Value ' ' chnl:HIDDEN
                            ) 
                            ( Identifier
                              (  text:'event' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
                        ) ) ) ) 
                        ( Dot
                          (  text:'.' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
                        ) ) 
                        ( identifierName
                          ( identifier
                            ( Identifier
                              (  text:'sdf' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
                    ) ) ) ) ) ) 
                    ( eos
                      ( SemiColon
                        (  text:';' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
            ) ) ) ) ) ) ) 
            ( Attribute Before Value ' ' chnl:HIDDEN
            ) 
            ( CloseBrace
              (  text:'}' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
  ) ) ) ) ) ) ) 
  ( EOF
    (  text:'' tt:0 chnl:DEFAULT_TOKEN_CHANNEL
) ) ) 

For sure, it feels that there is something wrong with the error recovery, but I haven't had enough debug time on the problem to figure out what it is doing exactly.

Here is an analysis starting with the first SyntaxError() called.

line 1:35 no viable alternative at input 'function onAction (event) { event. }'

>	Test.dll!ErrorListener<Antlr4.Runtime.IToken>.SyntaxError(System.IO.TextWriter output, Antlr4.Runtime.IRecognizer recognizer, Antlr4.Runtime.IToken offendingSymbol, int line, int col, string msg, Antlr4.Runtime.RecognitionException e) Line 31	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.ProxyErrorListener<Antlr4.Runtime.IToken>.SyntaxError(System.IO.TextWriter output, Antlr4.Runtime.IRecognizer recognizer, Antlr4.Runtime.IToken offendingSymbol, int line, int charPositionInLine, string msg, Antlr4.Runtime.RecognitionException e) Line 43	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.Parser.NotifyErrorListeners(Antlr4.Runtime.IToken offendingToken, string msg, Antlr4.Runtime.RecognitionException e) Line 688	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.NotifyErrorListeners(Antlr4.Runtime.Parser recognizer, string message, Antlr4.Runtime.RecognitionException e) Line 187	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.ReportNoViableAlternative(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.NoViableAltException e) Line 364	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.ReportError(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 162	C#
 	Test.dll!JavaScriptParser.statement() Line 547	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

Recover() is called, with the error state is 202 and current token is "function".
The followSet is {{<EOF>, 4..5, 7, 9, 12, 20..25, 61..73, 75, 78..79, 82..91, 93..95, 97..101, 104..110, 112..113, 120..122}}.

>	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.Recover(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 197	C#
 	Test.dll!JavaScriptParser.statement() Line 548	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

After Recover(), the current token is "function".

Recover() is called a second time.

>	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.Recover(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 197	C#
 	Test.dll!JavaScriptParser.statement() Line 548	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

After Recover(), we are now on "onAction".

SyntaxError() is called a second time.

line 1:26 no viable alternative at input '{'

>	Test.dll!ErrorListener<Antlr4.Runtime.IToken>.SyntaxError(System.IO.TextWriter output, Antlr4.Runtime.IRecognizer recognizer, Antlr4.Runtime.IToken offendingSymbol, int line, int col, string msg, Antlr4.Runtime.RecognitionException e) Line 31	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.ProxyErrorListener<Antlr4.Runtime.IToken>.SyntaxError(System.IO.TextWriter output, Antlr4.Runtime.IRecognizer recognizer, Antlr4.Runtime.IToken offendingSymbol, int line, int charPositionInLine, string msg, Antlr4.Runtime.RecognitionException e) Line 43	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.Parser.NotifyErrorListeners(Antlr4.Runtime.IToken offendingToken, string msg, Antlr4.Runtime.RecognitionException e) Line 688	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.NotifyErrorListeners(Antlr4.Runtime.Parser recognizer, string message, Antlr4.Runtime.RecognitionException e) Line 187	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.ReportNoViableAlternative(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.NoViableAltException e) Line 364	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.ReportError(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 162	C#
 	Test.dll!JavaScriptParser.expressionSequence() Line 6127	C#
 	Test.dll!JavaScriptParser.expressionStatement() Line 2407	C#
 	Test.dll!JavaScriptParser.statement() Line 456	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

The current token is "{".

Recover() is called with the error state 778 and current token is "function".
The followSet is {{<EOF>, 4..5, 7, 9, 12, 20..25, 61..73, 75, 78..79, 82..91, 93..95, 97..101, 104..110, 112..113, 120..122}}.
At the end of Recover(), we are still at token '{'.

Recover() is called a second time.

>	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.Recover(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 197	C#
 	Test.dll!JavaScriptParser.eos() Line 9930	C#
 	Test.dll!JavaScriptParser.expressionStatement() Line 2409	C#
 	Test.dll!JavaScriptParser.statement() Line 456	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

We are in state 1093. Afterwards, the current token is still '{'.

Recover() is called a third time.

>	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.Recover(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 197	C#
 	Test.dll!JavaScriptParser.statement() Line 548	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

Current state is 202. After, the current token is still '{'.

Recover() is called a fourth time.

>	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.Recover(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 197	C#
 	Test.dll!JavaScriptParser.statement() Line 548	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

The error state is now 202. Notably, the routine now Consume()'s one token, and we are now on "event".

line 1:35 mismatched input '}' expecting {'#', 'null', BooleanLiteral, 'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while', 'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'as', 'from', 'of', 'class', 'enum', 'extends', 'super', 'const', 'export', 'import', 'async', 'await', 'yield', 'implements', StrictLet, NonStrictLet, 'private', 'public', 'interface', 'package', 'protected', 'static', Identifier}

>	Test.dll!ErrorListener<Antlr4.Runtime.IToken>.SyntaxError(System.IO.TextWriter output, Antlr4.Runtime.IRecognizer recognizer, Antlr4.Runtime.IToken offendingSymbol, int line, int col, string msg, Antlr4.Runtime.RecognitionException e) Line 31	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.ProxyErrorListener<Antlr4.Runtime.IToken>.SyntaxError(System.IO.TextWriter output, Antlr4.Runtime.IRecognizer recognizer, Antlr4.Runtime.IToken offendingSymbol, int line, int charPositionInLine, string msg, Antlr4.Runtime.RecognitionException e) Line 43	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.Parser.NotifyErrorListeners(Antlr4.Runtime.IToken offendingToken, string msg, Antlr4.Runtime.RecognitionException e) Line 688	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.NotifyErrorListeners(Antlr4.Runtime.Parser recognizer, string message, Antlr4.Runtime.RecognitionException e) Line 187	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.ReportInputMismatch(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.InputMismatchException e) Line 380	C#
 	Antlr4.Runtime.Standard.dll!Antlr4.Runtime.DefaultErrorStrategy.ReportError(Antlr4.Runtime.Parser recognizer, Antlr4.Runtime.RecognitionException e) Line 168	C#
 	Test.dll!JavaScriptParser.singleExpression(int _p) Line 7995	C#
 	Test.dll!JavaScriptParser.expressionSequence() Line 6104	C#
 	Test.dll!JavaScriptParser.expressionStatement() Line 2407	C#
 	Test.dll!JavaScriptParser.statement() Line 456	C#
 	Test.dll!JavaScriptParser.sourceElement() Line 297	C#
 	Test.dll!JavaScriptParser.sourceElements() Line 5149	C#
 	Test.dll!JavaScriptParser.program() Line 243	C#
 	Test.dll!Program.DoParse(Antlr4.Runtime.ICharStream str, string input_name, int row_number) Line 268	C#
 	Test.dll!Program.ParseFilename(string input, int row_number) Line 224	C#
 	Test.dll!Program.Main(string[] args) Line 186	C#

We are now on token "}", state 911, and call Recover(), which finally moves past the problem.

Analysis

AdaptivePredict() flags an error while trying to figure out which alt of statement to choose. There is none, so it consumes a token from the beginning of the string function onAction (event) { event. }, to derive onAction (event) { event. }. But, that is still invalid. The problem is that the error is located far from the current token: a choice cannot be made with when considering a statement that begins with "function".

The error recovery only consumes input until it arrives at a token that is valid for a state that has the error. This not a minimal error correction strategy.

There is another possible problem here in that AdaptivePredict() should have just chosen the functionDeclaration because that is the only possible alt that could be chosen at input token "function". I can only be sure of that if I debug AdaptivePredict() and see all possible ATNConfigs.

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

No branches or pull requests

3 participants