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

时间:2016-06-28 15:43:05

标签: rascal concrete-syntax-tree

给定一些具体的语法值,我如何将其映射到不同类型的值(在本例中为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 个答案:

答案 0 :(得分:2)

您的问题有不同的答案:

  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. 如果您想实际增加Leaf值的语法表示,则必须将结果int转换回(解析或通过具体模式)返回Leaf
  4. 示例:

    import String;
    MyTree increment() {
        MyTree tree = (MyTree)`(3, (1, 10))`;
    
        return visit(tree) {
          case Leaf l => [Leaf] "<toInt("<l>") + 1>";  
        };
    }
    

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