是否可以使用scala宏来构造类型?

时间:2014-09-24 03:04:57

标签: scala parsing macros

我知道在生成的函数中构造类型是可能的,但是可以将它们返回到外部吗?

我需要一个生成Parser [T]的宏 - 其中解析器和T都是用外部语法构造的,用库用户的简化语法描述语言编写。 T被解析为AST,其中包含相互嵌套的case类。应该生成这些案例类并在外部可见。

语法:

RootType {
  member1: {
    member11: TypeB
    member12: String
    member13: TypeB
  }
  member2: String
  TypeB {
     member3: String
  }
}

使用:

//Somewhere in my library:
trait ASTNode
def parser: Parser[ASTNode] = macro ... //interpret types from grammar-file

//On the client side:
val input = ... //reads unparsed string from some script-file
val parsed = parse(parser, input)
parsed.member1.member11.member3 //so ASTNode should be replaced  with RootType 
//case class TypeB and synthetic case class for member1 should be also generated 

我正在考虑解决方案:

  • blackbox macro(如何定义可以在生成的函数之外使用的类型?)
  • 解决方法:从我的语法生成成员的宏注释类型(我不知道我有多少类型,所以我需要通过注释生成子类,是否可能?)
  • 编写编译器插件或单独的sbt-task或查看macroparadise
  • 在运行时生成类不是一个选项,因为我需要检查类型

1 个答案:

答案 0 :(得分:2)

是的,这是可能的。您可以毫无问题地生成包括ClassDefModuleDef等的AST,如果您使用宏注释(来自宏天堂),它们将对外部代码可见(在正常{{1}中在您想要的代码中,像def这样的宏是本地的)。请参阅http://docs.scala-lang.org/overviews/macros/typeproviders.htmlhttps://github.com/travisbrown/type-provider-examples中的“公共类型提供者”。您的库代码看起来会略有不同:

parser