第1关:用Bison构建逆波兰计算器

2023-11-03

任务描述
相信大家通过flex的实验已经掌握了如何构建一个词法分析器,但是为了创建一个完整的编译程序,我们还需要一个语法分析器。同样的,我们可以使用现有的工具来节省开发的时间,也就是Unix下的YACC和GNU/Linux下的Bison。
相关知识
逆波兰表达式
逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。下面是一些例子:

a+b —> a b +
a+(b-c) —> a b c - +
a+(b-c)d —> a b c - d * +
a+d
(b-c) —> a d b c - * +
a=1+3 —> a 1 3 + =
逆波兰表达式的逻辑实现是通过栈来完成的,如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个(一个)元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

BNF范式
由于Bison中使用的是BNF范式来描述产生式,这里先简单介绍一下BNF范式。
BNF规定是推导规则(产生式)的集合,写为:
<符号> ::= <使用符号的表达式>
这里的 <符号> 是非终结符,而表达式由一个符号序列,或用指示选择的竖杠’|'分隔的多个符号序列构成,每个符号序列整体都是左端的符号的一种可能的替代。从未在左端出现的符号叫做终结符。

BNF类似一种数学游戏:从一个符号开始(叫做起始标志,实例中常用S表示),然后给出替换前面符号的规则。BNF语法定义的语言只不过是一个字符串集合,你可以按照下述规则书写,这些规则叫做书写规范(生产式规则),形式如下:
symbol := alternative1 | alternative2 …

Bison语法结构
Bison的语法结构和lex/flex类似,也是分为三个部分

/* 定义段 /
%{
C/C++头文件、全局文件、全局变量、类型定义
词法分析器yylex(采用lex进行词法分析)和错误打印函数
%}
Bison声明区间。定义之后用到的终结符、非终结符、操作符优先级
%%
/
规则段 /
Bison语法规则定义
%%
/
用户子程序段 */
C/C++代码 需要定义prologue区域函数,或者其他代码,生成的c/c++文件会完全拷贝这份代码。
终结符、非终结符定义
Token用于定义终结符,type定义非终结符,操作符也属于终结符,left表示左关联运算符,right表示右关联运算符,下面是一些例子:

%token NUM
%nonassoc ‘<’ /表示该终结符无结合性 不能出现a<b<c/
%left ‘+’ ‘-’ /左结合 后面接操作符 下方的操作符比上方的优先级高/
%left ‘’ ‘/’
%right NEG NEG表示非
%right ‘^’
本关任务是利用YACC/Bison构建一个逆波兰符号计算器。
编程要求
根据提示,在右侧编辑器补充代码,实现加法(+)、减法(-)、乘法(
)、除法(/)、乘方(^)以及取负运算(n)!

测试说明
平台会对你编写的代码进行测试:

测试输入:4 5 +,3 4 ^,2 7 + 3 /,16 4 / 12 * n;
预期输出:
9
81
3
-48

 /* 逆波兰符号计算器 */
 /* 功能:能够计算出合法的后缀表达式的值,包括加法、减法、乘法、除法、乘方、取反等运算 */
 /* 说明:在下面的begin和end之间添加代码,加油吧! */
 /* 提示: */

%{
  #include <ctype.h>
  #include <stdio.h>
  #include <math.h>
  int yylex (void);
  void yyerror (char const *);
%}


%define api.value.type {double}
%token NUM

%% 

/* Grammar rules and actions follow.  */

input:
  %empty
| input line
;


line:
  '\n'
| exp '\n'      { printf ("%.10g\n", $1); }
;


exp:
  NUM           { $$ = $1;           }
 /* begin */
| exp exp '+'  { $$ = $1 + $2;      }
| exp exp '-'  { $$ = $1 - $2;      }
| exp exp '*'  { $$ = $1 * $2;      }
| exp exp '/'  { $$ = $1 / $2;      }
| exp exp '^'  { $$ = pow($1,$2);   }
| exp 'n'      { $$ = -1 * $1;      }
 /* end */
;

%%

/* The lexical analyzer returns a double floating point
   number on the stack and the token NUM, or the numeric code
   of the character read if not a number.  It skips all blanks
   and tabs, and returns 0 for end-of-input.  */


int yylex (void)
{
  int c;

  /* Skip white space.  */
  while ((c = getchar ()) == ' ' || c == '\t')
    continue;

  /* Process numbers.  */
  if (c == '.' || isdigit (c))
    {
      ungetc (c, stdin);
      scanf ("%lf", &yylval);
      return NUM;
    }

  /* Return end-of-input.  */
  if (c == EOF)
    return 0;
  if (c == '!')
  	return 0;
  /* Return a single char.  */
  return c;
}

int main (int argc, char** argv)
{
  return yyparse();
}


/* Called by yyparse on error.  */
void yyerror (char const *s)
{
  fprintf (stderr, "%s\n", s);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第1关:用Bison构建逆波兰计算器 的相关文章

  • 第1关:Hbase数据库的安装

    在安装HBase之前你需要先安装Hadoop和Zookeeper 如果你还没有安装可以通过这两个实训来学习 Hadoop安装与配置 Zookeeper安装与配置 本次实训的环境已经默认安装好了Hadoop 接下来我们就开始安装配置HBase
  • 编译原理LL(1)文法之提取左公因子,消除左递归

    在判断LL 1 文法是否符合的时候 需要判断LL 1 文法是否存在左公因子 和左递归的情况 以下给出相应的判断方法以及通过提取左公因子和消除左递归使非LL 1 文法转换为LL 1 法的方法 第一种情况 存在左公因子 解决方法 提取左公因子
  • linux下几种目标文件的分析

    本文中用到的命令 gcc c addvec c 生成可重定位目标文件addvec o readelf addvec o a 读取可重定位目标文件addvec o gcc O2 c main c 生成可重定位目标文件main o gcc st
  • Java面向对象 - 文件类

    文章目录 第4关 图片查看器 挑战任务 答案 第4关 图片查看器 挑战任务 本关任务 小明想要开发一个图片查看器 但是他想只显示文件夹下所有图片类型的文件 你来帮小明实现这个功能吧 答案 代码如下 示例 package step4 impo
  • LL(1)文法的预测分析表以及对某输入串的分析过程

    举例说明LL 1 文法的预测分析 以及对 a a 的分析过程 文法G S S gt a S gt S gt T T gt SN N gt SN N gt 是否 gt First集 Follow集 S 否 a T 否 a N 是 Select
  • 自下而上分析方法-算符优先,LR(0),SLR,LR(1),LALR大全

    文章目录 自下而上分析法 一 规范规约 相关定义 短语 直接短语 句柄 素短语 最左素短语 语法树表示 示例 规范规约 二 语法分析器 三 算符优先分析算法 算符文法 1 算符优先文法 2 FIRSTVT P 和LASTVT P 1 FIR
  • Compiler- 自增运算

    我们来看一下C语言中的前自增 i 和后自增 i 这个经典案例 大家在学习C的时候肯定学过前自增是先自增 然后将结果用于计算 后自增是先参与计算 再增加 好 看一下这段代码的结果 include
  • GCC 在 bison 生成的头文件中显示“数字常量之前的语法错误”

    当我使用 bison parser y d t 编译 y 文件 然后将 parser tab h 文件包含在我的 Flex 文件中时 gcc 说 错误 数字常量之前有语法错误 它引用第 32 行 这是 yytokentype 枚举中的第一行
  • 尝试使用 GNU GMP 库中的类型作为 Bison 的 yylval 类型时出错

    我正在尝试使用该类型mpz t来自 GMP 库的类型yylval通过在 Bison 文件中包含以下内容 define api value type mpz t 我检查了生成的解析器 它正确生成了该行typedef mpz t YYSTYPE
  • Lex 正则表达式获得一些额外的字符

    我的 lex 文件中有以下定义 L a zA Z A a zA Z 0 9 L A yylval id yytext return IDENTIFIER 我在 YACC 文件中执行以下操作 primary expression IDENTI
  • 如何修复编译时 -lfl 缺失的 ld 库?

    我正在尝试翻译我的 spl文件转换成C文件 因为没有编译器 我有一个示例 Hello World spl 文件 并且我已经下载了莎士比亚编程语言 http shakespearelang sourceforge net report sha
  • yyerror 的 Bison 冲突类型

    我试图用 flex 和 bison 制作一个计算器 但在编译过程中发现了一个错误 这是错误 C GnuWin32 src gt gcc lex yy c y tab c o tugas tugas y 51 error conflictin
  • 野牛转移而不是减少。减少/减少错误

    用我的语言我可以写 a 1 b 2 if true else if true Here is the problem else 我的语法不支持语句之间的换行符 else 只能与 if 一起使用 当我在规则中添加可选NL时 IfExpr IF
  • 我的 Flex 文件输出错误

    我编写了一个 l 文件并希望输出 c17 isc 中的内容 但有一个错误我不知道为什么 我已经给出了我打算读取的文件 flex文件和执行结果 这是 c17 isc 文件 内容的意思是 number gate name gate type o
  • 无法配置 CMake 来查找 Bison 的 Homebrew 安装版本

    我正在运行 macOS 10 14 并且安装了bison版本 3 2 与brew 但它拒绝链接 brew link bison force Warning Refusing to link macOS provided software b
  • 使用 qt:如何在控制台应用程序之上构建 GUI?

    我有一个从 bison 解析器 生成的控制台应用程序 我想为其构建一个简单的 GUI 这样我就可以将此 gui 的输入发送到控制台 并将控制台的输出获取到 gui 中 我尝试使用 java process 类来做到这一点 但它对我不起作用
  • Flex 和 Bison 彼此需要什么?

    当 Flex 和 Bison 一起使用时 为什么 Flex 文件需要 includebison 创建的 C 头文件 编译需要 bison 和 flex 创建的 C 源文件 bison 和 flex 创建的 C 源文件相互需要什么 bison
  • LR(k) 到 LR(1) 语法转换

    我对以下内容感到困惑quote http en wikipedia org wiki LR parser Theory来自维基百科 换句话说 如果一种语言足够合理 允许 高效的单遍解析器 可以用 LR k 语法来描述 语法总是可以机械地转化
  • Yacc/Bison:伪变量($$、$1、$2、..)以及如何使用 printf 打印它们

    我有一个用 flex 编写的词法分析器 它将标记传递给用 bison 编写的解析器 以下是我的词法分析器的一小部分 ID a z a z0 9 rule printf A rule s n yytext return RULE ID pri
  • BISON + FLEX 语法 - 为什么标记被连接在一起

    我想了解为什么 BISON 按照以下规则连接两个标记 stmt declaration assignment exp ID lt this rule fprintf stderr n my id is s 1 如果你检查输出就会明白我的意思

随机推荐

  • 大一下第一场

    大一下第一场比赛 太菜了 总结 小错误太多 应该提高严密性 long long scanf lld 有 gt lt 不要忘记了等于的情况 成绩那题 我默认把它看成了小数 其实还有整数的情况 一题有一些小细节没注意导致花了很多时间 诶 长寿的
  • 02-kafka集群搭建

    文章目录 0 服务器准备 1 zookeeper集群 1 1 下载 1 2 拷贝 1 3 配置变量 1 4 配置 1 5 启动 2 kafka 2 1 下载 2 2 拷贝到服务器 2 2 配置文件 2 3 启动 3 使用密码 3 1 配置文
  • win7 计算机属性 灰,打不开win7计算机属性解决方法

    1 点击 开端 单击翻开 记事本 程序 2 复制下面的代码 黏贴到新建的记事本里面 3 Windows Registry Editor Version 5 00 HKEY LOCAL MACHINE SOFTWARE Microsoft W
  • vue-router之 tag 和 v-solt 对比

    1 在vue router4 0之前 我们都是使用 tag 来自定义 router link 渲染成什么标签
  • 获取系统中各应用的运行时间

    通过增加动态库获取应用的运行时间 同事提出一个问题 如何获取嵌入式设备系统中各个应用已运行的时间 这个问题的解决方案有多种 其中一种是使用功能较强的软件作为系统的init进程和服务管理 例如systemd 以它启动各应用软件服务后 可通过s
  • K近邻算法,Matlab实现

    邻近算法 K近邻 通过计算测试样本与训练样本之间的距离 然后找出距离测试样本最近的K个样本 统计他们的结果 哪种类型的的结果出现的次数多则预测测试样本的结果为此结果 代码如下 function label1 KNN training tes
  • Python开发工具PyCharm的web开发教程:创建并运行 Python 项目

    在你开始前 要确定以下两点 PyCharm下载 已完成 安装了 Python PyCharm官方正版下载 要开始使用PyCharm 让我们编写一个 Python 脚本 创建一个 Python 项目 1 如果您在欢迎屏幕上 请单击新建项目 如
  • 关于 “定义_sys_exit()以避免使用半主机模式”的问题

    今天编译一个STM32程序的时候 遇到了一个问题 编译通不过 定义 sys exit 以避免使用半主机模式 void sys exit int x x x 输出的错误信息是 SYSTEM usart usart c 41 error 260
  • MySQL第二讲 MySQL主从架构搭建

    主从架构意义 通过搭建MySQL主从集群 可以缓解MySQL的数据存储以及访问的压力 1 数据安全 给主服务增加一个数据备份 基于这个目的 可以搭建主从架构 或者也可以基 于主从架构搭建互主的架构 2 读写分离 对于大部分的JAVA业务系统
  • python创意小作品-全国青少年创意编程与智能设计大赛Python创意编程比赛

    全国青少年创意编程与智能设计大赛Python创意编程比赛 一 作品类型 1 数字艺术 通过程序生成和展示视觉艺术 具备创意 美感和互动性 2 互动游戏 各种竞技类 探险类 角色扮演类 球类 棋牌类游戏等等 3 实用工具 有实用价值 能解决学
  • vscode js文件没有代码提示

    原因是 产生问题的原因可能是关闭了单纯的js文件中的javascript的提示 1 右下角设置 2 在上边输入 javascript suggest enabled 效果图
  • VBA:对Excel单元格进行合并操作

    Sub hb Dim n n 3 For i 3 To 18 If Range b i lt gt Range b i 1 Then Range b n b i Merge n i 1 End If Next End Sub
  • 自动化测试和性能测试的异同

    对于那些刚刚接触软件测试行业的小白来说 都会有这样一种错觉 觉得性能测试和自动化测试是差不多的 但是如果深入了解 会发现这两者的区分还是很大的 接下来我们就来详细了解一下自动化测试和性能测试的异同之处 首先两者都有一个共同点 那就是在处理脚
  • mysql 投影,MySQL —— select

    select语句使用详解 select语句是基础操作中比较复杂的部分 我们单拿出来详细解析一下 还是以上一篇文章里的student表为例 select from student 查询student表中所有记录 create table st
  • Clion 使用自己编写的 Makefile编译

    Clion 目前支持使用 cmake 来编译代码 如果习惯了自己写 makefile 那么还需要通过 cmake 的 add custom target 来调用make 命令来实现编译了 参考了http stackoverflow com
  • LoadRunner参数化详解

    LoadRunner参数化详解 距离上次使用loadrunner 已经有一年多的时间了 初做测试时在项目中用过 后面项目中用不到 自己把重点放在了工具之外的东西上 认为性能测试不仅仅是会用工具 最近又想有一把好的利器毕竟可以帮助自己更好的完
  • 明天全国哀悼日,小程序只需三行代码秒变黑白

    明天全国哀悼日 小程序只需三行代码秒变黑白 打开你的 app wxss 文件 在第一行加上 page filter grayscale 100
  • postgresql Insert插入的几个报错

    postgresql Insert插入的几个报错 1 org postgresql util PSQLException 未设定参数值 2 的内容 2 postgresql column reference is ambigious 参考
  • GD32的ADC模块简介

    ADC模块简介 驱动板所使用的主控芯片为GD32C103CB 该芯片总共有2个ADC单元 即ADC0 ADC1 因为驱动板上使用的是LQFP48封装 所以该芯片的每个ADC单元只有10个外部模拟输入通道 并且共用相同的GPIO口 这10个外
  • 第1关:用Bison构建逆波兰计算器

    任务描述 相信大家通过flex的实验已经掌握了如何构建一个词法分析器 但是为了创建一个完整的编译程序 我们还需要一个语法分析器 同样的 我们可以使用现有的工具来节省开发的时间 也就是Unix下的YACC和GNU Linux下的Bison 相