Scala AST避免遍历Tree子级

时间:2018-10-17 04:16:51

标签: scala pattern-matching abstract-syntax-tree scalac

我正在研究在AST中运行的scalac插件。现在,我在unit.body的每个循环中使用a,这是从传递的Global值中获得的。我面临的问题是,由于上述遍历的递归性质,我访问了每个Tree及其子级,尽管我不想遍历后者,因为我正在使用模式匹配来匹配函数调用

例如,如果我要遍历以下语句:

x.do(arg1)(arg2)(arg3)

我将在遍历中得到以下内容:

1. x.do(arg1)(arg2)(arg3)
2.    x.do(arg1)(arg2)
3.        x.do(arg1)
4.            x.do
5.                x
6.                do
7.            arg1
8.        arg2
9.    arg3

在这里,我按照遍历的顺序缩进了Tree对象。现在,如果我要使用Apply case类与它们中的每一个进行匹配,我将得到1,2和3的匹配,而我实际上只想要1。我考虑使用上下文相关的解决方案(就像检查之前遍历的Tree一样),但对于我的目的而言,一致性不够。我也不是在寻找使匹配更容易的特定方法,而是在一般方法上,但是我不能考虑这些孩子。

编写scalac插件时,是否可以使用更好的模式来匹配函数调用,还是可以使用更好的方法进行遍历,以免遇到递归问题?

1 个答案:

答案 0 :(得分:0)

我自己找到了答案: 而不是使用直观的

for(tree <- treeObject),其中treeObject : Tree

您只需在每个children对象中使用Tree对象,然后执行以下操作

def func(treeObject : Tree) : Something = {
    for(tree <- treeObject.children) {
        if(/*your condition for further traversal*/)
            func(treeObject : Tree) //RECURSE
        else
            someValue //do whatever and RETURN
    }
}

使用这种方法,可以设置遍历的停止条件。假设您只想查看每个方法调用。可以匹配使用Apply case类的方法调用。现在,您只需检查您当前的tree是否与该模式匹配即可。如果这样做,您将对其进行工作并返回。如果没有使用递归进一步遍历Tree,则可以进一步“向下”获得可能的方法调用。