2015-06-14 58 views
0

我有以下解析器:添加repitition作爲案例類(Scala的解析器)名單

import scala.util.parsing.combinator.RegexParsers 

class SimpleParser extends RegexParsers { 

    override val skipWhitespace = false 

    private val eol = sys.props("line.separator") 

    def word: Parser[String] = "[a-z]+".r ^^ { _.toString } 

    def freq: Parser[List[String]] = repsep(word, eol) ^^ { 
    case word => word 
    } 

} 

object TestSimpleParser extends SimpleParser { 
    def main(args: Array[String]) = { 
    parse(freq, 
     """mike 
     |john 
     |sara 
     """.stripMargin) match { 
     case Success(matched,_) => println(matched) 
     case Failure(msg,_) => println(msg) 
     case Error(msg,_) => println(msg) 
    } 
    } 
} 

這個執行的結果將是List(mike, john, sara),但它不是我想要的。

我想有以下案例類:

case class SomeEntity(list: List[String]) 

而結果將是以下幾點:

SomeEntity(List(mike), List(john), List(sara)). 

我想因爲有新詞加入儘可能多的列表線。 請不要把注意力放在列表中只有一個單詞的事實上。這只是我的問題的簡化版本。 那麼,我應該在解析器或案例類中更改哪些內容?

回答

3

案例類定義與預期輸出不匹配。您正在尋找這樣的:

case class SomeEntity(list: List[String]*) { 
    override def toString = this.getClass.getSimpleName+"("+list.mkString(", ")+")" 
} 

現在,如果你想要得到一個SomeEntity例如,解析器的類型將是Parser[SomeEntity]

由於repsep會給你回List[String],您需要在列表中的每個元素映射到一個單列表(讓你得到一個List[List[String]]),然後你強迫它,看看它作爲一個可變參數的類型與:_*

def freq: Parser[SomeEntity] = 
    repsep(word, eol) ^^ (list => new SomeEntity(list.map(List(_)) : _*)) 

鑑於你的輸入,輸出:

SomeEntity(List(mike), List(john), List(sara)) 

你的情況下,類也可以採取List[List[String]]爲參數。雖然在我看來List[String]將是最正確的類型,但你當然有理由要求這樣做。

請注意,您與word解析器的映射是多餘的,您可以將其刪除。

+0

不幸的是,沒有。它應該有SomeEntity(List(mike),List(john),List(sara))。這只是我的問題的一個簡化版本,所以請不要在這裏查看列表中的一個單詞。 – perc

+0

@perc簽名 –

+0

你能否告訴我應該在案例分類中改變什麼? – perc