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:
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.