首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

借助yacc和lex自制计算器——《自制编程语言》一

1.3 yacc:     yacc是自动生成语法分析器的工具,输入扩展名为.y的文件,就会输出语法分析器的C语言代码。...解析流程     对照语法规则代码 2-0跟踪下解析1 + 2 * 3的执行流程    首先,yacc生成的解析器保存在程序内部的栈。...称为移进/归约冲突 即便发生冲突yacc仍会生成解析器。如果存在归约/归约冲突,则优先匹配前面的语法规则,移进/归约冲突则会优先匹配移进规则。    ...1 shift/reduce // 冲突信息(见下文) State 14 conflicts: 1 shift/reduce State 15 conflicts: 1 shift/reduce Grammar...所以只放这段代码。 3 结束     以上结束了一个mycalc计算器的代码流程,编译完之后确实有一个终端计算器。但是实际上代码都是原书提供的,跟着思路走了一遍。

4.5K10
您找到你想要的搜索结果了吗?
是的
没有找到

bison解析中lookahead前瞻工作原理

https://www.gnu.org/software/bison/manual/bison.html#Algorithm 1 lookahead token 学习yacc后一直有一个疑问,reduce...bison解析器在发现一次匹配后,继续向前看一个lookahead,再决定做什么。...上面的步骤2并不是匹配上的都能reduce,lookahead token影响一些规则,使其延迟reduce。 1.1 lookahead token案例分析 这是一个有相互依赖关系的语法树。...选择2:lookahead继续shift入栈,按规则2规约。 现在发生了shift/reduce冲突。Bison会通过选择shift来解决这些冲突(除非运算符优先级声明)。...3.1 悬挂冲突 为了解其中的原因,下面与其他选择进行对比: 正例:如果bison更偏向于shift “else”,下面语句1就等价与语句2,符合预期。

1.5K70

【Python】Ply 简介

(start="foo") 移入/规约 上面给出的语法规则是经过规约的规则,对解析器来说,它更容易处理,因为它几乎不存在歧义,但从编程的角度来说,我们可能以一种更符合人类直觉的方式定义语法规则,就像下面这样...当出现这种冲突时,yacc 会打印一下警告信息: WARNING: 1 reduce/reduce conflict WARNING: reduce/reduce conflict in state 15...resolved using rule (assignment -> ID EQUALS NUMBER) WARNING: rejected rule (expression -> NUMBER) 上面的信息告诉你发生了什么冲突...,但并不会告诉你冲突是如何发生的,要了解语法分析的详细流程,你肯呢个需要阅读 parser.out 文件,该文件在语法分析器第一次运行时被生成,描述了语法分析的详细流程,文件内容其实很容易理解,你需要注意下面三点...标注出了冲突的地方,虽然这些冲突不见得都是不好的。

2.6K30

Postgresql源码(50)语法解析时关键字判定原理(函数名不能使用的关键字为例)

lex返回522后,yacc语法树没有匹配项了,返回错误。 [lex] NORMALIZE = 522 [yacc] if (!...所有的关键字都在gram.y文件中使用%token表示了,这些关键字应该都不能用于 表名、列名等对象名等,可能造成shift/reduce冲突。...但其实很多也不会触发冲突,为了使用这些关键字,在gram.y文件后面专门定义了几组语法规则: unreserved_keyword:可以用于任意命名场景,如果新增的关键字不会引发shift/reduce...冲突,可以放在这个列表中。...增加方法:先确定新增关键字会不会造成语法冲突歧义等,加到上面5个list中,然后根据能否用于表名、列名、as等场景,在kwlist中增加即可。

75930

三十分钟成为 Contributor | 提升 TiDB Parser 对 MySQL 8.0 语法的兼容性

TiDB 通过 AST 树生成执行计划,修改 AST 节点可能影响 TiDB 的行为,因此应尽量保持原有结构,不改变原有的属性,如果确实有修改 AST 树必要,我们帮助 Contributor 检查...goyacc 所生成的 parser 采用了 LALR(1) 方法进行解析,冲突有两类:一类是两条规则都能被用于归约,称为 reduce-reduce 冲突。...另一类是既能使用一条规则归约,又能按照另一条规则移进下一个 token,称为 shift-reduce 冲突。...可以通过指定优先级的方式消除冲突,具体可以参考 yacc 的 %precedence 和 %prec 指示。...经过比较和分析,我们发现第一个方案引入新的数据结构,有较大的概率会引起现有的 TiDB 测试不过,为此可能要修改 TiDB 方面的代码,工作量大的同时提高了 parser 的复杂度,因此作为备选方案;

1.3K20

TiDB SQL Parser 的实现

词法分析器读取源代码,根据patterns将源代码转换成tokens输出。Yacc根据用户定义的语法规则生成语法分析器。语法分析器以词法分析器输出的tokens作为输入,根据语法规则创建出语法树。...Yacc 生成的语法分析器使用自底向上的归约(shift-reduce)方式进行语法解析,同时使用堆栈保存中间状态。...对这个语法树进行遍历访问,可以生成机器代码,也可以解释执行。 至此,我们大致了解了Lex & Yacc的原理。...从 parser.y 的注释看到,这个文件最初是用工具从 BNF 转化生成的,从头手写这个规则文件,工作量非常大。...这段代码的运行结果如下,依次输出遍历过程中遇到的节点类型: *ast.SelectStmt *ast.TableOptimizerHint *ast.TableRefsClause *ast.Join

44210

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

词法分析器读取源代码,根据 patterns 将源代码转换成 tokens 输出。Yacc 根据用户定义的语法规则生成语法分析器。...Yacc 生成的语法分析器使用自底向上的归约(shift-reduce)方式进行语法解析,同时使用堆栈保存中间状态。...对这个语法树进行遍历访问,可以生成机器代码,也可以解释执行。 至此,我们大致了解了 Lex & Yacc的原理。...从 parser.y 的注释看到,这个文件最初是用 工具 从 BNF 转化生成的,从头手写这个规则文件,工作量非常大。...这段代码的运行结果如下,依次输出遍历过程中遇到的节点类型: *ast.SelectStmt *ast.TableOptimizerHint *ast.TableRefsClause *ast.Join

4.5K100

CSS大会 | 打破常“规”:挖掘语法解析器规则漏洞

我们的议题重点关注Lex&YACC和LEMON Parser Generator。 在Lex YACC解析器中,生成解析器的流程如右图所示。...右边是生成它的具体Fuzzer代码。这样一个PoC有什么玄机呢,让我们继续往后看。 POC在第一张图中。那么为什么导致这样的问题呢,让我们阅读一下layout相关的语法规则。...Yy就是yacc的那个y,大家可以读一下它的代码,他们写的时候并不是十分规范,大量使用了全局变量,我猜测这个yy是为了避免生成代码。...和它自己的代码冲突而加上的一个模拟C++namespace的东西,如果觉得看着很碍眼,可以在阅读的时候把yy全部删掉。...SQLite使用了Lemon Parser,它和Yacc&Lex很像,但是又不互相兼容,不过在右边Call Stack中大家一样能看到中间有个yy_reduce,最后它还是用了yy_这个标准开头。

96240

使用优先级解决shiftreduce冲突的经典例子(%prec UMINUS)

2 案例:%prec UMINUS解决shift/recude冲突 gram.y中处理select语句的语法规则,发生语法冲突。.../reduce conflicts: 1 found, 0 expected gram.y: warning: shift/reduce conflict on t0ken ')' [-Wcounterexamples...当前没有定义select_with_parens的优先级,所以发生了shift/recude冲突。如果加上%prec UMINUS为什么就没有冲突了,bison选择了shift还是recude?...处理上述情况bison的规则: 如果rule的优先级更高,bison选择reduce。 如果lookahead token的优先级更高,bison选择shift。.../recude错误,且错误发生的原因是lookahead token和同一条规则的冲突,可以尝试为规则配置优先级,达到帮助bison选择shiftreduce的效果。

78610

YACC嵌入式规则

测试用例在文章末尾 嵌入式用法 YACC语法分析只允许动作在规则的末端,例如: (其中{}内部为定义好的规则) expr: T_INT { $$ = $1; } | expr T_PLUS...当前1表示A、3表示B、 移进/规约冲突 嵌入式规则 等于 在匹配规则的过程中就执行一些动作(正常动作是在规则整体匹配完了再执行)。...这样导致规约的动作有可能要比没有嵌入式的规则提前做,例如: thing: abcd | abcz; abcd: ‘A' 'B' 'C' 'D' ; abcz: ‘A' 'B'...'B' 'C' 'Z' 原因是: 第一种情况下,yacc在看到4个字符之前不需要决定匹配abcd还是abcz,reduce动作可以在收到4个字符之后再做。...第二种情况下,在收到A、B之后,就必须做出决定了,因为abcd规则有嵌入式规则要执行,但是只收到两个字符无法决定走哪个分支,所以发生冲突

94410

Flex & Bison 开始

例如,如下代码片段: alpha = beta + gamma; 词法分析把这段代码分解为这样一些记号:alpha, =, beta, +, gamma, ;。...起源 bison 来源于 yacc,一个由 Stephen C. Johnson 于 1975 年到 1978 年期间在贝尔实验室完成的语法分析器生成程序。...正如它的名字(yacc 是 yet another compiler compiler 的缩写)所暗示的那样,那时很多人都在编写语法分析器生成程序。Johnson 的工具基于 D. E....来自自由软件基金(Free Software Foundation)的 Richard Stallman 改写了 Corbett 的版本并把它用于 GNU 项目中,在那里,它被添加了大量的新特性并演化成为当前的...如下编译所有范例: cd books/flex_bison/ # 编译 release make # 编译 debug make debug # 清理 make clean 范例程序输出进 _build

1.4K20

Python 之父撰文回忆:为什么要创造 pgen 解析器?

据我所知,他有自己的博客,为什么还会跑去 Medium 上写文呢?好奇之下,我就打开了他的老博客。...至于词法分析器(lexer),我决定不使用生成器——我对 Lex 的评价要比 Yacc 低得多,因为在尝试扫描超过 255 个字节的标记符时,我所熟悉的 Lex 版本会发生段错误(真实的!)。...Lex 是“LEXical compiler”的简称,用来生成词法分析器;Yacc 是“Yet another compiler compiler”的简称,用来生成语法分析器。...(对我而言)不通过添加帮助性的规则而解决冲突的方式。...代码生成器中就需要有一个简单的检查,来确定它遇到的是哪一种可能的情况。(这已经被证明是一把双刃剑,后来我们添加了一个由单独的生成器所驱动的“解析树 -> AST”步骤,以简化字节码生成器。)

1.3K30

SQLite虚拟机

LR(1):针对不同产生式上的非终极符,分别定义其后继符集,减少了移入/归约冲突。...由于许多LR(1)产生式具有同心状态,合并这些同心状态后没有冲突的文法即符合LALR文法。...这个文件是解释SQL语句生成可执行指令的编译程序,其入口是函数sqlite3Parser。 Lua在3.1版本以前使用LALR(1)文法文件,并使用YACC生成该文法文件生成编译引擎。...SQLite用的Lemon,Lua早期版本用Yacc。编译器编译文法文件,生成语法分析程序。SQLite中生成的文件是parse.c。Lua1.1版本生成的是y.tab.c。...不过,在编译器设计上,就要在代码生成阶段对寄存器进行分配,增加了实现的复杂度。并且每条指令的复杂度增加。 Lua 在5.0版本以前采用栈方式,5.0以后采用寄存器方式。

1.4K60
领券