Rascal: TrafoFields Syntax error: concrete syntax fragment

Rascal: TrafoFields Syntax error: concrete syntax fragment

我正在尝试重新创建 Tijs 的 CurryOn16 示例 "TrafoFields" 从视频中抓取代码,但使用 Java18.rsc 语法而不是他的 Java15.rsc .我已经在 repl 中成功解析了 Example.java,就像他在视频中所做的那样,产生了一个 var pt。然后我尝试使用 trafoFields(pt) 进行转换。我得到的回复是:

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

我的 TrafoFields.rsc 看起来像这样:

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>"
    }
 }

与 Tijs 代码的唯一差异是我将 ClassBodyDec* 更改为 ClassBodyDeclaration*,因为语法将 this 作为非终结符。任何提示还有什么可能是错误的?

更新

更多适应Java18语法的非终端重写:

啊,是的,这就是具体语法可用性的致命弱点;解析错误。

请注意,通用解析器(例如 Rascal 使用的 GLL)会模拟 "unlimited lookahead",因此解析错误可能会在实际原因之后的几个字符甚至几行中报告(但绝不会在之前! ).因此,缩短示例(增量调试)将有助于定位原因。

我的生活方式是:

  1. 首先用具体的 Java 片段替换所有图案孔。我知道 Java,所以我应该能够写出一个与漏洞匹配的正确片段。
  2. 如果还是有解析错误,现在检查top-non-terminal。它是你需要的吗?还要确保在反引号内的片段开始之前和结束之后没有额外的空格。仍然是解析错误?首先为子非终结符先写一个较短的片段。
  3. 解析错误解决了吗?这意味着其中一个模式漏洞在句法上不正确。洞的类型在这里领先,它应该是从字面上使用语法的非终结符之一,当然在片段的正确位置。将孔一个一个地添加回来,直到您再次遇到错误。然后您就知道了原因,也可能知道了解决方法。