日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ebnf范式_使用Scala基于词法单元的解析器定制EBNF范式文法解析

發(fā)布時(shí)間:2025/3/11 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ebnf范式_使用Scala基于词法单元的解析器定制EBNF范式文法解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

近期在做Oracle遷移到Spark平臺(tái)的項(xiàng)目上遇到了一些平臺(tái)公式翻譯為SparkSQL(on Hive)的需求,而Spark采用親媽語(yǔ)言Scala進(jìn)行開發(fā)。下面是個(gè)意外,被論文查重了,移步至我的Leanote博客查看點(diǎn)我,先亂碼一段時(shí)間[分后,擬使中的EB式,進(jìn)行基于@#@#@法解析。

平臺(tái)公式及翻譯后的SparkSQL

平臺(tái)公式的樣子如下所示:

if (XX1_m001[D003]="邢おb7骯α?薇" || XX1_m001[H003]

這里面字段值"邢おb7骯α?薇"為這個(gè)的目的是為了測(cè)試各種字符集是否都能匹配滿足。

那么對(duì)應(yīng)的SparkSQL應(yīng)該是這個(gè)樣子的,由于是使用的Hive on Spark,因而長(zhǎng)得跟Oracle的SQL語(yǔ)句差不多:

SELECT COUNT(H022) FROM XX1_m001 WHERE (XX1_m001.D003='邢おb7骯α?薇' OR XX1_m001.H003

總體而言比較簡(jiǎn)單,因?yàn)槲抑皇窍朐谶@里做一個(gè)Demo。

平臺(tái)公式的EBNF范式及詞法解析設(shè)計(jì)

expr-condition ::= tableName "[" valueName "]" comparator Condition

expr-front ::= expr-condition (("&&"|"||")expr-front)*

expr-back ::= tableName "[" valueName "," operator "]"

expr ::= "if" expr-front "then" expr-back

其中詞法定義如下

operator => [SUM,COUNT]

tableName,valueName =>ident #ident為關(guān)鍵字

comparator => ["=",">=","<=",">","

Condition => stringLit #stringLit為字符串常量

使用Scala基于詞法單元的解析器解析上述EBNF文法

Scala基于詞法單元的解析器是需要繼承StandardTokenParsers這個(gè)類的,該類提供了很方便的解析函數(shù),以及詞法集合。

我們可以通過(guò)使用lexical.delimiters列表來(lái)存放在文法翻譯器執(zhí)行過(guò)程中遇到的分隔符,使用lexical.reserved列表來(lái)存放執(zhí)行過(guò)程中的關(guān)鍵字。

比如,我們參照平臺(tái)公式,看到"=",">=","<=",">","=","<=",">","

表現(xiàn)在代碼中是醬紫的:

lexical.delimiters += ("=",">=","<=",">","

lexical.reserved += ("if","then","SUM","COUNT")

是不是so easy~。

我們?cè)賮?lái)看一下如何使用基于詞法單元的解析器解析前面我們?cè)O(shè)計(jì)的EBNF文法呢。我在這里先上代碼:

class ExprParsre extends StandardTokenParsers{

lexical.delimiters += ("=",">=","<=",">","

lexical.reserved += ("if","then","SUM","COUNT")

def expr: Parser[String] = "if" ~ expr_front ~ "then" ~ expr_back ^^{

case "if" ~ exp1 ~ "then" ~ exp2 => exp2 + " WHERE " +exp1

}

def expr_priority: Parser[String] = opt("(") ~ expr_condition ~ opt(")") ^^{

case Some("(") ~ conditions ~ Some(")") => "(" + conditions +")"

case Some("(") ~ conditions ~ None => "(" + conditions

case None ~ conditions ~ Some(")") => conditions +")"

case None ~ conditions ~ None => conditions

}

def expr_condition: Parser[String] = ident ~ "[" ~ ident ~ "]" ~ ("="|">="|"<="|">"|"

case ident1~"["~ident2~"]"~"="~stringList => ident1 + "." + ident2 +"='" + stringList +"'"

case ident1~"["~ident2~"]"~">="~stringList => ident1 + "." + ident2 +">='" + stringList +"'"

case ident1~"["~ident2~"]"~"<="~stringList => ident1 + "." + ident2 +"<='" + stringList +"'"

case ident1~"["~ident2~"]"~">"~stringList => ident1 + "." + ident2 +">'" + stringList +"'"

case ident1~"["~ident2~"]"~" ident1 + "." + ident2 +"

case ident1~"["~ident2~"]"~"!="~stringList => ident1 + "." + ident2 +"!='" + stringList +"'"

}

def comparator: Parser[String] = ("&&"|"||") ^^{

case "&&" => " AND "

case "||" => " OR "

}

def expr_front: Parser[String] = expr_priority ~ rep(comparator ~ expr_priority) ^^{

case exp1 ~ exp2 => exp1 + exp2.map(x =>{x._1 + " " + x._2}).mkString(" ")

}

def expr_back: Parser[String] = ident ~ "[" ~ ident ~ "," ~ ("SUM"|"COUNT") ~ "]" ^^ {

case ident1~"["~ident2~","~"COUNT"~"]" => "SELECT COUNT("+ ident2.toString() +") FROM " + ident1.toString()

case ident1~"["~ident2~","~"SUM"~"]" => "SELECT SUM("+ ident2.toString() +") FROM " + ident1.toString()

}

def parserAll[T]( p : Parser[T], input :String) = {

phrase(p)( new lexical.Scanner(input))

}

}

總結(jié)

以上是生活随笔為你收集整理的ebnf范式_使用Scala基于词法单元的解析器定制EBNF范式文法解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。