【问题标题】:Scala AST avoid traversal of Tree childrenScala AST 避免遍历树的孩子
【发布时间】:2018-10-17 04:16:51
【问题描述】:

我正在开发一个遍历 AST 的 scalac 插件。现在我在unit.body 上使用for each 循环,它是从传递的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 插件时,有没有更好的模式可以匹配函数调用,或者有更好的遍历方式,这样我就不会遇到这个递归问题?

【问题讨论】:

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


    【解决方案1】:

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

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

    您可以在每个Tree 对象中使用children 对象并执行以下操作

    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 案例类来匹配方法调用。现在您可以检查您当前的tree 是否与该模式匹配。如果确实如此,您将对其进行处理并返回。如果不使用递归进一步遍历Tree,则进一步“向下”获取可能的方法调用。

    【讨论】:

      猜你喜欢
      • 2016-10-24
      • 2018-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多