Internal parsing error: java.lang.IllegalStateException: Unkown node type (recovery failed)
JSGLR fails to parse certain files of my C11 grammar with the error “Internal parsing error: java.lang.IllegalStateException: Unkown node type (recovery failed)”.
For example the following file produces this error:
void p1 (p) int *p; {}
Note that there is no space after the semicolon. If a space is added after the semicolon the error disappears. Actually the error appears when there are 0 or an even number of spaces behind the semicolon. An uneven number of spaces does not produce the error.
The syntax can be found here: https://github.com/metaborg/metaborg-c/tree/c11-tmpl-syntax/syntax.
The stacktrace of the exception is:
Submitted by Gabriël Konat on 9 August 2013 at 19:13java.lang.IllegalStateException: Unkown node type at org.spoofax.jsglr.client.imploder.TreeBuilder.buildTreeAmb(TreeBuilder.java:421) at org.spoofax.jsglr.client.imploder.TreeBuilder.buildTreeAmb(TreeBuilder.java:415) at org.spoofax.jsglr.client.ParseNode.toTreeTopdown(ParseNode.java:308) at org.spoofax.jsglr.client.imploder.TreeBuilder.buildTreeNode(TreeBuilder.java:304) at org.spoofax.jsglr.client.ParseNode.toTreeTopdown(ParseNode.java:309) at org.spoofax.jsglr.client.imploder.TreeBuilder.buildTreeNode(TreeBuilder.java:279) at org.spoofax.jsglr.client.ParseNode.toTreeTopdown(ParseNode.java:309) at org.spoofax.jsglr.client.imploder.TreeBuilder.buildTreeNode(TreeBuilder.java:304) at org.spoofax.jsglr.client.ParseNode.toTreeTopdown(ParseNode.java:309) at org.spoofax.jsglr.client.imploder.TreeBuilder.buildTreeNode(TreeBuilder.java:304) at org.spoofax.jsglr.client.imploder.TopdownTreeBuilder.buildTree(TopdownTreeBuilder.java:28) at org.spoofax.jsglr.client.imploder.TreeBuilder.buildTree(TreeBuilder.java:161) at org.spoofax.jsglr.client.Disambiguator.yieldTree(Disambiguator.java:338) at org.spoofax.jsglr.client.Disambiguator.yieldTreeTop(Disambiguator.java:351) at org.spoofax.jsglr.client.Disambiguator.applyFilters(Disambiguator.java:291) at org.spoofax.jsglr.client.Disambiguator.applyFilters(Disambiguator.java:255) at org.spoofax.jsglr.client.SGLR.sglrParse(SGLR.java:614) at org.spoofax.jsglr.client.SGLR.parse(SGLR.java:538) at org.spoofax.jsglr.client.SGLR.parse(SGLR.java:325) at org.strategoxt.imp.runtime.parser.JSGLRI.doParse(JSGLRI.java:170) at org.strategoxt.imp.runtime.parser.AbstractSGLRI.parse(AbstractSGLRI.java:113) at org.strategoxt.imp.runtime.parser.SGLRParseController.doParse(SGLRParseController.java:370) at org.strategoxt.imp.runtime.parser.SGLRParseController.parse(SGLRParseController.java:298) at org.strategoxt.imp.runtime.parser.SGLRParseController.parse(SGLRParseController.java:1) at org.strategoxt.imp.runtime.dynamicloading.DynamicParseController.parse(DynamicParseController.java:205) at org.eclipse.imp.editor.ParserScheduler.run(ParserScheduler.java:86) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
Issue Log
Just ran the same file through the parser in Spoofax stable (1.1) and the error does not show up. An ambiguity is shown instead with 0 or even number of spaces:
TranslationUnit( [ amb( [ amb( [ FuncDef( [Void(), TypedefName("p1")] , Declarator(None(), Declarator(None(), "p")) , [Decl( [Int()] , [Declarator(Some(Ptr([])), "p")] )] , Block([]) ) , FuncDef( [Void()] , Declarator(None(), FuncDeclarator("p1", ParamList(["p"]))) , [Decl( [Int()] , [Declarator(Some(Ptr([])), "p")] )] , Block([]) ) ] ) , FuncDef( [Void()] , Declarator(None(), FuncDeclarator("p1", ParamList(["p"]))) , [Decl( [Int()] , [Declarator(Some(Ptr([])), "p")] )] , Block([]) ) ] ) ] )
and no ambiguity with an uneven number of spaces:
TranslationUnit( [ FuncDef( [Void()] , Declarator(None(), FuncDeclarator("p1", ParamList(["p"]))) , [Decl( [Int()] , [Declarator(Some(Ptr([])), "p")] )] , Block([]) ) ] )
That is probably an error in my grammar, but it should still report the ambiguity instead of throwing an exception.
Exactly the part of the TreeBuilder which deals with ambiguities was re-written 2013/02/09.
My hunch is that the nested ambiguity does not have a node type or it has an unhandled case in the node-type. Particularly the case of the avoid and prefer appears to not be handled.
Indeed, adding
case AbstractParseNode.PREFER: subtree = buildTreeNode((ParseNode) subnode); break; case AbstractParseNode.AVOID: subtree = buildTreeNode((ParseNode) subnode); break;
to the switch gets rid of the exception and produces ambiguities, although I don’t know if this is correct behaviour. Should it already try to disambiguate using prefer/avoids at this point? I always thought that disambiguation using prefer/avoid was performed after parsing, but the presence of prefer and avoid nodes in the parser makes me believe otherwise. Can the writer of this code clarify?
The switch was introduced by Sebastian at https://github.com/metaborg/jsglr/commit/5e6aa4997996bc99cc3c91a67755fb261497bd5c#L40R367 and then modified by Maartje to throw in the default case at https://github.com/metaborg/jsglr/commit/4e353450512bd66e7e93f931e29888a3382240f9#L0R388.
As far as I remember, I did a simple inline-refactoring of AbstractParseNode.toTreeTopdown(this)
Problem seems to be fixed by https://github.com/metaborg/jsglr/commit/ca778c4b61d49311f8727edfef71c4a62b37d39f (fixed as in behaves the same as in Spoofax 1.1), although I’m not sure if this is a proper fix. It does report the ambiguity now instead of throwing an exception.
Log in to post comments