Tôi đang chơi đùa với một phân tích cú pháp toy HTML, để giúp bạn làm quen với bản thân mình combinators phân tích cú pháp thư viện của Scala:Scala: Phân tích phù hợp với thẻ
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)
}
}
Những gì tôi đang nhận ra tôi muốn là một số cách để đảm bảo tôi thẻ mở và đóng khớp với nhau.
Tôi nghĩ rằng, tôi cần một số loại tổ hợp flatMap
combinator ~ Parser[A] => (A => Parser[B]) => Parser[B]
, để tôi có thể sử dụng thẻ mở để xây dựng trình phân tích cú pháp cho thẻ đóng. Nhưng tôi không thấy bất kỳ điều gì khớp với chữ ký đó in the library.
Cách thích hợp để thực hiện việc này là gì?