Skip to content

Instantly share code, notes, and snippets.

@halcat0x15a
Forked from tototoshi/KanjiNumberParser.scala
Created December 18, 2011 08:12
Show Gist options
  • Save halcat0x15a/1492704 to your computer and use it in GitHub Desktop.
Save halcat0x15a/1492704 to your computer and use it in GitHub Desktop.
漢数字パーサだよ
import scalaz._
import Scalaz._
import scala.util.parsing.combinator._
object KanjiNumberParser extends RegexParsers {
def one = "一" ^^^ digits(1)
def two = "二" ^^^ digits(2)
def three = "三" ^^^ digits(3)
def four = "四" ^^^ digits(4)
def five = "五" ^^^ digits(5)
def six = "六" ^^^ digits(6)
def seven = "七" ^^^ digits(7)
def eight = "八" ^^^ digits(8)
def nine = "九" ^^^ digits(9)
def oneDigit: Parser[Digit] = one | two | three | four | five | six | seven | eight | nine
def ju = opt(oneDigit) <~ "十" ^^ { _ | digits(1) }
def hyaku = opt(oneDigit) <~ "百" ^^ { _ | digits(1) }
def sen = opt(oneDigit) <~ "千" ^^ { _ | digits(1) }
def threeDigits = opt(sen) ~ opt(hyaku) ~ opt(ju) ~ opt(oneDigit) ^^ {
case a ~ b ~ c ~ d => (a +>: b +>: c +>: d +>: nil).map(_.orZero)
}
def man = opt(threeDigits) <~ "万" ^^ { _ | 10000L.digits }
def oku = opt(threeDigits) <~ "億" ^^ { _ | (10000L * 10000L).digits }
def cho = opt(threeDigits) <~ "兆" ^^ { _ | (10000L * 10000L * 10000L).digits }
def kanjiNumber = opt(cho) ~ opt(oku) ~ opt(man) ~ opt(threeDigits) ^^ {
case a ~ b ~ c ~ d => ~(a |+| b |+| c |+| d)
}
def parse(in: String) = parseAll(kanjiNumber, in)
}
object Main extends App {
KanjiNumberParser.parse("千五百兆二千二億三千五百十九万百一").map(_.longDigits assert_=== 1500200235190101L).getOrElse(throw new RuntimeException)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment