Composing scala parser combinators at runtime
我已经在这里看到了其他一些相关的SO帖子,这表明使用traits继承是解决此问题的唯一方法,但是我在这里看不到如何使用它。
我正在编写一个汇编器,该汇编器的指令允许您更改处理器的模型,从而影响可解析的操作码集。我有两个解析器类,一个处理所有指令关键字,一个处理指令。 (针对不同的处理器型号,还会有更多)。解析\\'cpu \\'指令后,将选择适当的指令解析器。这是一个非常简略的插图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import scala.util.parsing.combinator.JavaTokenParsers class ComposingParser { sealed abstract class Statement { } case class Dinst(value: String) extends Statement case class Keyword(value: String) extends Statement class InstructionParser extends JavaTokenParsers { def directOpcode: Parser[Statement] = j | ldlp | pfix private def j: Parser[Dinst] ="""(?i)J""".r ^^ ( x => Dinst(x.toUpperCase) ) private def ldlp: Parser[Dinst] ="""(?i)LDLP""".r ^^ ( x => Dinst(x.toUpperCase) ) private def pfix: Parser[Dinst] ="""(?i)PFIX""".r ^^ ( x => Dinst(x.toUpperCase) ) } class KeywordParser extends JavaTokenParsers { def program: Parser[Statement] = keys | instruction // the main, top-level parser def keys: Parser[Keyword] = start | end private def start: Parser[Keyword] ="""(?i)START""".r ^^ ( x => Keyword(x.toUpperCase) ) private def end: Parser[Keyword] ="""(?i)END""".r ^^ ( x => Keyword(x.toUpperCase) ) private def instruction: Parser[Statement] = { val ip = new InstructionParser // will be dynamically instantiating different parsers for different instruction sets so can't use traits ip.directOpcode // Error:(46, 16) type mismatch; // found : ip.Parser[ComposingParser.this.Statement] // required: KeywordParser.this.Parser[ComposingParser.this.Statement] // ip.directOpcode } // I can't use traits as in https://stackoverflow.com/questions/2650254/scala-how-to-combine-parser-combinators-from-different-objects // I can't see how to apply the solution from https://stackoverflow.com/questions/40166258/reuse-parser-within-another-parser-with-scala-parser-combinators // Is it possible to convert an 'ip.Parser[Statement]' into a 'KeywordParser.this.Parser[Statement]' ? } } |
directOpcode和指令都返回Parser [Statement],为什么不能这样组合它们?自我类型注释可以在这里提供帮助吗?在此先感谢您可以提供的任何帮助...(或显示其他引用的SO帖子中发布的解决方案可能有帮助的插图)。
从这个问题来看,为什么您"不能使用特征"并不清楚。至少您的具体示例确实适用于特质:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | // uses `$ivy`-imports, either run with Ammonite, or remove the import and // compile using SBT. import $ivy.`org.scala-lang.modules:scala-parser-combinators_2.12:1.1.1` import scala.util.parsing.combinator.JavaTokenParsers class ComposingParser { sealed abstract class Statement { } case class Dinst(value: String) extends Statement case class Keyword(value: String) extends Statement trait InstructionParser extends JavaTokenParsers { def directOpcode: Parser[Statement] = j | ldlp | pfix private def j: Parser[Dinst] ="""(?i)J""".r ^^ ( x => Dinst(x.toUpperCase) ) private def ldlp: Parser[Dinst] ="""(?i)LDLP""".r ^^ ( x => Dinst(x.toUpperCase) ) private def pfix: Parser[Dinst] ="""(?i)PFIX""".r ^^ ( x => Dinst(x.toUpperCase) ) } trait InstructionParser2 extends JavaTokenParsers { def directOpcode2: Parser[Statement] = j | ldlp | pfix private def j: Parser[Dinst] ="""(?i)J""".r ^^ ( x => Dinst(x.toUpperCase) ) private def ldlp: Parser[Dinst] ="""(?i)LDLP""".r ^^ ( x => Dinst(x.toUpperCase) ) private def pfix: Parser[Dinst] ="""(?i)PFIX""".r ^^ ( x => Dinst(x.toUpperCase) ) } class KeywordParser extends JavaTokenParsers with InstructionParser with InstructionParser2 { def program: Parser[Statement] = keys | instruction // the main, top-level parser def keys: Parser[Keyword] = start | end private def start: Parser[Keyword] ="""(?i)START""".r ^^ ( x => Keyword(x.toUpperCase) ) private def end: Parser[Keyword] ="""(?i)END""".r ^^ ( x => Keyword(x.toUpperCase) ) private def instruction: Parser[Statement] = { if (math.random < 0.5) directOpcode else directOpcode2 } } } |