我玩弄玩具HTML解析器,以帮助自己熟悉与Scala的解析组合子库:斯卡拉:解析匹配令牌
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)
}
}
什么我意识到我需要一些方法来确保我的打开和关闭标签匹配。
我认为要做到这一点,我需要某种flatMap
组合器〜Parser[A] => (A => Parser[B]) => Parser[B]
, ,所以我可以使用开始标记来构造结束标记的解析器。但我没有看到任何匹配in the library的签名。
这样做的正确方法是什么?