【问题标题】:evaluate Scala abstract syntax tree recursively递归评估Scala抽象语法树
【发布时间】:2016-01-29 11:32:43
【问题描述】:

假设我有一个 lambda,我使用 reify 将它转换为一个包裹在树周围的 Expr。例如

val expr = reify{x: Int => 3*(4+x)}

我可以对特定的 x 进行如下评估

val toolbox = currentMirror.mkToolBox()
val fun = toolbox.eval(expr.tree).asInstanceOf[Int => Int]
println(fun(10))

我的目标是打印出整个树,并用每个子表达式的值进行注释。如何确定所有子表达式及其值?例如,确定当 x 为 10 时存在子表达式

(4+x)

计算结果为 14。Traverser 类允许我访问树中的每个节点,但我不知道如何评估每个节点的子树。

例如,用下面的

class TestTraverser extends Traverser {
  override def traverse(tree: Tree): Unit = {
    val toolbox = currentMirror.mkToolBox()
    tree match {
      case app @ Apply(fun, args) =>
        val f = toolbox.eval(app.fun)
      case _ =>
    }
    super.traverse(tree)
  }
}

打电话

new TestTraverser().traverse(expr.tree)

导致此异常

scala.tools.reflect.ToolBoxError: reflective compilation has failed:

ambiguous reference to overloaded definition,
both method * in class Int of type (x: Char)Int
and  method * in class Int of type (x: Byte)Int
match expected type Any

【问题讨论】:

  • 为子树调用 eval?
  • 你会认为有一些方法可以在子树上调用 eval,但我还没有找到方法。我添加了一个 Traverser 来尝试这个并且 not 工作。

标签: scala abstract-syntax-tree


【解决方案1】:

自己解决了这个问题。为了在子树上调用toolbox.eval,您需要使用指示它是名为xInt 的函数的信息重新包装子树。这是一个有效的Traverser 示例。

class WorkingTraverser extends Traverser {
  val toolbox = currentMirror.mkToolBox()
  override def traverse(tree: Tree): Unit = {
    tree match {
      case app @ Apply(fun, args) =>
        val newfun = Function(List(ValDef(Modifiers(PARAM), TermName("x"), Ident(TypeName("Int")), EmptyTree)), Apply(app.fun, app.args))
        val f = toolbox.eval(newfun)
        val f2 = f.asInstanceOf[Int => Int]
        println(app.fun + "(" + app.args + ")" + " evaluates to " + f2(10))
        super.traverse(fun)
        super.traverseTrees(args)
      case _ => super.traverse(tree)
    }
  }
}

【讨论】:

  • 完全跑题了,但是,你知道“@”语法是怎么调用的吗?我不明白如何阅读它,它意味着什么,我还能在哪里使用它等等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 2015-07-12
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多