postgresql 词法/语法(scanner/parser)中flex/bison介绍

news2024/11/26 5:27:56

 

  • 专栏内容:postgresql内核源码分析
  • 个人主页:我的主页
  • 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

目录

前言

词法分析与语法分析的关系

工具介绍

flex的介绍

bison的介绍

flex的使用

举例

flex文件的结构

flex与bison协同工作

语法分析

bsion文件结构

语法规则

二义性的处理

结尾


前言

在数据库内核中,语法解析和词法分析已经非常成熟,本文来介绍一下它使用的基本知识点,后面介绍数据库内容时,也能更好的理解。

本文是基于postgresql 15的代码进行分析解读,演示是在centos8系统上进行。


  • 词法分析与语法分析的关系

一般的编程语言,如SQL的分析,分为:词法分析->语法分析->语义分析Semantic Analysis->语法树(Abstract Syntax Tree)

词法分析就是把输入的语句,按定义的模式规则分解成词语或符号,也叫token;

语法分析就是把有序的token输入,按约定的语句分隔符分析是否是完成语句,以及分析token组成的语句是否符合语法规则;

语义分析就是把语句的行为进行分析,得出它需要做什么,输入那些参数或约束,是否符合语义的规则;

  • 工具介绍

其中有两个重要的工具来协助完成词法和语法分析,它们是:

flex词法分析(lexical analysis 或称为scanning)

bison是语法分析(systax analysis 或称为parsing)

  • flex的介绍

flex的前身是Lex, Lex是1975年由Mike Lesk和当时尚在AT&T实习的Eric Schmidt共同完成的),是一个词法分析器的生成程序,可以单独使用也可以与Johnson的yacc协同工作。大概在1987年,Berkeley实验室的Vern Paxson用C重新写了Lex,并命名为FLex(the Fast Lexical Analyzer Generator),基于伯克利许可证。

 flex将模式处理为内部格式(确定性有穷自动机,Deterministic Fininte Automation,DFA),速度非常快;

  • bison的介绍

bison的前身是yacc。yacc是由贝尔实验室的S.C.Johnson基于Knuth大神的LR语法分析理论,于1975~1978年写成。大约1985年,UC Berkeley 的研究生Bob Corbett使用改进的内部算法实现了伯克利yacc,来自FSF的Richard Stallman改写了伯克利yacc并将其用于GNU项目,添加了很多特性,形成了今天的GNU Bison。bison现在作为FSF的项目被维护,基于GNU公共许可证发布。

原来lex/yacc组合,可以由flex/bsion组合来替代。

  • flex的使用

  • 举例

下面是一个统计行数,单词,字符的程序

%{

int chars = 0;

int words = 0;

int lines = 0;

%}

%%

[^ \t\n\r\f\v]+ { words++; chars += strlen(yytext); }

\n        { lines ++; chars++; }

.         { chars++; }

%%

int main(int argc, char *argv[])

{

        yylex();

        printf("lines:%8d\n words:%8d\n chars:%8d\n",lines,words,chars);

}

int yywrap(void) {

    return 1;

}

其中第一行模式,不是列出的空白字符,多个字符组成的字符串;

第二行模式,遇到换行时统计行数和字符;

第三行,其它的字符,统计字符;这里是上面匹配之外的。

[senllang@localhost demo04]$ flex charCount.l

[senllang@localhost demo04]$ gcc lex.yy.c

[senllang@localhost demo04]$ ./a.out

sdflk chain

234 df  dsf

lines:       2

 words:       5

 chars:      23

结束时按Ctrl+D,就会输出结果。

  • flex文件的结构

flex文件是嵌套c代码,它的文件(*.l)内容分三大部分

第一部分是声明和选项设置;在%{和}%间的会原样被拷到C程序中;

第二部分是一系列模式和动作;模式必须在每行的开头,因为flex认为有空格的都是行为,会被原样拷到c程序中;由%%和%%包围;这里的c代码是用{}括住的一行或多行;

第三部分C代码,会被拷到生的c文件中,通常是一些与动作代码相关的例程;

其中模式规则,使用正则表达式(regular expression, regex或regexp表示)。

  • flex与bison协同工作

在flex的yylex调用中,识别到一个标识符后,以记号的形式返回;再调用时,会以当前位置继续分析;对于空白等可以忽略,不返回时,yylex就继续工作;

利用以上特点,flex就可以与其它程序进行协作;

  • 语法分析

语法分析树,具用优先级;记号转换成语法分析树的规则,常用的语言是上下文无关文法(Contex-Free Grammar,CFG),在语言界也被称为短语结构文法(Phrase-Structure Grammar)或3型语言(Type-3 language)

上下文无关文法的格式就是BNF范式(BackusNaur form,BNF)。

bison的规则就是基于BNF范式,但简化了一点输入。

<exp> ::= <factor>

| <exp> + <factor>

<factor> ::= NUMBER

| <factor> * NUMBER

每一行就是一条规则,用来说明如何创建语法分析树的分支。在BNF里,::=被读作“是”,或者“变成”,|读作“或者”,是创建同类分支的另一种方式。

规则左边的名称是语法符号(symbol)。也就是说,所有记号都被认为是语法符号,但有一些语法符号不是记号。

有效的BNF总是带有递归性,规则会直接或间接的指向自身,这些简单的规则被递归的使用来匹配任何极端复杂的加法和乘法序列。

  • bsion文件结构

bison程序包含了与flex相同的三部分结构,

第一部分声明部分,声明也会被原样拷到C代码中,用%{和}%来声明。随后是%token记号声明,告诉语法分析程序记号名称。记号通常用大写,没有声明为记号的语法符号必须出现在至少一条规则左边。

第二部分规则部分;bison不是用::=,而是用:=,同时行间隔并不明显,分号被用来表示规则的结构。同样,C的动作代码在每条规则之后用{}包起来。第一条规则的左边的语法符号是语法起始符号(start symbol),当然其它规则,也可以拥有相同的起始符号。

第三部分是C代码部分。

  • 语法规则

在bison语法中,目标符号的值,也就是左边语法符号的值用$$来表示,右边语法符号的语义值依次用$1,$2...直到规则结束;当语法分析器返回时,值保存在yyval中。

第一条一般用常见的双规则递归定义来定义一个表达式;

  • 二义性的处理

对于有优先级的语法符号,需要定义多条规则来分别处理,通过前后顺序来决定优先级,否则就会产生二义性或不确定性。


结尾

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/525473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云原生进阶之PaaS中间件】第一章Redis-2.2Redis IO模型

1 IO模型 linux系统也是一种应用&#xff0c;它是基于计算机硬件的一种操作系统软件。当我们接收一次网络传输&#xff0c;计算机硬件的网卡会从网络中将读到的字节流写到linux的buffer缓冲区内存中&#xff0c;然后用户空间会调用linux对外暴露的接口&#xff0c;将linux中的b…

将虚拟机dmesg日志内容通过串口输出到windows下文件中

将虚拟机dmesg日志内容通过串口输出到windows下文件中 文章目录 将虚拟机dmesg日志内容通过串口输出到windows下文件中a. 设置vmware添加serial port, 使用文件作为串口b. 启动ubuntu&#xff0c;修改/etc/default/grubc. ubuntu使用root用户登录d. 修改printk优先级&#xff0…

数据科学中使用的17 种相似性和相异性度量之欧氏距离

目录 1简介 2距离函数 2.1 L2范数&#xff08;欧氏距离&#xff09; 1简介 在数据科学中&#xff0c;相似性度量是一种衡量数据样本如何相互关联或相互接近的方法。另一方面&#xff0c;相异性度量是告诉数据对象有多少是不同的。此外&#xff0c;当相似的数据样本被分组到一…

异常检测专栏(一)异常检测概述

前言 异常检测一直是机器学习中一个活跃的研究领域&#xff0c;由于风险管理、合规、安全、将抗和医疗风险以及人工智能安全等广泛领域的需求和应用不断增加&#xff0c;异常检测发挥和越来越重要的总用。近年来&#xff0c;随着深度学习和计算机视觉技术的不断发展&#xff0c…

零死角玩转stm32中级篇4-ADC和DAC

本篇博文目录: 一.ADC的基础概念1.什么是ADC2.在单片机中我们一般使用ADC技术来做什么?3.怎么查看单片机的某一个引脚是否具有ADC功能4.ADC采集和引脚数据的读取有什么区别5.单片机内部采用的是数字信号&#xff0c;为什么还要采用ADC进行转换6.ADC的分类7.ADC的工作原理8.ADC…

多目标应用:MOGWO求解环境经济负荷分配问题(IEEE-30bus)提供MATLAB代码

一、多目标灰狼优化算法 MOGWO MOGWO原理参考文献&#xff1a;S. Mirjalili, S. Saremi, S. M. Mirjalili, L. Coelho, Multi-objective grey wolf optimizer: A novel algorithm for multi-criterion optimization, Expert Systems with Applications, in press, DOI: http:/…

基础篇007. 串行通信

目录 1. 串行通信 1.1 串行通信概述 1.2 串行通信协议 2. 实验任务 3. 硬件原理 4. 利用STM32CubeMX创建MDK工程 5. 串行通信实验 5.1 UART串口printf&#xff0c;scanf函数串口重定向 5.2 UART串口printf输出实验 5.3串口控制LED实验 6.调试与验证 7.总结 串口调…

Redis主从复制是怎么实现的

如果数据都是存储在一台服务器上&#xff0c;如果出事就完犊子了&#xff0c;比如&#xff1a; 如果服务器发生了宕机&#xff0c;由于数据恢复是需要点时间&#xff0c;那么这个期间是无法服务新的请求的&#xff1b;如果这台服务器的硬盘出现了故障&#xff0c;可能数据就都…

Java注解方式实现aop,切点切面实战

注解方式实现aop我们主要分为如下几个步骤&#xff08;有更好的方法的话&#xff0c;欢迎交流&#xff09;&#xff1a; 1.在切面类&#xff08;为切点服务的类&#xff09;前用Aspect注释修饰&#xff0c;声明为一个切面类。 2.用Pointcut注释声明一个切点&#xff0c;目的是…

STM32 10个工程篇:1.IAP远程升级(三)

本想着周六去更新IAP远程升级&#xff08;三&#xff09;&#xff0c;但是周三单位突然通知团建周六去爬水长城&#xff0c;晚上回来已经精疲力竭&#xff0c;打开电脑不由地点开网易云音乐听着听着感觉很乏&#xff0c;去床上躺了会可一觉醒来已经夜里三点&#xff0c;于是调整…

【人工智能】— 贝叶斯网络、概率图模型、全局语义、因果链、朴素贝叶斯模型、枚举推理、变量消元

【人工智能】— 贝叶斯网络 频率学派 vs. 贝叶斯学派贝叶斯学派Probability&#xff08;概率&#xff09;:独立性/条件独立性&#xff1a;Probability Theory&#xff08;概率论&#xff09;:Graphical models &#xff08;概率图模型&#xff09;什么是图模型&#xff08;Grap…

深度学习之图像分类识别(一):AlexNet

本专栏介绍基于深度学习进行图像识别的经典和前沿模型&#xff0c;将持续更新&#xff0c;包括不仅限于&#xff1a;AlexNet&#xff0c; ZFNet&#xff0c;VGG&#xff0c;GoogLeNet&#xff0c;ResNet&#xff0c;DenseNet&#xff0c;SENet&#xff0c;MobileNet&#xff0c…

基于matlab使用麦克风阵列进行声波束成形

一、前言 此示例说明了麦克风阵列波束成形&#xff0c;以便在干扰为主的嘈杂环境中提取所需的语音信号。此类操作可用于增强语音信号质量以进行感知或进一步处理。例如&#xff0c;嘈杂的环境可以是交易室&#xff0c;麦克风阵列可以安装在交易计算机的显示器上。如果交易计算机…

js绘制的红心

看腻歪了粒子特效的红心&#xff0c;今天给各位整个线条的&#xff0c;效果图如下&#xff1a; 表白显圣神器&#xff0c;你值得拥有&#xff0c;代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…

必定收藏:国内免费可用 ChatGPT 网页版

ChatGPT是一个基于人工智能的聊天机器人&#xff0c;它可以与用户进行自然语言交互。ChatGPT使用了最新的自然语言处理技术&#xff0c;包括深度学习和神经网络&#xff0c;以便更好地理解用户的意图和回答用户的问题。 ChatGPT可以回答各种问题&#xff0c;包括但不限于常见问…

Cesium入门之七:Cesium加载地形数据

Cesium加载地形数据 一、什么是地形数据二、TerrainProvider类常用属性常用方法 三、TerrainProvider子类CesiumTerrainProvider类常用属性常用方法 CustomHeightmapTerrainProvider类ArcGISTiledElevationTerrainProvider类常用属性常用方法 EllipsoidTerrainProvider类常用属…

bash shell脚本常用代码记录

任何编程语言&#xff0c;常用的语法和代码结构其实不多的&#xff0c;如果为了快速的掌握入手一门编程语言&#xff0c;我认为只需要把该语言的常见语法和代码记下来&#xff0c;再结合实际需求去拼接成新的代码。这篇博客主要是记录bash shell的一些用法&#xff0c;便于日后…

机器学习指标: F1分数

动动发财的小手&#xff0c;点个赞吧&#xff01; F1 score 简介 在本文[1]中&#xff0c;您将了解 F1 分数。 F1 分数是一种机器学习指标&#xff0c;可用于分类模型。尽管分类模型存在许多指标&#xff0c;但通过本文&#xff0c;您将了解 F1 分数的计算方式以及何时使用它有…

腾讯云语音合成

用腾讯云 AI 语音合成打造有声书制作工具 代码开发 第一步&#xff1a;电子书文件解析 第二步&#xff1a;有声语音合成 第三步&#xff1a;完成有声书制作脚本 第四步&#xff1a;脚本可视化 产品体验 腾讯云 AI 语音合成服务已经非常成熟&#xff0c;基于开源工具整合 TTS P…

JAVA135-185

JAVA135-185 多线程多线程成员方法线程优先级eg&#xff0c;卖票&#xff08;线程的安全问题&#xff09;需要解决线程同时抢的问题 同步方法LOCK锁等待唤醒机制阻塞队列实现等待唤醒机制多线程的六种状态红包抽奖箱抽奖比较 线程池最大并行数网络编程InetAdress端口号协议练习…