编译原理实验3(基于算符优先文法分析的语法分析器 )

  • 实验目的
  1. 加深对语法分析器工作过程的理解;
  2. 加强对算符优先分析实现语法分析程序的掌握;
  3. 能够产用一种编程语言实现简单的语法分析程序;
  4. 能够使用自己编写的分析程序对简单的程序段进行语法分析。
  • 实验要求
  1. 根据简单表达式文法构造算符优先分析表
  2. 根据构造出来的算符优先分析表进行表达式的分析

  • 实验内容
  1. 在之前实验的基础上,用算符优先分析法编制语法分析程序,语法分析程序的实现可以采用任何一种编程语言和工具。
  2. 分析对象(算数表达式)的BNF定义如下:

<表达式> ::= [+|-]<项>{<加法运算符> <项>}

<项> ::= <因子>{<乘法运算符> <因子>}

<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’

<加法运算符> ::= +|-

<乘法运算符> ::= *|/

<关系运算符> ::= =|#|<=|>|>=

<标识符> ::= <字母>{<字母>|<数字>}

<无符号整数> ::= <数字>{<数字>}

<字母> ::= a|b|...|X|Y|Z

<数字> ::= 0|1|...|8|9

  1. 改为一般的文法形式,即普通的巴克斯范式

为表示方便:

  表达式E、项X、因子Y、标识符b,无符号整数z,加法运算符A,乘法运算符C,关系运算符G,

E->AX|X|EAX

X->Y|XCY

Y->b|z|(E)

A->+|-

C->*|/

  • 实验步骤
  1. 本程序中的文法,实质上为算数表达式的计算;
  2. 构建First VT()和Last VT()
  3. 构建优先符号表
  4. 构建词法分析的程序,实验一的内容
  5. 编写main()函数,用户输入文法对语句利用算符优先文法进行判别。

  • 实验算法流程图
  1. 算法思想

      用栈存储已经看到的输入符号,用优先关系指导移动规约语法分析器的动作,如果栈顶的终结符和下一个输入符之间的优先关系时<或者=,则语法分析器移动,表示还没有发现句柄的右端,如果时>关系,就调用归约。

模块一:解析产生式

  1. 功能:把产生式:S->aB解析成VN:S、B,VT:a
  2. 输入约定:这实际上是词法分析的范畴,这里为了简便,先用默认产生式是比较简单而且按照规范来写,大写字母代表VN,小写字母代表VT,并且是单个字符。
  3. 实现思路:

把产生式以->推导符号为边界分为左右两部分,左边一定是VN,右边大写字母是VN,小写字母是VT,为了避免重复记录,可以用一个map来记录是否出现过,map里key是VN或VT,值是它们在数组里的下标。既能起到记录的作用,又能便于之后使用时快速查找。

模块二:构建FIRSTVT()和LASTVT()

  1. 功能:根据FIRST()和LASTVT()定义,通过深度优先搜索来遍历这两个集合。
  2. 构造思想:

FIRSTVT()定义:

简单地说,FIRST集是推导出第一个VT,它是找推出的第一个VT或者第一个VN或者接着VN后的VT。

LASTVT()定义:

简单地说,找最后一个VT或者最后一个VN和倒数第二个VT。

  1. 函数说明

函数接口

函数功能

void GetFirstvt()

计算并打印FIRSTVT集

void SearchFirstvt(int x)

搜索指定VN的FIRSTVT集

void GetLastvt()

计算并打印LASTVT集

void Searchlastvt()

搜索指定VN的LASTVT集

模块三:构建算术优先符号表

  1. 功能:根据求出的FIRSTVT()和LASTVT()集构建算术优先符号表。
  2. 构造思想:

考虑下面的四种情况:

  1. A->...ab...,则a==b
  2. A->...aB...,则a<FIRSTVT(B)
  3. A->...Ba...,则a>FIRSTVT(B)
  4. A->...aBb,则a==b(最后三个)

对于每条产生式判断这四种情况即可构造算术优先符号表。

  1. 流程图

模块四:表达式语法分析

  1. 功能:

根据求出的算符优先分析表进行语法分析

  1. 输入约定:

只含+ - * / ( )这五种运算符,若是其他则会报错。

  1. 函数接口

函数接口

函数功能

void Calculate(char t1,char t2)

计算表达式值

int GetNum(int d1,int d2,char op)

四则运算

  1. 流程图

  1. 实现方法:

遍历表达式

考虑下面五种情况:

  1. 当前字符是数字,则直到当前字符不是数字时才退出,并压入数据栈
  2. 当前字符是VT且符号栈空,压入符号栈
  3. 当前字符是VT且符号栈非空,通过算符优先分析表判断当前字符和符号栈顶元素的优先级,若是当前优先级大则压入栈,若相等则弹出栈顶,若小于则用当前栈顶符号来计算,小于完后要continue,其他情况都是++i。
  4. 表达式遍历完且符号栈非空,依次弹出栈顶符号来计算。
  5. 表达式遍历完且符号栈空,数据栈栈顶元素是表达式计算结果值。

模块五:运算符识别计算

(1)功能

根据符号栈和数据栈来计算表达式的值

(2)构造思路:

数据栈:

如果表达式合法,每次运算数据栈都能弹出两个数字,并在符号栈空计算完时,数据栈存在一个数字,即表达式的结果。因此每次运算弹出两个数字,并把结果压入栈里。

符号栈:

考虑两种情况:

  1. + - * /四则运算,数据栈弹出两个数字,计算完结果压入即可
  2. 其他则报错

  1. 关键函数
  1. int main()函数

功能:创输入样例,计算VN、VT集合,调用GetFirstvt() 、GetLastvt() 、GetPriorityTabel() 、Analyze()

  1. void GetFirstvt()函数

功能:计算并打印FIRSTVT集,调用SearchFirstvt()

  1. void SearchFirstvt(int x)

功能:搜索指定VN的FIRSTVT集

  1. void GetLastvt()

功能:计算并打印LASTVT集,调用SearchLastvt()

  1. void SearchLastvt(int x)

功能:搜索指定VN的LASTVT集

  1. void GetPriorityTabel()

功能:计算并打印算术优先符号表

  1. void Analyze()

功能:分析表达式,调用Calculate()计算

  1. voiod Calculate(char t1,char t2)

功能:计算表达式值,调用GetName()得到结果

  1. int GetNum(int d1,int d2,char op)

功能:四则运算

  1. void PrintLine(string t=_____)

功能:打印一行一行来分割

  1. 算法流程

在Itc的程序中,文法是给定的,不用自行输入文法。只需要输入表达式,对表达式进行分析(表达式在实验一中已经进行过词法分析,以词法分析的结果作为输入。)

程序整体执行

函数之间的调用关系

  • 实验结果与分析
  1. 生成项目

2. 首先先对给出的文法求FirstVT、LASTVT集合

在程序中写了打印出来的函数,看结果是否正确

3.再求算符优先关系表

4.修改原来的代码,再到itc 进行验证

案例1

案例2

根据程序运行得到的结果可以看出:编写的代码正确

  • 实验体会

1.实验总结

本次实验通过对文法进行处理,获取FIRSTVT()集合、LASTVT()集合和算符优先关系表,从而进一步对语句进行分析判断。通过本次实验我对语义分析有了更进一步的理解。

实验过程中遇到的问题有:

  1. FIRSTVT()和LASTVT()者两个集合的构建。

解决方法:对书本中的原理进一步学习,写出伪代码,进一步进行功能的编写。

  1.  如何利用FIRSTVT()和LASTVT() 集合构建算符优先关系表。

解决方式:多次尝试如下的伪代码,从而实现该关系表的代码化。

FOR 每个产生式 P->X1 X2 ……Xn   

DO  FOR  i:=1  TO   n-1    DO      

      IF  X[i]和X[i+1]均为终结符

        THEN   置 X[i]=X[i+1]        

      IF  X[i]和X[i+2]均为终结符,X[i+1]为非终结符,i≤n-2,       

        THEN   置 X[i]=X[i+2]                

      IF  X[i]为终结符, 但X[i+1]为非终结符                                    

      THEN  FOR  FIRSTVT(X[i+1])中的每个a                                    

          DO  置 X[i]<a                

      IF  Xi为非终结符, 但X i+1 为终结符                                  

          THEN  FOR  LASTVT(X i )中的每个a

              DO   置 a>X[i+1]      

  1. 实验中的输入输出格式可以进一步调整优化,不过对于ITC的验证已经满足了。代码的注释有待增加,代码可读性也有进一步提升的空间。还有实验中开始的代码是输入文法,对文法求FIRSTVT集 和LASTVT集,再构造算符优先关系表,最后输入表达式,对表达式进行分析。但是itc的验证是以已经给定了文法,然后以实验一的词法分析结果作为输入,所以这里在代码实现上还存在一些问题,需要改进。

2.实验反思

这次的实验花费了我不少时间,但也从中学到了很多,从最初的第一个模块一路走来,也遇到许多挫折,特别是明明逻辑都对却找不到错误的原因的时候,多亏了调试工具。  编写这个程序一部分来自于学习的课程要求,另一部分也来自于对编程的喜爱,或许正是这种感觉一直支持我到现在吧。代码虽然写完了,对于老师给的文法绝对是没问题的,可毕竟也有它的局限性。即便如此,编译原理的处理问题的思想,思考问题的角度,都让我大受启发。这个程序其实是很全面的,它从词法分析-->语法分析-->语义分析---->问题求解,基本上走完了编译器的大部分生命周期。对于我们理解编译的过程和具体的实现都是很有帮助的。

当然,编译原理博大精深,比如说对于数组的处理、中间代码的生成、数据结构的相关知识等很多方面,都值得我们认真揣摩。这次实验难度其实还是可以的,理解和掌握算符优先文法来分析,以及对栈,Table结构体的理解对编写代码尤为重要。

这一次编译原理实验课,总结前几次次实验课的经验与教训:理解好项目给出的数据结构,以及演示模式程序执行的步骤和输出结果,熟练掌握数据结构的相关知识是完成代码的关键。

总的来说,通过这次实验课,既加深了我对编译原理课程重点内容的理解,又复习了数据结构的相关知识,提高了编写代码的能力,收获良多。

最后,特别感谢刘老师一直以来的耐心指导和同学的热心帮助。

代码

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实景三维在文化旅游领域的应用

实景三维技术&#xff0c;作为一种前沿的科技手段&#xff0c;近年来在文化旅游领域的应用逐渐崭露头角。它能够将真实世界的场景以三维的形式精确呈现&#xff0c;为游客带来身临其境的体验&#xff0c;为文化旅游注入新的活力。本文将探讨实景三维在文化旅游领域的应用及其所…

算法汇总啊

一些常用算法汇总 算法思想-----数据结构动态规划(DP)0.题目特点1.【重点】经典例题(简单一维dp&#xff09;1.斐波那契数列2.矩形覆盖3.跳台阶4.变态跳台阶 2.我的日常练习汇总(DP)1.蓝桥真题-----路径 算法思想-----数据结构 数据结构的存储方式 : 顺序存储(数组) , 链式存储…

【一步一步学】新手如何学习RouterOS

最近有很多同学私下问&#xff1a;ROS太难学&#xff0c;很难入门。 我在这里统一回答大家这个问题&#xff0c;其实入门还是比较简单&#xff0c;今天我写一个大概的学习过程 &#xff0c;后续是需要你们自己针对性学习与深入研究。 1. 了解RouterOS基础 学习任何东西&#x…

K8S之Job和CronJob控制器

这里写目录标题 Job概念适用场景使用案例 CronJob概念适用场景使用案例 Job 概念 Job控制器用于管理Pod对象运行一次性任务&#xff0c;例如&#xff1a;对数据库备份&#xff0c;可以直接在k8s上启动一个mysqldump备份程序&#xff0c;也可以启动一个pod&#xff0c;这个pod…

PostgreSQL入门到实战-第二弹

PostgreSQL入门到实战 PostgreSQL安装之Windows官网地址PostgreSQL概述Windows上安装PostgreSQL更新计划 PostgreSQL安装之Windows 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://www.postgresql.org/PostgreSQL概…

【Attention(0)】卷首语,从“SEAttention注意力效果秒杀CBAM”聊到“Transformer”

Attention 注意力是一个非常有价值的机制&#xff0c;例如我们耳熟能详的 SE attention。我们常常看到这样的标题《YOLOv8&#xff0c;注意力&#xff0c; SEAttention注意力&#xff0c;效果秒杀CBAM》。 其实&#xff0c;CBAM 是一种“卷积神经网络注意力模块”(Convolution…

The Sandbox:在NFT Paris 2024引领数字文艺复兴

我们的欧洲、中东和非洲&#xff08;EMEA&#xff09;总部位于法国巴黎&#xff0c;我们的创始人也是土生土长的法国人&#xff0c;因此 The Sandbox 一直与 "光之城 "有着紧密的联系。近年来&#xff0c;巴黎日益成为 Web3 创新的中心&#xff0c;NFT 艺术氛围日益浓…

动态规划刷题(算法竞赛、蓝桥杯)--线段(线性DP)

1、题目链接&#xff1a;P3842 [TJOI2007] 线段 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include <bits/stdc.h> using namespace std; const int N20010; int a[N][2],f[N][2]; //a[i][0]表示l[i],a[i][1]表示r[i] int dis(int a,int b){return abs(a-b); } int…

企业级开源路由系统VyOS-构建和使用

介绍 VyOS是一个基于Linux的企业级路由器操作系统&#xff0c;被许多公司和个人用来驱动物理网络设备&#xff0c;如路由器和防火墙。它有一个统一的命令行界面来管理其所有的网络相关功能&#xff08;和Juniper Junos操作很像&#xff09;。VyOS使用Debian GNU/Linux作为其基…

【JAVASE】带你了解instanceof和equals的魅力

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 1.instanceof instanceof 是 Java 的保留关键字。它的作用是测试…

自动化高并发批量抓取京东平台商品数据(内附接入key密钥API响应示例)

通过API接口&#xff08;接入key&#xff0c;密钥&#xff09;&#xff0c;可以获取商品的标题、价格、图片、描述等详细信息。 参数说明 通用参数说明 version:API版本key:调用key,测试key:test_api_keysecret:调用secret,测试secret:(不用填写)cache:[yes,no]默认yes&#x…

Java Netty个人对个人私聊demo

一、demo要求 1&#xff09;编写一个Netty个人对个人聊天系统&#xff0c;实现服务器端和客户端之间的数据简单通讯&#xff08;非阻塞&#xff09; 2&#xff09;实现单人对单人聊 3&#xff09;服务器端&#xff1a;可以监测用户上线&#xff0c;离线&#xff0c;并实现消…

【游戏逆向】游戏全屏捡物的实现

0x0前言&#xff1a; 在角色对战类中&#xff0c;拾取怪物掉落的装备是一项必备的工作&#xff0c;由于装备位置掉落的不确定性&#xff0c;玩家想要拾取离角色距离较远的装备需要一定的时间&#xff0c;这一段时间往往会影响游戏的评分或是玩家的心态&#xff0c;基于此&…

【经典算法】LeetCode25:K 个一组翻转链表(Java/C/Python3,Hard)

#算法 目录 题目描述思路及实现方式一&#xff1a;递归思路代码实现Java 版本C 语言版本Python3 版本 复杂度分析 方式二&#xff1a;迭代和原地反转思路代码实现Java 版本C 语言版本Python3 版本 复杂度分析 总结相似题目 标签&#xff1a;链表、递归 题目描述 给你链表的头…

接口日志配置表

表&#xff1a;ZTALL_LOGCFG ZE_ENABLED XFIELD ZE_LOGGING XFIELD ZE_NOTRANS XFIELD ZE_IFURL TEXT255 MANDT MANDT CLNT 3 0 0 客户端 SYSID SYST_SYSID CHAR 8 0 0 ABAP 系统字段&#xff1a;SAP 系统的名称 IFSNR ZE_IFSNR CHAR 30 0 0 接口编号(系统ID流水号…

线程安全--深入探究线程等待机制和死锁问题

꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转…

9亿用户、估值300亿美元,「暗黑版微信」决定上市

自 2017 年以来&#xff0c;Telegram 的创始人帕维尔•杜罗夫&#xff08;Pavel Durov&#xff09;就从没有接受过任何公共采访。直到不久前&#xff0c;这位神秘的亿万富翁接受了英国《金融时报》的采访&#xff0c;他向外界释放出了一个信号——Telegram 正在谋求 IPO。 根据…

Springboot相关知识-图片描述(学习笔记)

学习java过程中的一些笔记&#xff0c;觉得比较重要就顺手记录下来了~ 目录 一、前后端请求1.前后端交互2.简单传参3.数组集合传参4.日期参数5.Json参数6.路径参数7.响应数据8.解析xml文件9.统一返回类10.三层架构11.分层解耦12.Bean的声明13.组件扫描14.自动注入 一、前后端请…

《Java面试自救指南》(专题三)数据库

文章目录 一条sql语句的查询流程有哪些数据库存储引擎&#xff0c;各自的区别数据库的三大范式事务的四大特性&#xff08;含隔离级别&#xff09;MySQL四种隔离机制的底层实现&#xff08;如何解决幻读 &#xff09;MySQL有哪几种锁&#xff0c;分别怎么实现数据库中有哪些索引…

Leetcode-Hot 100题目分类

哈希 &#xff08;以空间换时间&#xff09; 1 两数之和 原始的暴力破解的方法&#xff1a; class Solution {public int[] twoSum(int[] nums, int target) {/** 暴力破解的方法 */int[] result new int[2];int length nums.length;for(int i 0;i<length;i){for(int j…