2010-04-16 61 views
15

給定一個實現解析器組合器的對象家族,如何組合解析器?由於Parsers.Parser是內部類,在Scala inner classes are bound to the outer object中,故事變得稍微複雜。Scala:如何組合來自不同對象的解析器組合器

下面是一個嘗試組合來自不同對象的兩個解析器的示例。

import scala.util.parsing.combinator._ 

class 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" 
} 

object LongChainParser extends BinaryParser { 
    def parser1: Parser[Any] = zero~zero~one~one 
} 

object ShortChainParser extends BinaryParser { 
    def parser2: Parser[Any] = zero~zero 
} 

object ExampleParser extends BinaryParser { 
    def parser: Parser[Any] = (LongChainParser.parser1 
    ||| ShortChainParser.parser2) ~ anyrep 

    def main(args: Array[String]) { 
    println(parseAll(parser, args(0))) 
    } 
} 

這將導致以下錯誤:

<console>:11: error: type mismatch; 
found : ShortChainParser.Parser[Any] 
required: LongChainParser.Parser[?] 
     def parser: Parser[Any] = (LongChainParser.parser1 
      ||| ShortChainParser.parser2) ~ anyrep 

我已經找到了解決這個問題了,但因爲自小 最近在斯卡拉用戶ML(Problem injecting one parser into another),它是可能值得把它放在這裏。

回答

17

簡單的回答是object s到使用trait!而非託管解析器:

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))) 
    } 
} 

因爲組合子運營商如~|是針對內部類寫的,升級到類解析器引用說BinaryParser#Parser[_]不對你有什麼好處。使用特徵解決了所有內部類問題,因爲Parser[Any]LongChainParserShortChainParser現在指的是ExampleParser對象的內部類。

+1

感謝您發佈這個問題,當然要回答它!這正是我所期待的。 – 2011-08-17 09:20:21

相關問題