Parsing a Syntax-Box mixed syntax file with JSGLR2 gives a result that does not fit the syntax rules. This bug is in the way of using JSGLR2 in strj. Using JSGLR2 would allow strj to generate code that gives better stack traces.

Steps to reproduce

Setup

Download strategoxt-distrib and extract to some directory $dir (or on Mac use homebrew-metaborg to install the latest strategoxt). Also download PrettyPrintRules.str AND PrettyPrintRules.meta.

Also get something set up for parsing a file with JSGLR2 (there’s no main around in the JSGLR2 code AFAIK).

Commands

To get the pretty-printed AST as JSGLR1 parses the file, or the second command if installed with homebrew:

java -cp $dir/share/strategoxt/strategoxt/strategoxt.jar run org.strategoxt.tools.parse-stratego-io -i PrettyPrintRules.str -I $dir/share/strategoxt/gpp/sdf --assimilation off | java -cp $dir/share/strategoxt/strategoxt/strategoxt.jar run org.strategoxt.stratego-aterm.io-pp-aterm > jsglr1.aterm
parse-stratego -i PrettyPrintRules.str -I /usr/local/share/strategoxt/gpp/sdf --assimilation off | pp-aterm > jsglr1.aterm

Now use whatever method you have handy to parse the same file with JSGLR2 (parse table is $dir/share/strategoxt/gpp/sdf/Stratego-Box.tbl), and use pp-aterm again for the pretty-printing

java -cp $dir/share/strategoxt/strategoxt/strategoxt.jar run org.strategoxt.stratego-aterm.io-pp-aterm` to pretty-print the AST to a file `jsglr2.aterm

Resulting diff

See also the conclusion below the diff.

$ diff jsglr1.aterm jsglr2.aterm
192,201c192,197
<               , Conc(
<                   Conc(
<                     [ S(FromTerm(Var("f")))
<                     , S("\"(\"")
<                     , FromTerm(App(CallNoArgs(SVar("s")), Var("x")))
<                     ]
<                   , FromTerm(Var("children"))
<                   )
<                 , [S("\")\"")]
<                 )
---
>               , [ S(FromTerm(Var("f")))
>                 , S("\"(\"")
>                 , FromTerm(App(CallNoArgs(SVar("s")), Var("x")))
>                 , Var("children")
>                 , S("\")\"")
>                 ]
237,248c233,235
<               , Conc(
<                   Conc(
<                     [ H(
<                         [SOpt(HS(), "0")]
<                       , [S(FromTerm(Var("f"))), S("\"(\"")]
<                       )
<                     , H(
<                         [SOpt(HS(), "1")]
<                       , [S("\" \""), FromTerm(App(CallNoArgs(SVar("s")), Var("x")))]
<                       )
<                     ]
<                   , FromTerm(Var("children"))
---
>               , [ H(
>                     [SOpt(HS(), "0")]
>                   , [S(FromTerm(Var("f"))), S("\"(\"")]
250,251c237,243
<                 , [S("\")\"")]
<                 )
---
>                 , H(
>                     [SOpt(HS(), "1")]
>                   , [S("\" \""), FromTerm(App(CallNoArgs(SVar("s")), Var("x")))]
>                   )
>                 , Var("children")
>                 , S("\")\"")
>                 ]
353,361c345,349
<               , Conc(
<                   Conc(
<                     [ FromTerm(App(CallNoArgs(SVar("before")), NoAnnoList(Tuple([]))))
<                     , FromTerm(App(CallNoArgs(SVar("s")), Var("x")))
<                     ]
<                   , FromTerm(Var("tail"))
<                   )
<                 , [FromTerm(App(CallNoArgs(SVar("after")), NoAnnoList(Tuple([]))))]
<                 )
---
>               , [ FromTerm(App(CallNoArgs(SVar("before")), NoAnnoList(Tuple([]))))
>                 , FromTerm(App(CallNoArgs(SVar("s")), Var("x")))
>                 , Var("tail")
>                 , FromTerm(App(CallNoArgs(SVar("after")), NoAnnoList(Tuple([]))))
>                 ]
392,399c380,383
<               , Conc(
<                   Conc(
<                     [ H(
<                         [SOpt(HS(), "1")]
<                       , [ FromTerm(App(CallNoArgs(SVar("before")), NoAnnoList(Tuple([]))))
<                         , FromTerm(App(CallNoArgs(SVar("s")), Var("x")))
<                         ]
<                       )
---
>               , [ H(
>                     [SOpt(HS(), "1")]
>                   , [ FromTerm(App(CallNoArgs(SVar("before")), NoAnnoList(Tuple([]))))
>                     , FromTerm(App(CallNoArgs(SVar("s")), Var("x")))
401d384
<                   , FromTerm(Var("tail"))
403,404c386,388
<                 , [FromTerm(App(CallNoArgs(SVar("after")), NoAnnoList(Tuple([]))))]
<                 )
---
>                 , Var("tail")
>                 , FromTerm(App(CallNoArgs(SVar("after")), NoAnnoList(Tuple([]))))
>                 ]

Conclusion

The JSGLR1 version is slightly more complex because of the Conc, and I can’t find where they come from, but that’s not the problem. The problem is JSGLR1 produces FromTerm(Var("children")) as expected, where JSGLR2 produces just Var("children"). JSGLR2 is wrong here. This happens four times in total, two times for variable children, two times for variable tail. These are variables that are in mix syntax patterns. Try comparing the input stratego file with the mix syntax rules, we should get the wrapping FromTerm.

Submitted by Jeff Smits on 17 June 2018 at 12:12

On 19 June 2018 at 14:40 Jasper Denkers commented:

Related to imploding list productions that also have constructors defined. Fixes in:


On 12 August 2019 at 22:25 Jasper Denkers commented:

Fixed in recent developments of JSGLR2. Part of the imploding implementation was actually lacking support for mix-syntax, causing weird and unpredictable behavior.


On 12 August 2019 at 22:25 Jasper Denkers closed this issue.

Log in to post comments