JSGLR imploder yields wrong AST for mixed syntax with meta list variables
The Java-based SGLR imploder (used in JSGLRv1) does not build the correct AST for list variables (where the variable name ends with an asterisk) in mixed syntax (such as in Stratego-Java-15).
Reproduce
Parsing:
module foo rules bar: _ -> |[ x_name.bar(e_bla*) ]| with x_name := "a" ; e_bla* := [1]
produces the AST:
ToMetaExpr( Invoke( Method(MethodName(AmbName(Id(meta-var("x_name"))), Id("bar"))) , [] ) )
whereas the expected output is:
ToMetaExpr( Invoke( Method(MethodName(AmbName(Id(meta-var("x_name"))), Id("bar"))) , meta-listvar("e_bla*") ) )
Note that the AST contains an empty list at line 4 instead of the meta-listvar term. This problem occurs when you parse the file from within Spoofax (Spoofax > Show Abstract Syntax) or when you parse programmatically (using Spoofax Core API). The strj compiler does not suffer from this problem; it looks like strj uses a different (Stratego-based) imploder. This also means that for the following example the Spoofax editor will show an “unresolved variable” error on the use of
e_arg*
but the project will build without a problem:java-to-gm-statement: java |[ x_method(e_arg*); ]| -> gm |[ x_method(e_arg'*); ]| with e_arg'* := <map(java-to-gm-expression)> e_arg*
Similarly, the following program contains unresolved variables, but no error shows up:
java-to-gm-statement: java |[ x_method(e_arg*); ]| -> gm |[ x_method(e_arg'*); ]|
Analysis
In this specific example the mixed parse table contains two productions:
{Expr[JavaObject] ","}* = varsym({Expr[JavaObject] ","})
varsym({Expr[JavaObject] ","}) = [lit("e_"),lex(iter-star(char-class([39,range(48,57),range(65,90),range(97,122)]))),lit("*")]
After parsing the example the parse tree contains a parent parse node (corresponding to production 1) and a child parse node (corresponding to production 2). When the TreeBuilder encounters the first parse node it tries to create a list (because
{Expr[_] ","}*
indicates that a list will follow). Since a list does not follow this fails and the TreeBuilder defaults to an empty list.Solution
I created a solution, albeit a bit hacky, here (https://github.com/MartijnDwars/jsglr/commit/088366d0210f2aa28e8780b26ea895586584f478). This solution checks if the parent node is a list node and has as child a meta-listvar node, and in that case it takes a different path.
Submitted by Martijn on 14 February 2018 at 14:00
Issue Log
Similar as #245, fixed in recent developments of JSGLR2. Part of the imploding implementation was lacking support for mix-syntax.
Log in to post comments