Scala: How to combine parser combinators from different objects

后端 未结 1 1563
轻奢々
轻奢々 2020-12-09 10:13

Given a family of objects that implement parser combinators, how do I combine the parsers? Since Parsers.Parser is an inner class, and in Scala inner classes are bound to th

相关标签:
1条回答
  • 2020-12-09 11:10

    The quick answer is to use the traits instead of hosting the parsers in objects:

    import scala.util.parsing.combinator._
    
    trait BinaryParser extends JavaTokenParsers {
      def anyrep: Parser[Any] = rep(any)
      def any: Parser[Any] = zero | one
      def zero: Parser[Any] = "0"
      def one: Parser[Any] = "1"
    }
    
    trait LongChainParser extends BinaryParser {
      def parser1: Parser[Any] = zero~zero~one~one
    }
    
    trait ShortChainParser extends BinaryParser {
      def parser2: Parser[Any] = zero~zero
    }
    
    object ExampleParser extends LongChainParser with ShortChainParser  {
      def parser: Parser[Any] = (parser1 ||| parser2) ~ anyrep
    
      def main(args: Array[String]) {
        println(parseAll(parser, args(0) ))
      }
    }
    

    Because the combinator operators like ~ and | are written against the inner class, escalating the parser references to class-level by saying BinaryParser#Parser[_] doesn't do you any good. Using traits solves all that inner-class issues since both Parser[Any] from LongChainParser and ShortChainParser now refer to the inner class of ExampleParser object.

    0 讨论(0)
提交回复
热议问题