Ich spiele um mit einem Spielzeug-HTML-Parser, um mir die Parsing combinators Bibliothek mit Scala vertraut machen:Scala: Parsen passende Token
import scala.util.parsing.combinator._
sealed abstract class Node
case class TextNode(val contents : String) extends Node
case class Element(
val tag : String,
val attributes : Map[String,Option[String]],
val children : Seq[Node]
) extends Node
object HTML extends RegexParsers {
val node: Parser[Node] = text | element
val text: Parser[TextNode] = """[^<]+""".r ^^ TextNode
val label: Parser[String] = """(\w[:\w]*)""".r
val value : Parser[String] = """("[^"]*"|\w+)""".r
val attribute : Parser[(String,Option[String])] = label ~ (
"=" ~> value ^^ Some[String] | "" ^^ { case _ => None }
) ^^ { case (k ~ v) => k -> v }
val element: Parser[Element] = (
("<" ~> label ~ rep(whiteSpace ~> attribute) <~ ">")
~ rep(node) ~
("</" ~> label <~ ">")
) ^^ {
case (tag ~ attributes ~ children ~ close) => Element(tag, Map(attributes : _*), children)
}
}
Was ich realisieren möchte ich irgendwie meine, um sicherzustellen, ist öffnende und schließende Tags passen zusammen.
Ich denke, das zu tun, ich brauche eine Art von flatMap
combinator ~ Parser[A] => (A => Parser[B]) => Parser[B]
, so kann ich das Starttag verwenden Sie den Parser für das schliessende Tag zu konstruieren. Aber ich sehe nichts, das dieser Unterschrift in the library entspricht.
Was ist der richtige Weg, dies zu tun?