0x10と010をパースしてみよう

30分プログラム、その714。0x10と010のパースをやってみました。
Scalaは気軽にパーサ・コンビネータが使えるからいいよね。これを正規表現でやってたら、死んでた気がする。

使い方

scala> Number.parse("0x10")
res0: Int = 16

scala> Number.parse("010")
res1: Int = 8

scala> Number.parse("10")
res2: Int = 10

ソースコード

import scala.util.parsing.combinator._

object Number extends RegexParsers {
  def charToInt(c : Char) : Int =  c - '0'

  def toInt(xs : Seq[Char], base : Int) = {
    xs.foldLeft(0){ (x,y) =>
      x * base + charToInt(y)
    }
  }

  def oct : Parser[Int] = "[0-7]+".r ^^ { x =>  toInt(x,8) }
  def dec : Parser[Int] = "[0-9]+".r ^^ { x =>  toInt(x,10) }
  def hex : Parser[Int] = "[0-9A-Fa-f]+".r ^^ { x =>  toInt(x,16) }

  def num : Parser[Int] = ("0x" ~> hex) | ("0" ~> oct) | dec

  def parse(s : String) : Int = {
    parseAll(Number.num,s) match {
      case Success(n,_) => n
      case _ => -1
    }
  }
}