如何在 Rascal 中初始化包含表达式列表的元组

How to initialize a tuple containing an list of expressions in Rascal

我正在尝试创建一个递归查找 For 循环的方法。我需要先初始化 return 值(一个元组),但我该怎么做呢? 我试过:tuple[list[Expression],Statement] = [];

此外,如果我要绑定一个完整的声明,例如;

case s:\for(_,_,_,_): 

这是否是正确的类型:tuple[list[Expression],Statement]?

public tuple[list[Expression],Statement] showForLoops(loc project) {
 set[loc] files = javaFiles(project);
 set[Declaration] decls = createAstsFromFiles(files, false);
 tuple[list[Expression],Statement] result = [];
visit (decls) {
 case \for(initializers,_,_,body): result += < initializers, body>;
}
return(result);
}

简单的答案是您必须选择这样的 Statement 类型:

result = <[], empty()>; // using the empty statement as a default

注意我没有使用类型(可以推断)

你也可以写成这样:

tuple[list[Expression],Statement] result = <[], empty()>;

还有其他方法可以编写此代码,您可能会觉得这些方法很有趣。

\for 构造函数本身,可以替换您需要的元组的概念。您稍后可以使用 myForLoop.initializers 投影出其字段(例如):

Statement findFirstForStatement(loc project) {
    decls = createAstsFromFiles(files, false);
    visit(decls) {
       case f:\for(_,_,_,_): return f;
    }
    return empty();
}

rascal>ff = findFirstForStatement(pr);
Statement: for(....)
rascal>ff.initializers
list[Expression]: [...]

或者你可以使用 Maybe:

import util::Maybe;

Maybe[tuple[list[Expression], Statement]] findFirstForLoop(loc project) {
   decls = createAstsFromFiles(files, false);
   visit(decls) {
       case f:\for(_,_,_,_) : return just(f);
   }
   return nothing();
}

或者,最后,如果找不到任何内容,您可能会抛出异常:

Statement findFirstForLoop(loc project) {
   decls = createAstsFromFiles(files, false);
   visit(decls) {
       case f:\for(_,_,_,_) : return f;
   }

   throw "couldn't find a for loop";
}

还有一个 Bonus 示例收集所有 for 循环而不是查找第一个循环:

list[Statement] getAllForLoops(loc project) {
   decls = createAstsFromFiles(files, false);
   result = [];

   visit(decls) {
       case f:\for(_,_,_,_) : result += [f];
   }
   return result;
}

也可以写成理解式:

list[Statement] getAllForLoops(loc project) {
   decls = createAstsFromFiles(files, false);
   return [ f | /f:\for(_,_,_,_) := decls];
}