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

前言

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

平臺公式及翻譯后的SparkSQL

平臺公式的樣子如下所示:

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

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

那么對應的SparkSQL應該是這個樣子的,由于是使用的Hive on Spark,因而長得跟Oracle的SQL語句差不多:

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

總體而言比較簡單,因為我只是想在這里做一個Demo。

平臺公式的EBNF范式及詞法解析設計

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為關鍵字

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

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

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

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

我們可以通過使用lexical.delimiters列表來存放在文法翻譯器執行過程中遇到的分隔符,使用lexical.reserved列表來存放執行過程中的關鍵字。

比如,我們參照平臺公式,看到"=",">=","<=",">","=","<=",">","

表現在代碼中是醬紫的:

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

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

是不是so easy~。

我們再來看一下如何使用基于詞法單元的解析器解析前面我們設計的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))

}

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538245.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538245.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538245.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鉆石指標和完美的計算

鉆石的高度計算公式為&#xff1a;鉆石的高度直徑的三次方&#xff08;單位毫米&#xff09;0.00366(允許有0.03克拉的誤差)例如&#xff0c;0.5克拉的鉆石直徑是5.01毫米&#xff0c;則它的高為&#xff1a;5.01*5.01*5.01*0.003660.46說明0.5克拉的鉆石直徑只有0.46克拉鉆石的…

linux開機自動ZFS,linux – 為什么重新啟動導致我的ZFS鏡像的一面成為UNAVAIL?

我最近剛剛將批量數據存儲池(ZFS OnLinux 0.6.2,Debian Wheezy)從單設備vdev配置遷移到雙向鏡像vdev配置.之前的池配置是&#xff1a;NAME STATE READ WRITE CKSUMakita ONLINE 0 0 0ST4000NM0033-Z1Z1A0LQ ONLINE 0 0 0在重新啟動完成后一切都很好(我在重新啟動完成后啟動了一…

華為交換機默認vlan都是通的嗎_【思唯網絡學院】華為交換機常用的三種vlan劃分方法...

端口類型在學習劃分vlan前&#xff0c;必須要了解華為交換機的端口類型&#xff0c;以及他們的使用方法&#xff0c;因為端口的類型在實際配置中是必須會用到的&#xff0c;因為下面的vlan劃分會用到。1、Access類型端口執行命令port default vlan vlan-id&#xff0c;將端口加…

Spark應用日志級別設置

Spark-core包設置默認的日志級別為info&#xff0c;所以我們才看到一大堆日志信息。 開發的時候&#xff0c;把print的日志掩蓋了。 方法一&#xff1a; 代碼中設置日志級別 JavaSparkContext contextnew JavaSparkContext(conf); context.setLogLevel("warn"); 方…

linux 恢復操作系統,如何恢復Linux操作系統的GRUB引導程?

先使用一張修復盤進入grub&#xff0c;或者利用其他linux恢復盤等等進入linux系統&#xff0c;然后進入grub控制臺。總之就是想盡辦法進入一個控制臺就是了。然后準備引導進入硬盤上的Linux系統。如下&#xff1a;  grub> root (hd0,10)  grub> kernel /boot/vmlinuz…

Centos 7初始化腳本

今天跟大家分享一個我自己寫的Linux初始化腳本&#xff0c;自認為寫的不是很好。希望看到這篇文章的你&#xff0c;能暫時停留下你的腳步&#xff0c;給些修改意見&#xff0c;或者有什么需要補充的地方都可以提出來&#xff0c;大家共同進步&#xff0c;謝謝&#xff01;此腳本…

Hive-sql與SQL的區別

總體一致&#xff1a; Hive-sql與SQL基本上一樣&#xff0c;因為當初的設計目的&#xff0c;就是讓會SQL不會編程MapReduce的也能使用Hadoop進行處理數據。 因此&#xff0c;大膽使用SQL的&#xff0c;如果遇到不對的&#xff0c;再查。 區別&#xff1a; Hive沒有delete和u…

python閏年多一天_記一個 python datetime 閏年問題

python中datetime是比較常用的&#xff0c;平時用起來也沒什么問題&#xff0c;但是今天2020年2月29日服務器卻開始報錯了&#xff0c;這里有個平時難以注意的坑服務器上跑的是新浪網的爬蟲&#xff0c;抓取的頁面信息中帶有日期 XX月XX日&#xff0c;需要strfptime轉化一下&am…

linux find 按類型查找,Linux find查找find命令詳解

玩蛇網推薦圖文教程&#xff1a;python 列表Linux命令有很多&#xff0c;今天要介紹的是常用的基礎命令中的find命令。find是Linux系統管理員所喜愛用的必備工具命令之一&#xff0c;它的作用是可以很輕松地找到你想要的文件&#xff0c;一個命令就可以在眾多文件中找到你的目標…

window安裝gcc編譯器

在使用 GraphLab Create 時&#xff0c;導入包失敗&#xff0c;提示libs沒有的導入&#xff0c;而這些libs的編譯是需要gcc。 1、訪問&#xff1a;http://www.mingw.org/ 下載。 2、雙擊安裝 3、安裝好后會彈出下面的組件安裝界面 3、找到mingw32-gcc-g&#xff08;注意cl…

視頻AI,助力體育賽事轉播走進智能時代

摘要&#xff1a;2018俄羅斯世界杯經過近20天的激戰&#xff0c;已經進入到最關鍵的階段。本次賽事除了精彩紛呈的比賽之外&#xff0c;還加入很多高科技的元素&#xff0c;例如門線、VAR技術等等。讓本屆世界杯成為科技含量最高的一屆世界杯。2018俄羅斯世界杯經過近20天的激戰…

python求同構數_用c語言求1到1000的同構數_后端開發

python與平臺有關嗎_后端開發Python與平臺無關&#xff0c;因為Python是跨平臺的語言&#xff0c;Python作為腳本語言&#xff0c;是解釋執行的&#xff0c;所以能跨平臺&#xff0c;前提是必須要有一個對應的解釋器。具體請看實例&#xff1a;python中count函數的用法詳解_后端…

element表格實現樹形全選_很實用!word中全選的快捷鍵介紹及使用方法

全選快捷鍵可以提高我們在操作word時工作效率&#xff0c;在操作Word2003中怎么對文檔中的文字進行全選呢?下面為大家提供幾種全選的方法&#xff0c;絕對好用。Word怎樣全選?方法一、使用Word全選快捷鍵“CtrlA”進行全選(也適用于電子表格);方法二、展開菜單欄中的“編輯”…

am3352 linux 內核 編譯,am335x uboot, kernel 編譯

一、設置環境變量// 寫在家目錄下面的 .bashrc 里面export KERNEL_PATH~/aplex/kernel3.2.0 // kernel 路徑export UBOOT_PATH~/aplex/uboot2011.09 // u-boot 路勁export ROOTFS_PATH~/aplex/filesystemexport TOOLFS_PATH~/aplex/toolsexport ARCHarm // 設置平臺類型export …

Docker的應用場景

原文鏈接&#xff1a;http://blog.csdn.net/dev_csdn/article/details/78424803 ------------------------------------------------------------------- Docker是開發人員和系統管理員構建&#xff0c;發布和運行分布式應用程序的開放平臺&#xff0c;可以在筆記本電腦、數據…

cad多段線畫圓弧方向_【學員分享】CAD多段線用法

原標題&#xff1a;【學員分享】CAD多段線用法1、執行方法&#xff1a;(1)菜單欄&#xff1a;繪圖→多段線(2)繪圖功能區&#xff1a;繪圖→多段線按鈕(3)快捷鍵&#xff1a;PL2、使用方法(1)多段線與直線的區別&#xff1a;直線每一段都是分開的&#xff0c;圖畫完后不是一個整…

linux 視頻編輯 ffmpeg,ffmpeg轉碼視頻真的好用!(ffmpeg的簡單使用方法)

說明轉碼和編輯視頻今天用Android Studio(后面簡稱AS)里的模擬器給系統錄屏&#xff0c;用來展示OpenGL可視化的東西&#xff0c;打算上傳B站&#xff0c;后來發現AS只能保存webm格式和GIF格式的視頻&#xff0c;并且文件體積巨大&#xff0c;視頻圖像也是順時針旋轉的。沒辦法…

requests庫入門09-OAUTH認證

實際登陸中&#xff0c;認證用到的token會變的&#xff0c;不過可以在GIthub設置一個私人token。 如圖&#xff0c;登錄GIthub&#xff0c;然后用戶下面選擇Settings/Developer settings/Personal access tokens,點擊Generate new token&#xff0c;然后隨便輸個描述&#xff0…

mysql期末考試試卷_mysql試題

net start mysqlfound_rows函數 返回select的總行數哪種操作能夠實現實體完整性 設置外鍵數據模型三要素&#xff1a;數據結構、數據操作、完整性約束&#xff0c;哪項不屬于數據模型 網狀模型(層次、網狀、關系、面向對象模型)觸發器主要用于監視某個表的insert、update以及de…

深入了解HashMap

什么是hash&#xff1f;哈希算法將任意長度的二進制值映射為較短的固定長度的二進制值&#xff0c;這個小的二進制值稱為哈希值。哈希值是一段數據唯一且極其緊湊的數值表示形式。如果散列一段明文而且哪怕只更改該段落的一個字母&#xff0c;隨后的哈希都將產生不同的值。要找…