Created
March 22, 2012 11:29
-
-
Save rirakkumya/2157789 to your computer and use it in GitHub Desktop.
漢数字変換 by scala parser combinator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
libraryDependencies += "org.scala-tools.testing" %% "scalacheck" % "1.9" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
}} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.アラビア数字 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
宿題: 万・億・兆の変換も対応する