Skip to content

Instantly share code, notes, and snippets.

@rirakkumya
Created March 22, 2012 11:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rirakkumya/2157789 to your computer and use it in GitHub Desktop.
Save rirakkumya/2157789 to your computer and use it in GitHub Desktop.
漢数字変換 by scala parser combinator
libraryDependencies += "org.scala-tools.testing" %% "scalacheck" % "1.9"
import scala.util.parsing.combinator._
object PrsKsj {
def apply(s:String) = {
val p = new PrsKsj
p.parseAll(p.root,s)
}
}
class PrsKsj extends JavaTokenParsers {
val k2d = Seq("壱","弐","参","四","五","六","七","八","九") zip (1 to 9) toMap
def root = opt(千の位) ~ opt(百の位) ~ opt(十の位) ~ opt(一の位) ^^ {
case s ~ h ~ j ~ i => Seq(s,h,j,i).foldLeft(0){(l,r) => l + r.getOrElse(0)}
}
def ksj = "壱" | "弐" | "参" | "四" | "五" | "六" | "七" | "八" | "九"
def 一の位 = ksj ^^ k2d
def 十の位 = unitPrs("拾",10)
def 百の位 = unitPrs("百",100)
def 千の位 = unitPrs("千",1000)
def unitPrs(u:String,mul:Int) = opt(ksj) <~ u ^^ {
case Some(d) => k2d(d) * mul
case None => mul
}
}
object Main extends App {
Seq(("壱",1),("百",100),("千",1000),("千壱",1001),("千弐拾",1020),
("百五",105),("六千参百拾壱",6311),("unmatch data",33)
) foreach {t => PrsKsj(t._1) match {
case x if(x.successful) => print("test:" + t);assert(x.get == t._2);println(":OK")
case x => println(t,x)
}}
}
import org.scalacheck._
import Prop._
object KsjSpecification extends Properties("漢数字テスト") {
case class KsjMaker(ksj:Seq[(String,Int)]) {
val ksjPair = ksj map {_._1} zip Seq("千","百","拾","")
val 漢数字 = ksjPair filter(_._1 != "") map {x => x._1 + x._2} mkString("")
val アラビア数字 = ksj map {_._2} zip Seq(1000,100,10,1) map {case (a,b) => a * b} sum
}
val seed = Seq("","壱","弐","参","四","五","六","七","八","九") zip (0 to 9)
val gen = for{
th <- Gen.oneOf(seed)
h <- Gen.oneOf(seed)
t <- Gen.oneOf(seed)
o <- Gen.oneOf(seed)
} yield KsjMaker(th :: h :: t :: o :: Nil)
property("ランダム選択") = forAll(gen) { x =>
collect("%s(%s)".format(x.漢数字,x.アラビア数字)) {
PrsKsj(x.漢数字).get == x.アラビア数字
}
}
}
@rirakkumya
Copy link
Author

宿題: 万・億・兆の変換も対応する

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment