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

Yacc/Bison:伪变量($$,$ 1,$ 2,..)以及如何使用printf打印它们

在云计算领域中,Yacc(Yet Another Compiler Compiler)和Bison是两个用于构建解析器的工具。Yacc是一个基于LALR(1)算法的解析器生成器,而Bison是Yacc的增强版本,支持更多的功能和更高效的运行。

在Yacc/Bison中,伪变量(pseudo-variables)是在解析规则中使用的特殊变量,用于表示不同的值。伪变量的名称通常以美元符号($)开头,后面跟一个数字,例如:$1、$2、$3等。这些变量的值是根据解析规则的匹配情况自动填充的。

伪变量的作用是在解析规则中传递和处理终结符和非终结符的值。例如,在一个简单的算术表达式解析器中,我们可能有以下规则:

代码语言:txt
复制
expression: expression '+' term { $$ = $1 + $3; }
          | term { $$ = $1; }
          ;

term: term '*' factor { $$ = $1 * $3; }
    | factor { $$ = $1; }
    ;

factor: NUMBER { $$ = $1; }
      ;

在这个例子中,伪变量$$表示当前规则的返回值,$1、$2和$3表示规则中的不同符号的值。例如,在第一个expression规则中,$1表示左侧的expression,$3表示右侧的term,$$表示整个表达式的值。

要使用printf打印伪变量的值,可以在规则的动作中使用printf函数。例如,在上面的expression规则中,我们可以添加以下代码来打印$$的值:

代码语言:txt
复制
expression: expression '+' term { $$ = $1 + $3; printf("Result: %d\n", $$); }
          | term { $$ = $1; }
          ;

这将在每次计算表达式时打印结果。

总之,Yacc/Bison中的伪变量是一种在解析规则中传递和处理值的方式。通过使用伪变量,我们可以构建更复杂的解析器和处理器,以处理各种语言结构。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Yacc 与 Lex 快速入门(词法分析和语法分析)

A{1,2}shis+ 匹配 AAshis, Ashis, AAshi, Ashi。 (A[b-e])+ 匹配在 A 出现位置后跟随的从 b 到 e 的所有字符中的 0 个或 1个。...-n不打印 -v 的汇总。 高级 Lex Lex 有几个函数和变量提供了不同的信息,可以用来编译实现复杂函数的程序。 下表中列出了一些变量和函数,以及它们使用。...我们假设文件有多个姓名和年龄,它们以空格分隔。 在看 Yacc 程序的每一段时,我们将为我们的例子编写一个语法文件。 C 与 Yacc 的声明 C 声明可能会定义动作中使用的类型和变量以及宏。...这里另一个有用的就是 1 和 3 的使用, 它们引用了标记 NAME 和 NAME(或者第二行的 VALUE)的值。 lexer 通过 Yacc变量 yylval 返回这些值。...命令行的其他常用选项 '-d' ,'--defines' : 编写额外的输出文件,它们包含这些宏定义:语法中定义的标记类型名称,语义的取值类型 YYSTYPE, 以及一些外部变量声明。

5.1K20

Mac下利用Flex和Bison实现控制台计算器

Flex使用手册:http://tinf2.vub.ac.be/~dvermeir/courses/compilers/flex/flex_toc.html Bison使用手册:http://www.gnu.org.../software/bison/manual/index.html ---- 环境配置 环境类Unix系统:macOS 10.14.2 由于Unix系统自带yacc,因此需要配置bison与flex软件包...---- 语法分析器bison使用bison文件,以.y作为后缀名结尾,和flex的词法分析输入文件类似,bison的输入文件也是分成3部分(不是巧合) 1 第一部分% {和% }之间,是原封不动拷贝到输出的...Bison能够完全支持LR(1)文法。 这种文法的特点是只要多向前看一个TOKEN, 就能够决定如何解析。...因此如果bison告诉你语法ambiguous的时候, 可以想一想如何把自己的文法改成LR(1)型文法。

1.7K30

1)PHP内核 - 玩转php的编译与执行

单条指令可能有两个操作数op1,op2,也可能只有一个op1,也可能存在一个操作数都没有的情况,但至多只有两个操作数。那么指令是如何使用操作数,首先必须知道它的类型和具体的数据内容。...zend_op zend_op; 可以看到不仅有两个操作数的op1和op2的定义,还有一个result变量,这个是变量是标识单条opline执行的返回值,当出现使用函数返回值赋值时,多个变量连续赋值,变量赋值出现在...PHP内词法分析和语法分析分别使用的是re2c和yacc来完成的。其实准确来说一个应该是re2c和bison。...如果你真的想看看yacc内部扫描语法的,不要去看经过bison预处理之后的.c文件,同级目录下有一个.output后缀相同文件名的文件,里面描述了yacc里面的状态机是如何工作的。...yacc和re2c到这里真的就结束了。抽象语法树其实是和它们耦合在一起的,虽然把编译器和执行器隔开了。re2c在返回的token对应的值的时候,就是以抽象语法树节点返回的。

1.8K10

如何愉快地写个小parser

(一) 在前几日的文章『软件随想录』里,我随性写了一句:「现在似乎已经不是lex/yaccbison/flex的时代了。...很多同学不解,问我:lex/yacc不是写编译器 [1] 的么?我又不发明新的语言,它们对我有什么用? 从这个问题里,我们可以见到国内本科教育荼毒之深。...标准的unix下,语法分析的工具是bison,我们看看上述文本如何使用bison解析: ?...如果你经常使用函数式编程语言,你会发现,这种规则的撰写似曾相识。 bison使用的描述规则的语法是BNF的变体。 以下是编译和执行的结果,作为展示,我仅仅把语法树中我感兴趣的内容打印出来了: ?...(三) 这篇文章并未告诉你LALR(1),LL(1),LL(*)等概念,没有具体解释lexical parser,grammar parser的详细步骤,虽然举了一些BNF(及其变体)的例子,也没有触及如何撰写

3K100

Architecture of SQLite

附近的图表显示了SQLite的主要组件以及它们如何进行互操作。 下面的文本解释了各种组件的角色。 ?...SQLite的解析器是使用Lemon解析器生成器生成的。Lemon与YACC/BISON做同样的工作,但是它使用了不同的输入语法,因此不易出错。Lemon还生成一个可重入且线程安全的解析器。...vdbeaux.c文件包含虚拟机使用的实用程序以及库中其他部分用来构造虚拟机程序的接口模块。...每个VFS提供打开、读取、写入和关闭磁盘上文件的方法,以及用于其他操作系统特定任务的方法,例如查找当前时间或获取随机性以初始化内置随机数生成器。...SQLite在printf.c中有自己的printf()私有实现(带有一些扩展),在random.c中有自己的随机数生成器(PRNG)。

1.4K30

Go 常用命令介绍

默认情况下,go vet 只运行一些常见的检查,但使用 -all 标志可以启用所有检查。 -shadow: 检查代码中的变量阴影问题。这个标志用于检测局部变量覆盖外部变量的情况。...这个标志用于检测代码中是否存在复制锁,以及它们是否正确使用。 -lostcancel: 检查丢失的上下文取消问题。这个标志用于检测代码中是否存在未正确处理的上下文取消。...如果不使用此标记,则只会打印不同行的前10个错误。...-cpuprofile 支持调试模式,写入相应的cpufile到指定的文件 1.6 go get 用于下载、安装和更新 Go 语言包(也称为模块)以及它们的依赖项。这个命令通常用于获取外部包。...举一个简单的例子,例如经常会使用yacc来生成代码,那么常用这样的命令: go tool yacc -o gopher.go -p parser gopher.y -o 指定了输出的文件名, -p指定了

36120

揭晓:一条SQL语句的执行过程是怎么样的?

本文先带你了解一下如何跟踪 MySQL 的运行,了解它处理一个 SQL 语句的过程,以及 MySQL 在词法分析和语法分析方面的实现机制。   ...它采用的是表、字段、连接等要素,而不需要使用常见的高级语言的变量、类、函数等要素。   ...MySQL 的语法分析器是用bison 工具生成的,bison 是一个语法分析器生成工具,它是GNU 版本的 yacc。...一般研究表达式的时候,我们总是会关注编译器是如何处理结合性和优先级的。那么,bison如何处理的呢?   原来,bison 里面有专门的规则,可以规定运算符的优先级和结合性。...四、重温LR算法   你在阅读 yacc.yy 文件的时候,在注释里,你会发现如何跟踪语法分析器的执行过程的一些信息。

54230

编译入门 - 从零实现中文计算器

基本概念 如何执行一个字符串 1+1 呢?在 JS 中,我们可以直接执行 eval('1+1') 就行了,这将会输出 2。如果不能使用 eval 这些函数,那么如何执行这个字符串呢?...GNU bisonBison意为犎牛;而Yacc与意为牦牛的Yak同音)是一个自由软件,用于自动生成语法分析器程序,实际上可用于所有常见的操作系统。...GNU bison基本兼容Yacc,并做了一些改进。它一般与flex一起使用。 上面介绍了几个有名的工具,这些工具在其他语言中都有对应的类库,比如 JS 中的 bison 叫 jison。...比如下图是字符串 1 + 2 * (3 + 4) 生成的 AST。 可以发现字符串中的括号并没有与之对应的节点,而是使用树的层级来描述对应的优先级。...其中 INT 为叶子节点,双向运算和单运算为树枝节点,比如 1 + 2,就是一个双向节点,它的左子节点是 INT(1),右子节点是的 INT(2)。

74210

TiDB SQL Parser 的实现

&1 ... goyacc是yacc的Golang版,所以要想看懂语法规则定义文件parser.y,了解解析器是如何工作的,先要对Lex & Yacc有些了解。...Lex & Yacc 介绍 Lex & Yacc 是用来生成词法分析器和语法分析器的工具,它们的出现简化了编译器的编写。...Spark的SQL解析就是使用了ANTLR。Lex & Yacc 相对显得有些古老,实现的不是那么优雅,不过我们也不需要非常深入的学习,只要能看懂语法定义文件,了解生成的解析器是如何工作的就够了。...上面只列出了规则定义部分,可以看出该规则使用正则表达式定义了变量、整数和操作符等几种token。...我们可以使用 position 的形式访问堆栈中的项,1引用的是第一项,2引用的是第二项,以此类推。 上面例子中语法规则关联的动作,在完成语法解析的同时,也完成了表达式求值。

41310

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

之所以我要写自己的语法分析生成器,原因是当时这玩意(我熟悉的)相当稀少——基本上就是用 Yacc(有个 GNU 的重写版,叫作 Bison(译注:美洲野牛),但我不确定那时的自己是否知道);或者是自己手写一个...龙书还教会了我如何将正则表达式转换成 DFA,所以我把所有这些东西一结合,pgen 就诞生了。【更新:请参阅下文,对于这个理由,有个略微不同的版本。】 我曾不熟悉更高级的技术,或者曾认为它们效率太低。...至于词法分析器(lexer),我决定不使用生成器——我对 Lex 的评价要比 Yacc 低得多,因为在尝试扫描超过 255 个字节的标记符时,我所熟悉的 Lex 版本会发生段错误(真实的!)。...如果让我重做一遍,我可能会选择一个更强大的解析引擎,可能是 LALR(1) 的某个版本(例如 Yacc/Bison)。...2019 年 3 月更新:Python 3.8 将删除 pgen 的 C 版本,转而使用重写的 pgen2 版本。

1.3K30

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

&1 ... goyacc 是 yacc 的 Golang 版,所以要想看懂语法规则定义文件 parser.y,了解解析器是如何工作的,先要对 Lex & Yacc 有些了解。...Lex & Yacc 介绍 Lex & Yacc 是用来生成词法分析器和语法分析器的工具,它们的出现简化了编译器的编写。...上面只列出了规则定义部分,可以看出该规则使用正则表达式定义了变量、整数和操作符等几种 token。...我们可以使用 $position 的形式访问堆栈中的项,$1 引用的是第一项,$2 引用的是第二项,以此类推。$$ 代表的是归约操作执行后的堆栈顶。...完成了语法规则文件 parser.y 的定义,就可以使用 goyacc 生成语法解析器: bin/goyacc -o parser/parser.go parser/parser.y 2>&1 TiDB

4.5K100

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

右边的图是一个简单的编译流程图,在早期,编写编译器相当耗时,直到Lex和YACC的诞生,有了它们,开发者只需要关注如何设计词法和语法规则,剩下的解析器代码都由它们来生成处理,大大提高了程序编译解析器开发的效率...接着,来看语法规则的漏洞模式: 正如右上图代码所示,print_console这个规则里,会把WORD(词素)传递到printf函数里($2表示为WORD),那么在第一步词法分析中,非法的输入hello...Yy就是yacc的那个y,大家可以读一下它的代码,他们写的时候并不是十分规范,大量使用了全局变量,我猜测这个yy是为了避免生成的代码。...所以不难理解,现在它扫描到8686u,所以-1的位置就是等号,-2的位置就是location。 让我们看看最感兴趣的第三个参数,这也是他明显写错的地方。...2.避免过于宽泛的定义 避免一个规则对应多种类型的变量,C系列是强类型的语言,尤其是从Java移植过来的代码,更要检验是否存在某个规则过于宽泛。

96040
领券