Created
August 6, 2011 14:26
-
-
Save casualjim/1129380 to your computer and use it in GitHub Desktop.
A ParserCombinator base ipv6 address parser
This file contains hidden or 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
trait IPv6AddressParser extends RegexParsers { | |
def hexDigit = """[0123456789abcdefABCDEF]""".r | |
def decOctet = """25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d""".r | |
def dottedDecOctet = decOctet <~ "." | |
private def IPv4Address = dottedDecOctet ~ dottedDecOctet ~ dottedDecOctet ~ decOctet ^^ { | |
case a ~ b ~ c ~ d ⇒ a + "." + b + "." + c + "." + d | |
} | |
private def h16_2 = repN(2, hexDigit) | |
private def h16_3 = repN(3, hexDigit) | |
private def h16_4 = repN(4, hexDigit) | |
private def h16_multi = (h16_4 | h16_3 | h16_2) ^^ { _ mkString "" } | |
private def h16 = h16_multi | hexDigit | |
private def h16Colon = h16 ~ ":" ^^ { case a ~ b ⇒ a + b } | |
private def h16Colon_2 = h16Colon ~ h16Colon ^^ { case a ~ b ⇒ a + b } | |
private def h16Colon_3 = repN(3, h16Colon) ^^ { _ mkString "" } | |
private def h16Colon_4 = repN(4, h16Colon) ^^ { _ mkString "" } | |
private def h16Colon_5 = repN(5, h16Colon) ^^ { _ mkString "" } | |
private def h16Colon_6 = repN(6, h16Colon) ^^ { _ mkString "" } | |
private def h16Wrap(parser: Parser[String]): Parser[String] = parser ~ h16 ^^ { case a ~ b ⇒ a + b } | |
private def h16ColonN(max: Int) = max match { | |
case 6 ⇒ h16Wrap(h16Colon_6) | h16Wrap(h16Colon_5) | h16Wrap(h16Colon_4) | h16Wrap(h16Colon_3) | h16Wrap(h16Colon_2) | h16Wrap(h16Colon) | |
case 5 ⇒ h16Wrap(h16Colon_5) | h16Wrap(h16Colon_4) | h16Wrap(h16Colon_3) | h16Wrap(h16Colon_2) | h16Wrap(h16Colon) | |
case 4 ⇒ h16Wrap(h16Colon_4) | h16Wrap(h16Colon_3) | h16Wrap(h16Colon_2) | h16Wrap(h16Colon) | |
case 3 ⇒ h16Wrap(h16Colon_3) | h16Wrap(h16Colon_2) | h16Wrap(h16Colon) | |
case 2 ⇒ h16Wrap(h16Colon_2) | h16Wrap(h16Colon) | |
case 1 ⇒ h16Wrap(h16Colon) | |
} | |
private def h16Colonh16N(max: Int) = h16ColonN(max) | h16 | |
private def nH16Colon(n: Int) = repN(n, h16Colon) ^^ { _ mkString "" } | |
private def flatOpt(parser: ⇒ Parser[String]): Parser[String] = opt(parser) ^^ { _ getOrElse "" } | |
private def ls32 = (h16Colon ~ h16 ^^ { case a ~ b ⇒ a + b }) | IPv4Address | |
private def ip6_1 = nH16Colon(6) ~ ls32 ^^ { case a ~ b ⇒ a + b } | |
private def ip6_2 = "::" ~ nH16Colon(5) ~ ls32 ^^ { case a ~ b ~ c ⇒ a + b + c } | |
private def ip6_3 = flatOpt(h16) ~ "::" ~ nH16Colon(4) ~ ls32 ^^ { case a ~ b ~ c ~ d ⇒ a + b + c + d } | |
private def ip6_4 = flatOpt(h16Colonh16N(1)) ~ "::" ~ nH16Colon(3) ~ ls32 ^^ { case a ~ b ~ c ~ d ⇒ a + b + c + d } | |
private def ip6_5 = flatOpt(h16Colonh16N(2)) ~ "::" ~ nH16Colon(2) ~ ls32 ^^ { case a ~ b ~ c ~ d ⇒ a + b + c + d } | |
private def ip6_6 = flatOpt(h16Colonh16N(3)) ~ "::" ~ nH16Colon(1) ~ ls32 ^^ { case a ~ b ~ c ~ d ⇒ a + b + c + d } | |
private def ip6_7 = flatOpt(h16Colonh16N(4)) ~ "::" ~ ls32 ^^ { case a ~ b ~ c ⇒ a + b + c } | |
private def ip6_8 = flatOpt(h16Colonh16N(5)) ~ "::" ~ h16 ^^ { case a ~ b ~ c ⇒ a + b + c } | |
private def ip6_9 = flatOpt(h16Colonh16N(6)) ~ "::" ^^ { case a ~ b ⇒ a + b } | |
def IP6Address = ip6_1 | ip6_2 | ip6_3 | ip6_4 | ip6_5 | ip6_6 | ip6_7 | ip6_8 | ip6_9 | |
override def skipWhitespace = false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment