如何将具体语法值转换为其他类型的值?

How I can convert concrete syntax values to other kinds of values?

给定一些具体的语法值,我如何才能将其映射到不同类型的值(在本例中为 int)?

// Syntax
start syntax MyTree = \node: "(" MyTree left "," MyTree right ")"
                    | leaf: Leaf leaf
                    ;

layout MyLayout = [\ \t\n\r]*;

lexical Leaf = [0-9]+;

不幸的是,这不起作用:

public Tree increment() {
    MyTree tree = (MyTree)`(3, (1, 10))`;

    return visit(tree) {
      case l:(Leaf)`3` => l + 1  
    };
}

或者是 implode 进入我指定类型的 ADT 的唯一方法?

您的问题有不同的可能答案:

  1. 使用implode,您可以将解析树转换为抽象树。如果目标抽象语言的构造函数期望 int,那么恰好匹配 [0-9]+ 的词法树将被自动转换。例如,syntax Exp = intValue: IntValue; 的语法树可以转换为构造函数 data Exp = intValue(int i);,它实际上会构建一个 i.
  2. 通常要在 Rascal 中将一种类型的值转换为另一种类型的值,您可以编写(相互)递归函数,如 int eval (MyTree t)int (Leaf l).
  3. 如果你想实际增加叶值的语法表示,你必须从结果 int 转换回(解析或通过具体模式)返回 Leaf

示例:

import String;
MyTree increment() {
    MyTree tree = (MyTree)`(3, (1, 10))`;

    return visit(tree) {
      case Leaf l => [Leaf] "<toInt("<l>") + 1>";  
    };
}

首先将词法转换为字符串 "<l>",然后使用 toInt() 将其解析为 int,然后使用 + 1 加 1,然后映射int 返回字符串 "< ... >",之后我们可以使用 [Leaf].

调用 Leaf 解析器