【问题标题】:Can I get AST from live scala code?我可以从实时 scala 代码中获取 AST 吗?
【发布时间】:2009-12-26 08:39:54
【问题描述】:

我说“实时代码”是因为我的意思不是来自文本源文件或源字符串,而是来自 partialFunctions / lambdas。 (我知道Ruby1.8的parseTree和C# linq可以做到)

考虑一个partialFunction f:

val f = (i: Int, j: Int) => (i + j) * 2

我希望有一些工具可以像这样工作:

getBodyAstFrom(f) //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2'))

我不在乎语义的东西(上下文解析和隐式太复杂,对我来说没有必要),我只需要来自实时代码的语法树,可以吗?

检查其他人的代码可能会出现问题,但我自己的代码呢?下面的事情可能吗?

val f = AstFunction(i: Int, j: Int){(i + j) * 2}
f(5, 6) //=> 22
f.ast   //=> (Infix('*'), (Infix('+'), Id('i'), Id('j')), Val('2'))

似乎需要对编译器进行一些破解,嗯...

【问题讨论】:

    标签: scala abstract-syntax-tree


    【解决方案1】:

    编译器本身就是一个库,您可以调用它。事实上,这就是 REPL 的工作方式。但是,虽然您可以为一串代码获取树(在不同阶段),但您无法为编译后的代码获取它。

    当然,如果您使用的实验性材料可以随时更改或干脆不复存在。在这种情况下,您可以尝试:

    scala.reflect.Code.lift(f).tree
    

    得到:

    res17: scala.reflect.Tree = Select(Select(Select(Ident(Field(line26$object,PrefixedType(ThisType(RootSymbol),Class(line26$object)))),Field($iw,PrefixedType(ThisType(Class(line26$object)),Class($iw)))),Field($iw,PrefixedType(ThisType(Class($iw)),Class($iw)))),Method(f,PolyType(List(),List(),AppliedType(PrefixedType(ThisType(Class(scala)),Class(scala.Function2)),List(PrefixedType(ThisType(Class(scala)),Class(scala.Int)), PrefixedType(ThisType(Class(scala)),Class(scala.Int)), PrefixedType(ThisType(Class(scala)),Class(scala.Int)))))))
    

    这是否有帮助...您可能需要查看 Miguel Garcia 的“The Scala Compiler Corner”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      相关资源
      最近更新 更多