パーサ書いてると結構大小を区別しないキーワードがあったりするので、さくっと書けるようにしてみた。
trait SampleParsers extends RegexParsers {
/** 文字列に".i"を付けると大文字小文字を区別せずマッチさせるようにする拡張 */
implicit class IgnoreCaseString(s: String) {
def i: Parser[String] = ("""(?i)\Q""" + s + """\E""").r
}
def keyword: Parser[String] = "keyword:".i
def value: Parser[String] = "[a-zA-Z0-9]+".r
def parameter: Parser[(String,String)] = keyword ~ value ^^ { case k~v => (k,v) }
}
ちなみに、specs2にはパーサコンビネータ用のマッチャーがある。
パーサ全体を通してだけでなく、細かいパーサ単位でテストを記述しておけるので、ちょっとずつ動きを確認しながら積み上げていける。
import org.specs2.mutable.Specification
import org.specs2.matcher.ParserMatchers
class SampleParsersSpec extends Specification with ParserMatchers {
"keyword" should {
"match with ignore-case" in {
keyword must succeedOn("KEYWORD:")
keyword must succeedOn("Keyword:")
keyword must succeedOn("keyWord:")
}
"fail in other pattern" in {
keyword must failOn("key-word:")
}
}
}
テストもちゃんと通るけど、IntellijIDEAで構文エラーになるのはなぜ…。