Skip to content

Instantly share code, notes, and snippets.

@akr4
Created October 12, 2011 10:23
Show Gist options
  • Save akr4/1280844 to your computer and use it in GitHub Desktop.
Save akr4/1280844 to your computer and use it in GitHub Desktop.
hosts parser
import scala.util.parsing.combinator._
/**
* <hosts> ::= { <line> }
* <line> ::= <entry> | [ <comment> ] <eol>
* <entry> ::= <ip-address> <hostnames> [ <comment> ] <eol>
* <ip-address> ::= <ipv4-address> | <ipv6-address>
* <ipv4-address> ::= "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}"
* <ipv6-address> ::= ...
* <hostnames> ::= <hostname> { <hostname> }
* <hostname> ::= [a-zA-Z\.]+
* <eol> ::= "\r?\n"
* <comment> ::= #.*
*/
class HostsParser extends RegexParsers {
import java.net.InetAddress
case class Comment(text: String = "")
override val whiteSpace = """[ \t]+""".r
def hosts: Parser[Map[InetAddress, Set[String]]] = (line*) ^^ { lines =>
val map = new collection.mutable.HashMap[InetAddress, Set[String]]
lines.flatMap(e => e).foreach[Any] {
case (key, value) => {
if (map.contains(key)) map(key) = map(key) ++ value
else map += (key -> value)
}
}
map.toMap
}
def line: Parser[Option[Pair[InetAddress, Set[String]]]]
= (entry | opt(comment)~eol) ^^ {
case entry : Pair[InetAddress, Set[String]] => Some(entry)
case _ => None
}
def entry: Parser[Pair[InetAddress, Set[String]]]
= ipAddress~(hostname*)~opt(comment)~eol ^^
{
case ipAddress~hostnames~_~eol => (ipAddress -> hostnames.toSet)
}
def ipAddress: Parser[InetAddress] = ipv4Address | ipv6Address
def ipv4Address: Parser[InetAddress] = """[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}""".r ^^ (s => InetAddress.getByName(s))
def ipv6Address: Parser[InetAddress] = """[:%a-z0-9]+""".r ^^ (s => InetAddress.getByName(s))
def hostname: Parser[String] = """[a-zA-Z0-9\.]+""".r
def eol: Parser[Any] = """\r?\n""".r ^^ (s => "")
def comment: Parser[Comment] = """#.*""".r ^^ (s => Comment(s))
}
object Main extends HostsParser with App {
import scala.io.Source
val hostsFile = Source.fromFile(args(0)).mkString
println("=====================================")
println(hostsFile)
println("=====================================")
println(parseAll(hosts, hostsFile))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment