欢迎来到【c语言源码代码】【酷趣源码】【网校课堂源码】lex源码 github-皮皮网网站!!!

皮皮网

【c语言源码代码】【酷趣源码】【网校课堂源码】lex源码 github-皮皮网 扫描左侧二维码访问本站手机端

【c语言源码代码】【酷趣源码】【网校课堂源码】lex源码 github

2024-11-30 08:34:32 来源:{typename type="name"/} 分类:{typename type="name"/}

1.TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现
2.Epub如何编辑
3.snownlp和nltk什么关系
4.CALL 、libc++、libc

lex源码 github

TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现

       本文是 TiDB 源码阅读系列文章的第五篇,主要内容围绕 SQL Parser 功能实现进行讲解。内容源自社区伙伴马震(GitHub ID:mz)的投稿。系列文章的c语言源码代码目的是与数据库研究者及爱好者深入交流,收到了社区的积极反馈。后续,期待更多伙伴加入 TiDB 的探讨与分享。

       TiDB 的源码阅读系列文章,帮助读者系统性地学习 TiDB 内部实现。最近的《SQL 的一生》一文,全面阐述了 SQL 语句处理流程,从接收网络数据、MySQL 协议解析、SQL 语法解析、查询计划制定与优化、执行直至返回结果。

       其中,SQL Parser 的功能是将 SQL 语句按照 SQL 语法规则进行解析,将文本转换为抽象语法树(AST)。此功能需要一定背景知识,下文将尝试介绍相关知识,酷趣源码以帮助理解这部分代码。

       TiDB 使用 goyacc 根据预定义的 SQL 语法规则文件 parser.y 生成 SQL 语法解析器。这一过程可在 TiDB 的 Makefile 文件中看到,通过构建 goyacc 工具,使用 goyacc 依据 parser.y 生成解析器 parser.go。

       goyacc 是 yacc 的 Golang 版本,因此理解语法规则定义文件 parser.y 及解析器工作原理之前,需要对 Lex & Yacc 有所了解。Lex & Yacc 是用于生成词法分析器和语法分析器的工具,它们简化了编译器的编写。

       下文将详细介绍 Lex & Yacc 的工作流程,以及生成解析器的过程。我们将从 Lex 根据用户定义的 patterns 生成词法分析器,词法分析器读取源代码并转换为 tokens 输出,以及 Yacc 根据用户定义的语法规则生成语法分析器等角度进行阐述。

       生成词法分析器和语法分析器的过程,用户需为 Lex 提供 patterns 的定义,为 Yacc 提供语法规则文件。这两种配置都是文本文件,结构相同,分为三个部分。我们将关注中间规则定义部分,网校课堂源码并通过一个简单的例子来解释。

       Lex 的输入文件中,规则定义部分使用正则表达式定义了变量、整数和操作符等 token 类型。例如整数 token 的定义,当输入字符串匹配正则表达式时,大括号内的动作会被执行,将整数值存储在变量yylval 中,并返回 token 类型 INTEGER 给 Yacc。

       而 Yacc 的语法规则定义文件中,第一部分定义了 token 类型和运算符的结合性。四种运算符都是左结合,同一行的运算符优先级相同,不同行的运算符,后定义的行具有更高的优先级。语法规则使用 BNF 表达,大部分现代编程语言都可以使用 BNF 表示。

       表达式解析是生成表达式的逆向操作,需要将语法树归约到一个非终结符。Yacc 生成的语法分析器使用自底向上的归约方式进行语法解析,同时使用堆栈保存中间状态。通过一个表达式 x + y * z 的postgres 源码下载解析过程,我们可以理解这一过程。

       在这一过程中,读取的 token 压入堆栈,当发现堆栈中的内容匹配了某个产生式的右侧,则将匹配的项从堆栈中弹出,将该产生式左侧的非终结符压入堆栈。这个过程持续进行,直到读取完所有的 tokens,并且只有启始非终结符保留在堆栈中。

       产生式右侧的大括号中定义了该规则关联的动作,例如将三项从堆栈中弹出,两个表达式相加,结果再压回堆栈顶。这里可以使用 $position 的形式访问堆栈中的项,$1 引用第一项,$2 引用第二项,以此类推。$$ 代表归约操作执行后的堆栈顶。本例的动作是将三项从堆栈中弹出,两个表达式相加,结果再压回堆栈顶。

       在上述例子中,lsd slam源码动作不仅完成了语法解析,还完成了表达式求值。一般希望语法解析的结果是一颗抽象语法树(AST),可以定义语法规则关联的动作。这样,解析完成时,我们就能得到由 nodeType 构成的抽象语法树,对这个语法树进行遍历访问,可以生成机器代码或解释执行。

       至此,我们对 Lex & Yacc 的原理有了大致了解,虽然还有许多细节,如如何消除语法的歧义,但这些概念对于理解 TiDB 的代码已经足够。

       下一部分,我们介绍 TiDB SQL Parser 的实现。有了前面的背景知识,对 TiDB 的 SQL Parser 模块的理解会更易上手。TiDB 使用手写的词法解析器(出于性能考虑),语法解析采用 goyacc。我们先来看 SQL 语法规则文件 parser.y,这是生成 SQL 语法解析器的基础。

       parser.y 文件包含 多行代码,初看可能令人感到复杂,但该文件仍然遵循我们之前介绍的结构。我们只需要关注第一部分 definitions 和第二部分 rules。

       第一部分定义了 token 类型、优先级、结合性等。注意 union 结构体,它定义了在语法解析过程中被压入堆栈的项的属性和类型。压入堆栈的项可能是终结符,也就是 token,它的类型可以是 item 或 ident;也可能是非终结符,即产生式的左侧,它的类型可以是 expr、statement、item 或 ident。

       goyacc 根据这个 union 在解析器中生成对应的 struct。在语法解析过程中,非终结符会被构造成抽象语法树(AST)的节点 ast.ExprNode 或 ast.StmtNode。抽象语法树相关的数据结构定义在 ast 包中,它们大都实现了 ast.Node 接口。

       ast.Node 接口有一个 Accept 方法,接受 Visitor 参数,后续对 AST 的处理主要依赖这个 Accept 方法,以 Visitor 模式遍历所有的节点以及对 AST 做结构转换。例如 plan.preprocess 是对 AST 做预处理,包括合法性检查以及名字绑定。

       union 后面是对 token 和非终结符按照类型分别定义。第一部分的最后是对优先级和结合性的定义。文件的第二部分是 SQL 语法的产生式和每个规则对应的 aciton。SQL 语法非常复杂,大部分内容都是产生式的定义。例如 SELECT 语法的定义,我们可以在 parser.y 中找到 SELECT 语句的产生式。

       完成语法规则文件 parser.y 的定义后,使用 goyacc 生成语法解析器。TiDB 对 lexer 和 parser.go 进行封装,对外提供 parser.yy_parser 进行 SQL 语句的解析。

       最后,我们通过一个简单的例子,使用 TiDB 的 SQL Parser 进行 SQL 语法解析,构建出抽象语法树,并通过 visitor 遍历 AST。我实现的 visitor 只输出节点的类型,运行结果依次输出遍历过程中遇到的节点类型。

       了解 TiDB SQL Parser 的实现后,我们有可能实现当前不支持的语法,如添加内置函数。这为我们学习查询计划以及优化打下了基础。希望这篇文章对读者有所帮助。

       作者介绍:马震,金蝶天燕架构师,负责中间件、大数据平台的研发,今年转向 NewSQL 领域,关注 OLTP/AP 融合,目前在推动金蝶下一代 ERP 引入 TiDB 作为数据库存储服务。

Epub如何编辑

       å› ä¸ºepub是谷歌开放的EPUB格式的图书存档,所以也必须要谷歌的软件来查看了。去下载Google Book Downloader – 谷歌图书搜索下载器[.net] 即可打开。

       EPub是一个自由的开放标准,属于一种可以“自动重新编排”的内容;也就是文字内容可以根据阅读设备的特性,以最适于阅读的方式显示。EPub档案内部使用了XHTML或DTBook (一种由DAISY Consortium提出的XML标准)来展现文字、并以zip压缩格式来包裹档案内容。EPub格式中包含了数位版权管理(DRM)相关功能可供选用。

       [1]EPub于年9月成为国际数位出版论坛(IDPF)[2]的正式标准,以取代旧的开放Open eBook电子书标准。EPub包括三项主要规格:开放出版结构(Open Publication Structure,OPS)2.0,以定义内容的版面; 开放包裹格式(Open Packaging Format,OPF)2.0,定义以XML为基础的.epub档案结构; OEBPS容纳格式(OEBPS Container Format,OCF)1.0,将所有相关文件收集至ZIP压缩档案之中。

       2. 相关软件Adobe Digital Editions 免费、开放源代码、功能多样的Calibre Mobipocket-Reader/Creator Openberg Lector Stanza电脑桌面版 / iPhone版 AldikoAndroid版 FBReader Free:可在Windows,Linux,以及多种PDA上使用的开放源代码阅读软件,支援多种档案格式 BookGlutton:以阅读社群为主的免费线上ePub阅读工具 Bookworm Free:线上ePub阅读工具(亦适用于行动设备 ) Talking Clipboard:文字转换语音软件,可读出ePub书籍内容 AZARDI ePub Desktop Reader(仅有Windows版):内建ePub编辑和重新压缩打包功能。 eScape:供自由软件Open Office使用的ePub制作工具;适用于Windows与Linux系统 epubBuilder: 功能强大的epub电子书制作软件, 多种格式导入. 支持Stanza, Sony , Adobe DE等多种阅读器

       3. 操作系统OpenInkpot:开放源代码的嵌入式操作系统,相容于多种eReader阅读设备。

       4. 相关硬件苹果iPad (使用iBooks 软件) 苹果iPhone (使用Lexcycle Stanza软件) 翰林eReader Sony Reader COOL-ER Reader 使用Android系统的手机或其他装置(使用FBReaderJ ) Plastic Logic

snownlp和nltk什么关系

       æ²¡ä»€ä¹ˆå…³ç³»å§ã€‚ SnowNLP的开发者在GitHub描述中提到是受TextBlobd的启发才写的SnowNLP,而这两个类库的最大区别就是SnowNLP具体实现的时候没有用nltk,主要针对中文文本处理。

CALL 、libc++、libc

       CALL 是 **(Compiler/Assembler/Linker/Loader)**的简称。如果你和 C/C++ 打过交道,这几个词应该不会陌生。

       Levels of Representation/Interpretation

       抛开正确性,我们可以尝试填空(Python / C++、Go)并且知道:

       但是同时,Python 也能通过一些方式打包成 exe (虽然很巨大),同时 LLVM 这些层次的引入让我们的理解模糊了起来。所以我们要明确一下这个 Level。

       这个问题实际上是很含糊不清的,第三点里面 JIT 等的引入更让事情扑朔迷离了起来。具体其实可以参考这个链接里的说法: /question/。

       一般被称为“解释型语言”的是主流实现为解释器的语言,但并不是说它就无法编译。例如说经常被认为是“解释型语言”的 Scheme就有好几种编译器实现,其中率先支持 R6RS规范的大部分内容的是 Ikarus,支持在x上编译Scheme;它最终不是生成某种虚拟机的字节码,而是直接生成x机器码。

       实际上解释器的性能劣势也不一定是一种坏事,像我去年去 PyCon 听的“慢解释是一种优势”,虽然有点破罐子破摔的味道,但是如果你在 C/C++ 下开 asan/valgrind 或者带gcc -g, 和 Go 这种带 Runtime 的、V8这些可以提供的debug比较,难免会有羡慕的想法。

       Interpreter provides instruction set independence: run on any machine

       就是这样。

       CALL chain

       这是一张水图。可能还要处理一下预处理之类的过程,但是大概流程是这样没错。

       Compile

       Compile 的过程大概是

       不过看上面转的那篇文章,似乎形式有变,这方面我不是很了解。Lexer/Parser 的部分可以参考我之前的 Lex/Yacc 入门。总之,我们现在把源代码编译后可以转化为一种对应的 IR, 即nmsl.c -> nmsl.S.

       Assembler

       Assembler 接下来会nmsl.s -> nmsl.o.

       顺便给出这个 part 一个很有意思的 slide:

       ELF

       这个我觉得还是 csapp 写得好...总之生成的目标文件会满足这样的形式。

       Linker

       Combines several object (.o) files into a single executable (“linking”)

       这段我感觉 CSAPP 讲的稍微详细一些。

       在应用层面上,这里其实还涉及(不一定是这里引入的)name mangling,calling convention这种 C/C++ 相关的问题,所以可能extern "C" 在这种情况下就相对很好理解了。

       Loader

       When one is run, loader’s job is to load it into memory and start it running In reality, loader is the operating system (OS)

       这里可以参考 CSAPP 里面链接的时机相关的概念。

       libc/libc++

       qsort 是一个 下的函数,如果你去 libc++ 找的话,会发现事情好像不太对:

       github.com/llvm-mirror/...

       这里只有using 和函数声明,没有对应的实现。

       实际上 C++ 的标准库(以 libc++) 为例,可能会根据模版生成需要的函数/类。所以我们可以看到对应的一些源代码。

       C语言的库函数实际上通常以链接库的形式在 libc 中提供,链接的时候我们找到: stackoverflow.com/quest...