嵌套后代模式匹配
Nested descendant pattern matches
我正在尝试查找所有方法调用和包含它们的 classes。如果我没理解错的话,模式匹配执行回溯,以所有可能的方式进行匹配。
采取以下java代码。
package main;
public class Main {
public static void main(String[] args) {
System.out.println("hello world");
System.out.println("hello again");
}
}
我正在使用 createAstsFromDirectory 加载代码。
rascal>ast = createAstsFromDirectory(|home:///multiple-method-calls|, false);
我试图找到对 println 的两个调用。以下代码匹配一次:
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case \class(_,_,_,/\methodCall(_,_,str methodName,_)):
println("<methodName>");
}
}
rascal>findCalls(ast);
println
ok
这段代码匹配四次:
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case /\class(_,_,_,/\methodCall(_,_,str methodName,_)):
println("<methodName>");
}
}
rascal>findCalls(ast);
println
println
println
println
ok
模式必须如何才能恰好匹配两次?
相关问题,如何获取class名字?尝试访问 class 名称时出现错误消息。
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case /\class(str className,_,_,/\methodCall(_,_,str methodName,_)):
println("<className> <methodName>");
}
}
findCalls(ast);
Main println
|project://personal-prof/src/Assignment13Rules.rsc|(3177,9,<141,16>,<141,25>): Undeclared variable: className
看起来第一个匹配项 className 正确绑定到 "Main",但第二个匹配项没有。
我想我会这样写:
void findCalls(set[Declaration] ast) {
for(/class(_, _, _, /methodCall(_,_,str methodName,_)) <- ast) {
println("<methodName>");
}
}
for 循环遍历它可以找到的每个 class,通过它可以在内部找到的每个 methodCall,因此对于您给出的示例两次。
你的第二次尝试出错并且匹配太频繁:如果你在一个访问的情况的顶部嵌套一个/
,你访问树中的每个位置一次,并遍历整个子 -再次包含根节点的树。所以你每次都会接到两次电话。
您的第一次尝试出错了,因为访问的案例模式的顶级不会自行回溯,它会找到整个模式的第一个匹配项,然后停止。所以嵌套的/
只匹配一次然后body被执行
在 for 循环解决方案中,for 循环(与访问不同)将尝试所有可能的匹配直到它停止,所以这就是要走的路。还有一个更接近你原计划的解决方案:
void findCalls(set[Declaration] ast) {
visit (ast) {
case class(_, _, _, body) :
for (/methodCall(_,_,str methodName,_) <- body) {
println("<methodName>");
}
}
}
这也像 for 循环一样工作,它首先通过访问一个一个地找到所有 classes,然后通过 for 循环遍历所有嵌套匹配。
最后,您还可以嵌套访问本身以获得正确答案:
void findCalls(set[Declaration] ast) {
visit (ast) {
case class(_, _, _, body) :
visit(body) {
case methodCall(_,_,str methodName,_): {
println("<methodName>");
}
}
}
}
WRT 到 className 东西,似乎 visit
和顶级深度匹配的组合在这样的情况下:case /<pattern>
中有一个错误Rasca 解释器在深层模式中丢失了变量绑定。所以请避免这种模式(我认为您不需要它),如果您愿意,请在 github?
上提交问题报告
在 for 循环的情况下,这将按预期简单地工作:
for(/class(str className, _, _, /methodCall(_,_,str methodName,_)) <- ast) {
println("<className>::<methodName>");
}
我正在尝试查找所有方法调用和包含它们的 classes。如果我没理解错的话,模式匹配执行回溯,以所有可能的方式进行匹配。
采取以下java代码。
package main;
public class Main {
public static void main(String[] args) {
System.out.println("hello world");
System.out.println("hello again");
}
}
我正在使用 createAstsFromDirectory 加载代码。
rascal>ast = createAstsFromDirectory(|home:///multiple-method-calls|, false);
我试图找到对 println 的两个调用。以下代码匹配一次:
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case \class(_,_,_,/\methodCall(_,_,str methodName,_)):
println("<methodName>");
}
}
rascal>findCalls(ast);
println
ok
这段代码匹配四次:
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case /\class(_,_,_,/\methodCall(_,_,str methodName,_)):
println("<methodName>");
}
}
rascal>findCalls(ast);
println
println
println
println
ok
模式必须如何才能恰好匹配两次?
相关问题,如何获取class名字?尝试访问 class 名称时出现错误消息。
void findCalls(set[Declaration] ast)
{
visit(ast)
{
case /\class(str className,_,_,/\methodCall(_,_,str methodName,_)):
println("<className> <methodName>");
}
}
findCalls(ast);
Main println
|project://personal-prof/src/Assignment13Rules.rsc|(3177,9,<141,16>,<141,25>): Undeclared variable: className
看起来第一个匹配项 className 正确绑定到 "Main",但第二个匹配项没有。
我想我会这样写:
void findCalls(set[Declaration] ast) {
for(/class(_, _, _, /methodCall(_,_,str methodName,_)) <- ast) {
println("<methodName>");
}
}
for 循环遍历它可以找到的每个 class,通过它可以在内部找到的每个 methodCall,因此对于您给出的示例两次。
你的第二次尝试出错并且匹配太频繁:如果你在一个访问的情况的顶部嵌套一个/
,你访问树中的每个位置一次,并遍历整个子 -再次包含根节点的树。所以你每次都会接到两次电话。
您的第一次尝试出错了,因为访问的案例模式的顶级不会自行回溯,它会找到整个模式的第一个匹配项,然后停止。所以嵌套的/
只匹配一次然后body被执行
在 for 循环解决方案中,for 循环(与访问不同)将尝试所有可能的匹配直到它停止,所以这就是要走的路。还有一个更接近你原计划的解决方案:
void findCalls(set[Declaration] ast) {
visit (ast) {
case class(_, _, _, body) :
for (/methodCall(_,_,str methodName,_) <- body) {
println("<methodName>");
}
}
}
这也像 for 循环一样工作,它首先通过访问一个一个地找到所有 classes,然后通过 for 循环遍历所有嵌套匹配。
最后,您还可以嵌套访问本身以获得正确答案:
void findCalls(set[Declaration] ast) {
visit (ast) {
case class(_, _, _, body) :
visit(body) {
case methodCall(_,_,str methodName,_): {
println("<methodName>");
}
}
}
}
WRT 到 className 东西,似乎 visit
和顶级深度匹配的组合在这样的情况下:case /<pattern>
中有一个错误Rasca 解释器在深层模式中丢失了变量绑定。所以请避免这种模式(我认为您不需要它),如果您愿意,请在 github?
在 for 循环的情况下,这将按预期简单地工作:
for(/class(str className, _, _, /methodCall(_,_,str methodName,_)) <- ast) {
println("<className>::<methodName>");
}