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))
}
}
ebnf范式_使用Scala基于词法单元的解析器定制EBNF范式文法解析相关推荐
- abnf java实现_详细讲解如何利用Java实现组合式解析器?
简介:Ward Cunningham 曾经说过,干净的代码清晰地表达了代码编写者所 想要表达的东西,而优美的代码则更进一步,优美的代码看起来就像是专门为了 要解决的问题而存在的.在本文中,我们将展示一 ...
- python的网页解析器_网页解析器(BeautifulSoup)-- Python
分享一下关于 Python的网页解析器(BeautifulSoup) BeautifulSoup解析器 为了实现解析器,可以选择使用正则表达式.html.parser.BeautifulSoup.lx ...
- flex bison解析json文件_每秒解析千兆字节的 JSON 解析器开源了
本文转自我们的网站 InfoQ,译者无明.除了推荐 simdjson 之外,还想测试一下微信平台编辑器的代码样式功能. 事实证明,微信文章的代码展示能力很强了.非常棒. 近日,GitHub 开源了一 ...
- java 解析器_高性能Java解析器实现过程详解
如果你没有指定数据或语言标准的或开源的Java解析器, 可能经常要用Java实现你自己的数据或语言解析器.或者,可能有很多解析器可选,但是要么太慢,要么太耗内存,或者没有你需要的特定功能.或者开源解析 ...
- csv文件示例_自己动手? -一个简单的CSV解析器示例
csv文件示例 Download source code - 2.7 MB 下载源代码2.7 MB 目录 (Table of Contents) Introduction 介绍 The Dataset ...
- 设计模式学习(四):基于Builder模式的歌词解析器
一.前言 上篇文章(设计模式学习(三):生成器(Builder)模式)记录了 Builder 模式的具体内容,这次使用C语言来实现一个实际的例子--基于Builder模式的歌词解析器. 本文的示例来自 ...
- Spring源码深度解析(郝佳)-学习-源码解析-基于注解切面解析(一)
我们知道,使用面积对象编程(OOP) 有一些弊端,当需要为多个不具有继承关系的对象引入同一个公共的行为时,例如日志,安全检测等,我们只有在每个对象引用公共的行为,这样程序中能产生大量的重复代码,程序就 ...
- 第五章 多范式的编程语言Scala
第五章 多范式的编程语言Scala 1. Scala入门 1.1 Scala概述 1.1.1 为什么学习Scala Spark-新一代内存级大数据计算框架, 是大数据的重要内容 Spark就是使用Sc ...
- 让解析器可以快速处理词法单元之间的空格
2019独角兽企业重金招聘Python工程师标准>>> 空格在字符串中时必要的字符,如果在字符串解析中,空格时必须要处理的. rules / tokens 分别定义区分空格的 rul ...
最新文章
- 根号均摊 ---- E. Xenia and Tree(树形dp + 暴力根号均摊)
- vs2010发布、打包安装程序(超全超详细)
- tp5中mysql使用REGEXP 正则匹配
- 当女朋友问你会不会出轨的时候,该怎么回答?
- 单片机矩阵消抖延时c语言,单片机矩阵按键定时器消抖程序源码
- word List 48
- 哈工大-基于内核栈切换的进程切换
- HTML中可以有多个meta吗,HTML5中meta标签有三个主要属性是什么
- java day05【数组】
- LCD1602中文资料
- 2021 运维面试1800道题 都掌握 面试已经无敌了 看答案来吧
- centos安装office及PDF阅读器
- Excel表格常用快捷键大全
- 计算机专业总人数所占比例公式,excel统计数据所占比例的教程详解
- 洛谷P5960 【模板】差分约束算法
- 【JSP】关于The JSP specification requires that an attribute name is preceded by whitespace
- 001-查看ts版本、安装、卸载
- power 相关:(二)功耗的分析 —— power compiler
- 程序员职业资格软考——软考,你不想软就得考 (值得一看的总结)
- 外星人显卡拓展坞支持linux,外星人扩展坞可以用哪些显卡?
热门文章
- Linux的网络协议族是什么,Linux 网络协议的概述
- mysql何时会走索引
- 码云怎么创建公开的仓库_使用码云或GitHub搭建简单的个人网站(补充hexo搭建博客)...
- Eclipse 答疑:Eclipse 如何设置 Java 代码自动提示和自动补全?
- kafka告警简单方案
- java类初始化顺序_《To Be a Better Javaer》-- Java 基础篇 vol.2:面向对象
- proteus里面没有stm32怎么办_嵌入式单片机之stm32串口你懂了多少!!
- vant部署_vant ui rem配置流程
- SSRF,以weblogic为案例
- 计算机网络讨论4,计算机网络实验四