Scala學習整理[第三十一章 連接符解析]

第三十一章 連接符解析(Parser工具)

package SecondWithProgrammingInScala

import scala.util.parsing.combinator.{JavaTokenParsers, RegexParsers}

/**
  * 連接符解析
  *
  * scala提供了一個連接符解釋器 ,可以藉助他實現一個編譯器 ,編譯解釋你自己的文法
  * [上下文無關:對於文法G = (N, Σ, P, S) ,其中V->w ,V總是能夠被w替換而與V的所在上下文無關]
  * [反例 ,漢語 : '本來'可以去成都的. 拿我的筆記'本來' ,"本來"出現的位置決定他的含義]
  */
class Arith extends JavaTokenParsers {
  /**
    * JavaTokenParsers 按照Java的格式識別一些參數值
    *
    * expr ::= term {'+' term | '-' term}
    * term ::= factor {'*' factor | '/' factor}
    * factor ::= floatingPointNumber | '(' expr ')'
    */
  def expr: Parser[Any] = term ~ rep("+" ~ term | "-" ~ term)

  def term: Parser[Any] = factor ~ rep("*" ~ factor | "/" ~ factor)

  def factor: Parser[Any] = floatingPointNumber | "(" ~ expr ~ ")"
}

object ArithParser extends Arith with App {
  println(parseAll(expr, "5+2*7/(3-1)"))
}

object MyParsers extends RegexParsers {
  /**
    * 按正則表達式匹配
    */
  val ident: Parser[String] =
  """[a-zA-Z_]\w*""".r
}

class JSON extends JavaTokenParsers {
  /**
    * 對象:用大括號包裹多條屬性
    * obj ::= "{" [members] "}"
    * 數組:用中括號包裹多條值
    * arr ::= "[" [values] "]"
    * 屬性:由key:value構成
    * member ::= stringLiteral ":" value
    * 多條屬性:屬性間用逗號隔開
    * members ::= member {"," member}
    * 值:可以是任意對象/數組/字符/數字/布爾值
    * value ::=
    * 多條值:用逗號分隔
    * values ::= value {"," value}
    */

  //使用^^指定輸出解析器 ,會一直追溯到最底層
  //例如從obj開始解析
  //    解析是否是{member}
  //        解析member結構
  //            調用解析器生成(k,v)鍵值對
  //        調用解析器將m鍵值對加入Map
  //    返回形成的屬性Map
  //解析obj完成
  def obj: Parser[Map[String, Any]] = "{" ~ repsep(member, ",") ~ "}" ^^ { case "{" ~ members ~ "}" => Map() ++ members }

  def arr: Parser[List[Any]] = "[" ~ repsep(value, ",") ~ "]" ^^ { case "[" ~ values ~ "]" => values }

  def member: Parser[(String, Any)] = stringLiteral ~ ":" ~ value ^^ { case k ~ ":" ~ v => (k, v) }

  def value: Parser[Any] =
    obj |
      arr |
      stringLiteral |
      floatingPointNumber ^^ (_.toDouble) |
      "null" ^^ (x => null) |
      "true" ^^ (x => true) |
      "false" ^^ (x => false)
}

object JSONParser extends JSON with App {
  val json = "{\"country\":{\"name\":\"China\",\"province\":[{\"name\":\"北京\",\"citys\":[\"東城區\"]},{\"name\":\"重慶\",\"citys\":[\"九龍坡\",\"萬州\",\"涪陵\"]},{\"name\":\"上海\",\"citys\":[\"浦東\"]},{\"name\":\"天津\",\"citys\":[\"海港\"]}]}}"

  println(parseAll(obj, json))
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章