1

I'm trying to re-create Tijs' CurryOn16 example "TrafoFields" scraping the code from the video, but using the Java18.rsc grammar instead of his Java15.rsc. I've parsed the Example.java successfully in the repl, like he did in the video, yielding a var pt. I then try to do the transformation with trafoFields(pt). The response I get is:

|project://Rascal-Test/src/TrafoFields.rsc|(235,142,<12,9>,<16,11>): Syntax error: concrete syntax fragment

My TrafoFields.rsc looks like this:

module TrafoFields

import lang::java::\syntax::Java18;

/**
 * - Make public fields private
 * - add getters and setters
 */

 start[CompilationUnit] trafoFields(start[CompilationUnit] cu) {
    return innermost visit (cu) {
        case  (ClassBody)`{
                         '  <ClassBodyDeclaration* cs1>
                         '  public <Type t> <ID f>;
                         '  <ClassBodyDeclaration* cs2>
                         '}`
         =>  (ClassBody)`{
                         '  <ClassBodyDeclaration* cs1>
                         '  private <Type t> <ID f>;
                         '  public void <ID setter>(<Type t> x) {
                         '    this.<ID f> = x;
                         '  }
                         '  public <Type t> <ID getter>() {
                         '      return this.<ID f>;
                         '  }
                         '  <ClassBodyDeclaration* cs2>
                         '}`
         when
            ID setter := [ID]"set<f>",
            ID getter := [ID]"get<f>"
    }
 }

The only deviation from Tijs' code is that I've changed ClassBodyDec* to ClassBodyDeclaration*, as the grammar has this as a non-terminal. Any hint what else could be wrong?

UPDATE

More non-terminal re-writing adapting to Java18 grammar:

  • Id => ID
ThomasH
  • 22,276
  • 13
  • 61
  • 62
  • Thomas, thanks for the questions! A word of warning: the Java18 grammar has not been tried and tested much. Yesterday I ran it through the new static checker and that produced lots of issues and warnings as well. – Jurgen Vinju Feb 10 '20 at 13:13
  • Interestingly, when I import the Java15 grammar in the repl, I get lots of warnings. Java18 just goes through fine, without warning. – ThomasH Feb 10 '20 at 13:21
  • I suspect the released experimental type-checker even crashes on that Java18 file, so you don't see errors at all. Paul is working on these issues, as we speak. – Jurgen Vinju Feb 10 '20 at 13:29
  • Another issue with this grammar is that instead of having a single Expression non-terminal with priorities, it has the LR factored expression grammar from the standard. This makes it harder to use because every level in the expression grammar introduces new types to remember. We'll have to apply some grammar refactorings soon to simplify it. – Jurgen Vinju Feb 10 '20 at 13:34
  • You mean like replacing `syntax Expression = LambdaExpression | AssignmentExpression ;` with `syntax Expression = LambdaExpression > AssignmentExpression ;`?! – ThomasH Feb 10 '20 at 13:59
  • yes, in that vain. No more "AssignmentExpression", just only "Expression" everywhere. You see how that would influence your concrete syntax patterns for the better? The grammar would start approaching the conciseness and leveled structure of an abstract tree grammar as well. – Jurgen Vinju Feb 10 '20 at 14:06
  • I've to sleep now; I'll come back later or tomorrow. have fun! – Jurgen Vinju Feb 10 '20 at 14:07
  • Sure. I might add more comments so you can catch up when you get back. – ThomasH Feb 10 '20 at 14:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/207531/discussion-between-thomash-and-jurgen-vinju). – ThomasH Feb 10 '20 at 14:58

1 Answers1

1

Ah yes, that is the Achilles-heal of concrete syntax usability; parse errors.

Note that a generalized parser (such as GLL which Rascal uses), simulates "unlimited lookahead" and so a parse error may be reported a few characters or even a few lines after the actual cause (but never before!). So shortening the example (delta debugging) will help localize the cause.

My way-of-life in this is:

  1. First replace all pattern holes by concrete Java snippets. I know Java, so I should be able to write a correct fragment that would have matched the holes.
  2. If there is still a parse error, now you check the top-non-terminal. Is it the one you needed? also make sure there is no extra whitespace before the start and after the end of the fragment inside the backquotes. Still a parse error? Write a shorter fragment first for a sub-nonterminal first.
  3. Parse error solved? this means one of the pattern holes was not syntactically correct. The type of the hole is leading here, it should be one of the non-terminals used the grammar literally, and of course at the right spot in the fragment. Add the holes back in one-by-one until you hit the error again. Then you know the cause and probably also the fix.
Jurgen Vinju
  • 6,393
  • 1
  • 15
  • 26
  • I think I nailed it: The error hinges on the the pattern `` in `public ;`, but I don't know what to do about it. I thought mayb the type `Type` is ambiguous and needs to be made more specific. But something like `` in the tree pattern throws a syntax error immediately. Using the explicit type name `int` for the example works fine, matches and transforms. NB: The concrete syntax seems to be insensitive to whitespace before or after the pattern in a line like `' public int ; `. – ThomasH Feb 10 '20 at 13:52
  • Good work. The rule for members uses `Unanntype` rather than `Type` so thats one down; – Jurgen Vinju Feb 10 '20 at 14:11