Yacc 代表 Yet Another Compiler Compiler。 让我们从 Lex 开始吧。 Lex Lex 是一种生成扫描器的工具。扫描器是一种识别文本中的词汇模式的程序。...Lex 的模式匹配规则 让我们看一下 Lex 描述我们所要匹配的标记的规则。(我们将使用 C 来定义标记匹配后的动作。) 继续看我们的字数统计程序,下面是标记匹配的规则。...在这个例子中,result 是规则描述的非终端符号。...其他输出文件根据 '-d' 选项描述的输出文件来命名。 Yacc 库通常在编译步骤中自动被包括。但是它也能被显式的包括,以便在编译步骤中指定 �ly选项。...一个由 Yacc 生成的解析器调用 yylex() 函数来获得标记。 yylex() 可以由 Lex 来生成或完全由自己来编写。
的Golang版,所以要想看懂语法规则定义文件parser.y,了解解析器是如何工作的,先要对Lex & Yacc有些了解。...Lex & Yacc 相对显得有些古老,实现的不是那么优雅,不过我们也不需要非常深入的学习,只要能看懂语法定义文件,了解生成的解析器是如何工作的就够了。...我们可以从一个简单的例子开始: 上图描述了使用Lex & Yacc构建编译器的流程。Lex根据用户定义的patterns生成词法分析器。...从上面的流程可以看出,用户需要分别为Lex提供patterns的定义,为 Yacc 提供语法规则文件,Lex & Yacc 根据用户提供的输入文件,生成符合他们需求的词法分析器和语法分析器。...至此,我们大致了解了Lex & Yacc的原理。其实还有非常多的细节,例如如何消除语法的歧义,但我们的目的是读懂TiDB的代码,掌握这些概念已经够用了。
的 Golang 版,所以要想看懂语法规则定义文件 parser.y,了解解析器是如何工作的,先要对 Lex & Yacc 有些了解。...Lex & Yacc 相对显得有些古老,实现的不是那么优雅,不过我们也不需要非常深入的学习,只要能看懂语法定义文件,了解生成的解析器是如何工作的就够了。...我们可以从一个简单的例子开始: [1240] 上图描述了使用 Lex & Yacc 构建编译器的流程。Lex 根据用户定义的 patterns 生成词法分析器。...从上面的流程可以看出,用户需要分别为 Lex 提供 patterns 的定义,为 Yacc 提供语法规则文件,Lex & Yacc 根据用户提供的输入文件,生成符合他们需求的词法分析器和语法分析器。...至此,我们大致了解了 Lex & Yacc的原理。其实还有非常多的细节,例如如何消除语法的歧义,但我们的目的是读懂 TiDB 的代码,掌握这些概念已经够用了。
Ply 是一个纯 python 的词法分析和语法分析库,包括两个模块:lex 和 yacc Ply Ply 是一个纯 python 的词法分析和语法分析库,包括两个模块:lex 和 yacc lex 用于将输入的文本通过正则表达式转换为一系列...Token yacc 用作上下文无关语法分析 lex 词法分析 使用 lex 词法分析最重要的是定义 token 及其解析规则,每个词法分析程序都必须定义 tokens 元组用于声明 TOKEN: tokens...t_token_name 来定义,支持这样三种方式: 对于非常简单的规则,你可以简单地定义上面格式的字符串去声明,如: t_PLUS = r'\+' 对于复杂的规则,你可以定义如下格式签名的函数去声明...# or parser = yacc.yacc(start="foo") 移入/规约 上面给出的语法规则是经过规约的规则,对解析器来说,它更容易处理,因为它几乎不存在歧义,但从编程的角度来说,我们可能会以一种更符合人类直觉的方式定义语法规则...相当于语法分析的一个分支,里面描述了在这个状态下分析器允许输入的 TOKEN 或表达式,其中的 .
就是根据词法规则自动生成词法分析器 执行语法分析的程序称为解析器(parser),yacc就是能根据语法规则自动生成解析器的程序 yacc和lex在mac上已经预装。...如果没有这个函数的话,就必须手动链接lex的库文件。 第12行到第27行是规则区块。这一部分是使用正则表达式*去描述记号。...第13行的%%是分界,之后的是规则区块。yacc的规则区块由语法规则以及C语言编写的相应动作两部分构成。 语法规则 在yacc中,会使用类似BNF(巴克斯范式)的规范来编写语法规则。...2.3 生成执行文件 mac下按顺序执行如下命令,就会输出名为mycalc的执行文件 yacc -dv mycalc.y // 运行yacc lex mycalc.l // 运行...再下面,记录的是当前状态下,下一个记号进入时如何变化。具体来讲,当MUL(*)记号进入后悔进行移进并转换到state 12,如果进入的是DIV(/),则进行移进并转移到state 13。
其实我们最开始学习英语的时候老师都会告诉我们英语其实就是“单词+语法”,这个观点放到编程语言中很合适,lex提取了单词,那么是剩下的部分就是如何表达语法。...lex和yacc的输入文件格式 Definition section %% Rules section %% C code section .l和.y的文件格式都是分成三段,用%%来分割,三个section....y文件这里的动作都是用{}扩起来的,用C语言来描述,这些代码可以做你任何想要做的事情 C code Section main函数,yyerror函数等的定义 lex和yacc能帮我们做什么?...其实任何计算机能做的事情都可以用C语言来实现,lex和yacc存在的意义在于简化语言,让使用者能够以一种用比较简单的语言来实现复杂的操作。...如果我们想实自定义一个简单的语言(比如SQL)来实现操作,这个时候就可以用lex和yacc。 lex和yacc 做的事情只是:用C语言来实现另外一种语言。
这个版本主要对Cuda项目的构建做了很多的改进,并且新增了对lex/yacc编译支持,同时也对target新增了on_link, before_link和after_link等链接阶段的定制化支持。...Lex/Yacc编译支持 当前xmake已经可以原生支持lex/flex, yacc/bison等对.l/.y文件的编译处理,来快速开发一些跟编译器相关的项目。...我们只需要添加lex,yacc两个规则到target中,使其可以正常处理.l/.y文件,当然.ll/.yy也是支持的。...target("calc") set_kind("binary") add_rules("lex", "yacc") add_files("src/*.l", "src/*.y"...", "yacc")规则去支持lex/yacc项目 改进 #430: 添加add_cucodegens()api为cuda改进设置codegen #432: 针对cuda编译支持依赖分析检测 #437
Flex 与 Bison 是为编译器和解释器的编程人员特别设计的工具: Flex 用于词法分析(lexical analysis,或称 scanning),把输入分割成一个个有意义的词块,称为记号(token...Bison 用于语法分析(syntax analysis,或称 parsing),确定这些记号是如何彼此关联的。...他们发现 lex 既可以作为一个独立的工具,也可以作为 Johnson 的 yacc 的协同程序。lex 因此变得十分流行,尽管它运行起来有一点慢并且有很多错误。...由于它比 AT&T 的 lex 更快速和可靠,并且就像伯克利的 yacc 那样基于伯克利许可证,它最终也超越了原来的 lex。...范例指导了我们如何使用 Flex & Bison 开发一个计算器,并能支持变量、过程、循环和条件表达式,有内置函数,也支持用户自定义函数。
(一) 在前几日的文章『软件随想录』里,我随性写了一句:「现在似乎已经不是lex/yacc 或 bison/flex的时代了。...很多同学不解,问我:lex/yacc不是写编译器 [1] 的么?我又不发明新的语言,它们对我有什么用? 从这个问题里,我们可以见到国内本科教育荼毒之深。...我用lex/yacc干的唯一一件事,就是TMD设计一个语言。 这世间的语言如此之多,实在容不下我等庸人再设计一门蹩脚的,捉急的,没有颜值,没有性能的语言。...如果你经常使用函数式编程语言,你会发现,这种规则的撰写似曾相识。 bison使用的描述规则的语法是BNF的变体。 以下是编译和执行的结果,作为展示,我仅仅把语法树中我感兴趣的内容打印出来了: ?...instaparse的强大之处不仅仅在于简单的语法,还在于你可以使用REPL来调试你的代码!用REPL来调试你的代码!用REPL来调试你的代码!
隐含规则会使用系统变量,我们可以通过系统变量来改变隐含规则运行时的参数,比如系统变量 CFLAGS 可以控制编译器的参数等。另外,我们还可以通过模式规则来写自己的隐含规则或使用后缀规则来保证兼容性。...当然,我们可以使用 make 选项 -r 或 -n-builtin-rules 来取消所有的预设的隐含规则,但是即便使用参数,有些隐含规则也会生效。...(Yacc 是一个语法、词法分析器) Lex C 程序时的隐含规则.c 的依赖文件被自动推导为 n.l (Lex 生成的文件), 生成命令是 (LEX) (LFALGS) 。...从C程序、Yacc文件或Lex文件创建Lint库的隐含规则.ln (lint生成的文件)的依赖文件被自动推导为 n.c ,生成命令是 (LINT) (LINTFALGS) 实际上,我们完全可以使用模式规则来重载内建的隐含规则或者取消内建隐含规则...Lex 方法分析器(针对于C或Ratfor),默认命令是 lex PC Pascal 语言编译程序,默认命令是 pc YACC Yacc 文法分析器(针对于C程序),默认命令是 yacc YACCR
这些其实都是在 静态层面 上对语言的描述,为了实际执行这些语言,就需要对其进行解析,还原出语言本身所描述的信息结构。...可以这样来理解: 由词法解析器生成的符号,也叫 token,是终结符。终结符是最小表义单位,无法继续进行拆解和解析 规则左侧定义的符号,是非终结符。...Lex 函数的返回值类型(即词法分析器的实际产物)需要在后面的 yacc 文件的 token 部分定义。...yacc 实现 parser,最少需要知道的就是前面四种描述符。...一开始我们只实现最简单的语法规则,后面自己就会逐渐了解更高级的文法规则了。 3.5 参考工程 goyacc 的示例工程不多,不推荐用 yacc 实现计算器的例子,参考性比较差。
右边的图是一个简单的编译流程图,在早期,编写编译器相当耗时,直到Lex和YACC的诞生,有了它们,开发者只需要关注如何设计词法和语法规则,剩下的解析器代码都由它们来生成处理,大大提高了程序编译解析器开发的效率...我们的议题重点关注Lex&YACC和LEMON Parser Generator。 在Lex YACC解析器中,生成解析器的流程如右图所示。...三、如何人工挖掘语法规则的漏洞 首先是Lex和YACC历史漏洞不多,但词法/语法规则是由开发者定义的,虽然Lex 和YACC的代码不多,漏洞较少,但规则就好比我们开发的插件,如果插件有问题,这个软件也存在安全风险...接下来,我们来看一下Lex和YACC的攻击模型。 正如右图所示,黄色部分表示可能被攻击的攻击面,分别对应四个处理程序(Lex,YACC,yylex,yyparse)。...六、如何编写安全的规则 最后,我们简单介绍一下如何编写安全的规则。 1.避免类型混用 规则定义中,可能存在大量的类型转换(显式的和隐式的),需要对每种情况都做好单元测试,以防漏掉某个规则产生混用。
相关: 《Postgresql源码(44)server端语法解析流程分析》 《Postgresql源码(50)语法解析时关键字判定原理(函数名不能使用的关键字为例)》 关键字报错场景 关键字不出现,或出现在函数内部...] CREATE = 352 OR = 544 REPLACE = 595 FUNCTION = 429 ========================================== [yacc...lex返回522后,yacc语法树没有匹配项了,返回错误。 [lex] NORMALIZE = 522 [yacc] if (!...这些标识符主要是给lex使用的,在lex匹配到正则规则时,返回其中一个token。...但其实很多也不会触发冲突,为了使用这些关键字,在gram.y文件后面专门定义了几组语法规则: unreserved_keyword:可以用于任意命名场景,如果新增的关键字不会引发shift/reduce
词法分析就是将分割出来的token再按照语法规则重新组合到一起。PHP内词法分析和语法分析分别使用的是re2c和yacc来完成的。其实准确来说一个应该是re2c和bison。...&& bison 接下来就是yacc语法分析器,yacc对应的功能函数在php里面为zendparse(),这个函数其实预处理自动生成的,在这个函数通过不断的调用lex_scan返回token,根据定义的语法规则动态的生成抽象语法数...,挑出一些有代表性的yacc语法规则来描述一下 %left '|' %left '^' %left '&' %nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL...后面就是描述非终结字符是如何嵌套的,有一个特殊的start节点,yacc在开始扫描语法的规则的时候只关注它,相当于入口点。...如果你真的想看看yacc内部扫描语法的,不要去看经过bison预处理之后的.c文件,同级目录下有一个.output后缀相同文件名的文件,里面描述了yacc里面的状态机是如何工作的。
我们改造 MySQL 源码的 Client 模块来实现SQL审核工具的输入,利用 MySQL 源码的语法分析模块来对 SQL 语法进行解析。...MySQL 通过 yacc定义语法规则,并且将 SQL 语句解析出来的内容放在LEX结构体里。...如下图3所示为 Update 语句的 yacc 规则, Update:为一个非终结符,后面为一系列的终结符号与非终结符号组合。...从图3也可以看出,语法解析的内容存放在LEX结构体中。在 MySQL 源码中,函数 parse_sql() 封装了MySQL中通过 yacc 解析语法的逻辑。...图3 Update语句的yacc规则 3. 使用介绍 上面介绍了 SQL 审核工具的背景及实现,现在讲下SQL审核工具应如何使用。
,通常可以简化为下面的过程 graph LR 词解析--> 语法解析 语法解析 --> 解释执行 每个过程也有很多种做法 词解析是将一个语句解析成 token 的过程,这个过程一般比较简单,可以使用 lex...: 由 非终结符 与 终结符 组成的匹配 + 动作规则 %% 嵌入代码 (这部分为可选,比如可以 lexer 或者 main 可以写在这里或者单独用文件写 ) 文法定义简单说明如下 描述符 说明 %union...一般写作下面的形式, 规则描述 可以是 非终结符、终结符, 可用 | 分割多个规则....$$ 则表示当前整个符号对应的结构 非终结符: 规则描述1 { 动作描述2 } | 规则描述2 { 动作描述2 } // 例子 top: expr { if $1.IsInt...本文将原始的代码分成 .y, lexer, main 多个文件,并且做了一定的简化,使得代码可读性更高,可以参考这里 实战:Json Parser 例子来自这里, 写一个编译器识别 json 格式的字符串
3.编译成opcode执行 4.如果安装opcode缓存扩展(如APC, xcache, eAccelerator等),可能直接从缓存中读取opcode执行 脚本的编译执行: 1.读取脚本,通过lex按照词法规则切分一个一个的标记...编程语言的编译器(compiler)或解释器(interpreter)一般包括两大部分: 1.读取源程序,并处理语言结构。 2.处理语言结构并生成目标程序。...词法分析器: Lex(词法分析生成器:A Lexical Analyzer Generator)。...Yacc(Yet Another Compiler-Compiler) 1.安装lex,apt-get install flex 2.lex的词法规则文件 定义段 %% 规则段 %% 用户代码段
Makefile文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。...2、Makefile的基本内容 Makefile一般包括包含:显式规则、变量定义、隐含规则、文件指示和注释等五个内容。 (1)显式规则:显式规则说明如何生成一个或多个的目标文件。...LEX Lex方法分析器程序(针对于C或Ratfor)。默认命令是“lex”。 PC Pascal语言编译程序。默认命令是“pc”。 YACC Yacc文法分析器(针对于C程序)。...YFLAGS Yacc文法分析器参数。 2.2隐含规则 GNU make 包含有一些内置的或隐含的规则,这些规则定义了如何从不同的依赖文件建立特定类型的目标。...2.4 Makefile中的函数 在Makefile中可以使用函数来处理变量,从而让命令或规则更为的灵活和具有智能,函数调用,很像变量的使用,也是以“$”来标识的,函数调用后,函数的返回值可以当做变量来使用
框架 3、yacc框架中调用base_yylex进入lex拿一个token(正常用框架是每次拿一个,PG通过对lex函数的封装可以拿后面多个,有些语法需要看到后面多个一块解析) 4、拿回来token...后,进入语法树开始递归(有点像后续遍历,从底层开始向上构造语法节点,实际是用两个堆栈解析每一层语法规则,原理也比较简单,见第二节)。...5、从语法树底层节点向上reduce,识别收集文本中的目标信息,创建对应的stmt结构体,填入数据,返回上层。...(2)如果有预读的token就直接用了,不再重新解析 (3)如果没有预读的token,调core_yylex从lex拿一个token出来,如果是普通token直接返回yacc继续reduce (4)...框架定义的,保存了解析所需 6、core_yylex是scan.l生成scan.c中提供的函数,功能就是scan.l中编写的匹配规则 7、core_yylex可以自己在scan.l中自定义其他同参函数
这篇文章通过实现中文计算器方式,来介绍解释器或编译器中的各种概念。 基本概念 如何执行一个字符串 1+1 呢?在 JS 中,我们可以直接执行 eval('1+1') 就行了,这将会输出 2。...Lex / Yacc lex是一个产生词法分析器(lexical analyzer,"扫描仪"(scanners)或者"lexers")的程序,Lex是许多UNIX系统的标准词法分析器产生程序。...Lex 常常与 yacc 语法分析器产生程序一起使用。 yacc(Yet Another Compiler Compiler),是Unix/Linux上一个用来生成编译器的编译器(编译器代码生成器)。...yacc生成的编译器主要是用C语言写成的语法解析器,需要与词法解析器Lex一起使用,再把两部分产生出来的C程序一并编译。...可以发现字符串中的括号并没有与之对应的节点,而是使用树的层级来描述对应的优先级。 中文计算器语法 中文计算器的语法可以用下面 EBNF 来表示。
领取专属 10元无门槛券
手把手带您无忧上云