我有一个外部DSL(Combinator-Parsers)来定义Extractor[A]
,其中A是执行Extractor时提取的类型。
提取器包含将下一步调用为延续的步骤。
提取器创建中间提取(基于字符串的键/值对),最终由工厂转换为正确的A
。
提取器:case class Extractor[A](id: String, start: Step[A], factory: Factory[A])
步骤:sealed trait Step[A] {
def process(ctx: Context[A]): List[A]
}
工厂:trait Factory[A] { def create(extracts: List[(String,String)]): List[A] }
目前我的提取器解析器如下所示:
val extractor: Parser[Extractor[_]] = trace ~ "EXTRACT" ~ extractorType ~ extractorId ~ step ^^ {
case t ~ _ ~ ty ~ id ~ step => {
val extr = ty match {
case "SUBTITLES" => {
Extractor[MovieInfos.Subtitle](id, step.asInstanceOf[Step[MovieInfos.Subtitle]], new SubtitleFactory)
}
case x => throw new InvalidExtractorType(x)
}
extr.trace(t)
}
}
编辑:步骤解析器具有签名val step: Parser[Step[_]]
(步骤解析器无法知道它正在解析的Step[A]
类型。最后步骤得到正确的A
- 由提取器解析器的asInstanceOf
)
上面的提取器解析器目前只能解析extractorType "SUBTITLES"
的提取器。我想连续添加其他extractorTypes,例如case "REVIEWS" => ...
。
对于每个提取器Extractor[A]
,我必须提供一个专门的工厂(例如new SubtitleFactory
)来创建A
类型的东西(例如MovieInfos.Subtitle
)并传递匹配{{ 1}}进入提取器(这就是step
的用途)。
解析器必须解析不同的Extractor-Types(字幕,图像,Audiotracks等),
所以我使用asInstanceOf
,这是正确输入还是有更好的方法?
此外,我想避免看起来有点可疑的Parser[Extractor[_]]
因为我已经提供了正确的类型step.asInstanceOf[Step[MovieInfos.Subtitle]]
最后我想要一个更灵活的工厂,可能通过某种配置/钩子可扩展。
任何建议都表示赞赏,谢谢。