Skip to content

Instantly share code, notes, and snippets.

@tototoshi
Created December 18, 2011 05:50
Show Gist options
  • Save tototoshi/1492501 to your computer and use it in GitHub Desktop.
Save tototoshi/1492501 to your computer and use it in GitHub Desktop.
漢数字パーサだよ
import scalaz._
import Scalaz._
import scala.util.parsing.combinator._
object KanjiNumberParser extends RegexParsers {
def one = "一" ^^ { _ => 1L }
def two = "二" ^^ { _ => 2L }
def three = "三" ^^ { _ => 3L }
def four = "四" ^^ { _ => 4L }
def five = "五" ^^ { _ => 5L }
def six = "六" ^^ { _ => 6L }
def seven = "七" ^^ { _ => 7L }
def eight = "八" ^^ { _ => 8L }
def nine = "九" ^^ { _ => 9L }
def oneDigit =
one | two | three | four | five | six | seven | eight | nine
def ju = opt(oneDigit) <~ "十" ^^ { n => (n | 1L) * 10L }
def hyaku = opt(oneDigit) <~ "百" ^^ { n => (n | 1L) * 100L }
def sen = opt(oneDigit) <~ "千" ^^ { n => (n | 1L) * 1000L }
def threeDigits = opt(sen) ~ opt(hyaku) ~ opt(ju) ~ opt(oneDigit) ^^ {
case a ~ b ~ c ~ d => ~ (a |+| b |+| c |+| d)
}
def man = opt(threeDigits) <~ "万" ^^ { n => (n | 1L) * 10000L }
def oku = opt(threeDigits) <~ "億" ^^ { n => (n | 1L) * 10000L * 10000L }
def cho = opt(threeDigits) <~ "兆" ^^ { n => (n | 1L) * 10000L * 10000L * 10000L }
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 {
println(KanjiNumberParser.parse("千五百兆二千二億三千五百十九万百一"))
}
/*
[info] Running Main
[1.18] parsed: 1500200235190101
*/
@tototoshi
Copy link
Author

な、なんだってー!

@xuwei-k
Copy link

xuwei-k commented Dec 18, 2011

あと

case a ~ b ~ c ~ d => (a |+| b |+| c |+| d) | 0L

case a ~ b ~ c ~ d => ~ (a |+| b |+| c |+| d)

って書けば、零元を明示的に書かなくて、短く書けて素敵!ってなるんじゃなイカ!?

https://github.com/scalaz/scalaz/blob/6.0.3/core/src/main/scala/scalaz/OptionW.scala#L80

@tototoshi
Copy link
Author

短く書けて素敵!

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