estoy jugando un poco con un analizador de HTML juguete, para ayudar a familiarizarme con combinadores de análisis biblioteca de Scala:Scala: el análisis de juego simbólico
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)
}
}
Lo que yo estoy dando cuenta de lo que quiero es una manera de asegurarse de que mi las etiquetas de apertura y cierre coinciden.
creo que hacer eso, necesito algún tipo de flatMap
combinador ~ Parser[A] => (A => Parser[B]) => Parser[B]
, por lo que puede utilizar la etiqueta de apertura para construir el programa de análisis de la etiqueta de cierre. Pero no veo nada que coincida con esa firma in the library.
¿Cuál es la forma correcta de hacerlo?