1. 程式人生 > >Scala學習整理[第三十一章 連線符解析]

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)) }