简体   繁体   中英

Is it possible to use scala macro to construct types?

I know that it's possible to construct types inside generated function, but is it possible to return them outside?

I need a macro which generates Parser[T] - where both parser and T are constructed from external grammar, written in simplified grammar description language for library users. T is parsed AST which contains mutually nested case classes. These case classes should be generated and visible outside.

Grammar:

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

Use:

//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 

I'm thinking about solutions:

  • blackbox macro (how to define type which may be used outside of the generated function?)
  • workaround: macro-annotated types whith members generated from my grammar (i don't know how many types i have, so i need to generate subclasses by annotation, is it possible?)
  • write compiler plugin or separate sbt-task or look at macroparadise
  • generate class in runtime is not an option because i need to check types

Yes, it's possible. You can generate ASTs including ClassDef , ModuleDef , etc. without problem, and if you use macro annotations (from macro-paradise), they will be visible to external code (in a normal def macro like parser in your desired code they are local). See "Public type providers" in http://docs.scala-lang.org/overviews/macros/typeproviders.html and https://github.com/travisbrown/type-provider-examples . Your library code would look slightly differently:

@Grammar("path/to/file") trait ASTNode // reads grammar, and generates subclasses, parser, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM