编译原理本科课程 专题5 基于 SLR(1)分析的语义分析及中间代码生成程序设计

一、程序功能描述

本程序由C/C++编写,实现了赋值语句语法制导生成四元式,并完成了语法分析和语义分析过程。

以专题 1 词法分析程序的输出为语法分析的输入,完成以下描述赋值语句 SLR(1)文法的语义分析及中间代码四元式的过程,实现编译器前端。

G[S]:     S→V=E

E→E+T∣E-T∣T

T→T*F∣T/F∣F

F→(E)∣i

V→i

二、主要数据结构描述

        关于本程序的数据结构,首先用map存储了非终结符及终结符的编码映射,而后用string存储文件读入和写入的信息等,最重要的是利用vector二维数组实现了SLR分析表,用于存储分析动作;此外定义了四元组和栈的相应结构体。由于本人习惯,字符串处理总体上采用了C风格和C++方式并存的写法。

、程序结构描述

        除main函数外,本程序共定义了4个函数:

        getIndex用于返回输入字符在deCode 映射中的对应索引,若非法字符则返回-1。

dispQuad用于显示解析过程中生成的四元组,并展示输入表达式的中间代码表示;SLR_display则显示分析栈的当前状态、剩余的输入字符串以及解析过程中的当前动作。这两个函数都用于实现编译前端的可视化。

        在SLR_analysis真正实现了SLR(1)文法的分析过程,使用栈 (anstk) 跟踪解析过程中的状态、符号和输入字符串位置,并根据 SLR 解析表执行移入、规约和接受等动作,最后在解析过程中生成四元组,表示中间代码。

四、程序测试

        测试案例展示如下:

        测试用例1:a=((b)+c*d)/f+e*g

#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<map>
using namespace std;
const int N=1024;
string testFileName = "test4.txt";
string info[3] = {"---------------------------", "SLR(1)分析", "---------------------------"};
map<char, int> deCode =
{{'i', 0},{'=', 1},{'+', 2},{'-', 3},{'*', 4},{'/', 5},{'(', 6},{')', 7},{'#', 8},{'S', 9},{'E', 10},{'T', 11},{'F', 12},{'V', 13},
};
vector<vector<int>>table = {{ 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2},{ 0, 0, 0, 0, 0, 0, 0, 0,-11,0,0, 0, 0, 0},{ 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{-10,-10,-10,-10,-10,-10,-10,-10,-10, 0, 0, 0, 0, 0},{ 9, 0, 0, 0, 0, 0, 8, 0, 0, 0, 5, 6, 7, 0},{-1,-1,10,11,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0},{-4,-4,-4,-4,12,13,-4,-4,-4, 0, 0, 0, 0, 0},{-7,-7,-7,-7,-7,-7,-7,-7,-7, 0, 0, 0, 0, 0},{ 9, 0, 0, 0, 0, 0, 8, 0, 0, 0,14, 6, 7, 0},{-9,-9,-9,-9,-9,-9,-9,-9,-9, 0, 0, 0, 0, 0},{ 9, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0,15, 7, 0},{ 9, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0,16, 7, 0},{ 9, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0,17, 0},{ 9, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0,18, 0},{ 0, 0,10,11, 0, 0, 0,19, 0, 0, 0, 0, 0, 0},{-2,-2,-2,-2,12,13,-2,-2,-2, 0, 0, 0, 0, 0},{-3,-3,-3,-3,12,13,-3,-3,-3, 0, 0, 0, 0, 0},{-5,-5,-5,-5,-5,-5,-5,-5,-5, 0, 0, 0, 0, 0},{-6,-6,-6,-6,-6,-6,-6,-6,-6, 0, 0, 0, 0, 0},{-8,-8,-8,-8,-8,-8,-8,-8,-8, 0, 0, 0, 0, 0}};struct quadruple {char op[N];char arg1[N];char arg2[N];char res[N];
};
struct quadruple quad[N];   
int topOfQuad = 0;          struct Stack {char s[N];int i[N];int space[N];int top;
}; int getIndex(char ch);
int SLR_analysis(char *str, struct Stack *anstk);
void SLR_display(char *str, struct Stack *anstk, int cur);
void dispQuad();int main() {for (int i = 0; i < 3; i++)cout << info[i] << endl;FILE *fp = fopen(testFileName.c_str(), "r");char buf[N] = "";char input[N] = "";fgets(buf, N, fp);int j = 0;for(int k = 0; k < strlen(buf); k++) { if(buf[k] == '1' && buf[k+1] == ',') {k += 3;while(1) {if(buf[k] == ')' && buf[k+1] == ' ')break;input[j++] = buf[k++];}continue;}if(buf[k] == ',' && buf[k+1] == ' ') {k += 2;while(1) {if(buf[k] == ')' && buf[k+1] == ' ')break;input[j++] = buf[k++];}}}printf("输入表达式为: %s\n", input); input[j] = '#'; fclose(fp);struct Stack *anstk;anstk = (struct Stack *)malloc(sizeof(struct Stack));anstk->s[0] = '#';anstk->i[0] = 0;anstk->space[0] = -1;anstk->top = 0; if(!SLR_analysis(input, anstk)) {cout << "语法错误!" << endl;}else {cout << "分析成功!" << endl;dispQuad(); }return 0;
}int getIndex(char ch) {if (deCode.find(ch) != deCode.end())return deCode[ch];elsereturn -1;
}void SLR_display(char *str, struct Stack *anstk, int cur) { for(int i = 0; i <= anstk->top; i++) {cout << anstk->s[i];}for(int i = 0; i < 3-(anstk->top+1)/8; i++) {cout<< "\t";}for(int i = cur; i < strlen(str); i++) {cout << str[i];}printf("\n");
}void dispQuad() { printf("四元式:\n");for(int i = 1; i <= topOfQuad; i++) {printf("(%s, %s, %s, %s)\n", quad[i].op, quad[i].arg1, quad[i].arg2, quad[i].res);}
}int SLR_analysis(char *str, struct Stack *anstk) { topOfQuad = 0;int i = 0;int next;printf("分析栈:\t\t\t字符串:\t\t\t动作:\n");while(i < strlen(str)) {if(anstk->top < 0) return 0; int y; if (str[i] >= 'a' && str[i] <= 'z') y = getIndex('i'); else y = getIndex(str[i]);if(y == -1 || table[anstk->i[anstk->top]][y] == 0) { return 0;}if(table[anstk->i[anstk->top]][y] > 0) { next = table[anstk->i[anstk->top]][y];anstk->top++;anstk->s[anstk->top] = str[i];anstk->i[anstk->top] = next;anstk->space[anstk->top] = i;i++;SLR_display(str, anstk, i);}else if(table[anstk->i[anstk->top]][y] < 0) { int tmp = -table[anstk->i[anstk->top]][y]; if(tmp == 4 || tmp == 7 || tmp == 9 || tmp == 10) {anstk->top--; }else if(tmp == 2 || tmp == 3 || tmp == 5 || tmp == 6){topOfQuad++;if(tmp == 2) strcpy(quad[topOfQuad].op, "+");else if(tmp == 3) strcpy(quad[topOfQuad].op, "-");else if(tmp == 5) strcpy(quad[topOfQuad].op, "*");else strcpy(quad[topOfQuad].op, "/");if(anstk->space[anstk->top - 2] < 0) sprintf(quad[topOfQuad].arg1, "t%d", -anstk->space[anstk->top - 2]);else {char arg1[2] = {str[anstk->space[anstk->top - 2]], '\0'};strcpy(quad[topOfQuad].arg1, arg1);}if(anstk->space[anstk->top] < 0) sprintf(quad[topOfQuad].arg2, "t%d", -anstk->space[anstk->top]);else {char arg2[2] = {str[anstk->space[anstk->top]], '\0'};strcpy(quad[topOfQuad].arg2, arg2);}cout << "\t\t\t\t\t\t";printf("t%d = %s %s %s\n", topOfQuad, quad[topOfQuad].arg1, quad[topOfQuad].op, quad[topOfQuad].arg2); sprintf(quad[topOfQuad].res, "t%d", topOfQuad);anstk->top -= 3; anstk->space[anstk->top + 1] = -topOfQuad; }else if(tmp == 8) {anstk->top -= 3; anstk->space[anstk->top + 1] = anstk->space[anstk->top + 2]; }else if(tmp == 1){topOfQuad++;strcpy(quad[topOfQuad].op, "=");if(anstk->space[anstk->top] < 0) sprintf(quad[topOfQuad].arg1, "t%d", abs(anstk->space[anstk->top]));else {char arg1[2] = {str[anstk->space[anstk->top]], '\0'};strcpy(quad[topOfQuad].arg1, arg1);}sprintf(quad[topOfQuad].arg2, " ");char res[2] = {str[anstk->space[anstk->top - 2]], '\0'};strcpy(quad[topOfQuad].res, res);cout << "\t\t\t\t\t\t";printf("%s = %s\n", quad[topOfQuad].res, quad[topOfQuad].arg1);anstk->top -= 3; }else anstk->top -= 3;if(tmp == 1) { y = getIndex('S');next = table[anstk->i[anstk->top]][y]; anstk->top++;anstk->s[anstk->top] = 'S';anstk->i[anstk->top] = next; }else if(tmp == 2 || tmp ==3 || tmp == 4) {y = getIndex('E');next = table[anstk->i[anstk->top]][y]; anstk->top++;anstk->s[anstk->top] = 'E';anstk->i[anstk->top] = next;}else if(tmp == 5 || tmp == 6 || tmp == 7) {y = getIndex('T');next = table[anstk->i[anstk->top]][y];anstk->top++;anstk->s[anstk->top] = 'T';anstk->i[anstk->top] = next;}else if(tmp == 8 || tmp == 9) {y = getIndex('F');next = table[anstk->i[anstk->top]][y];anstk->top++;anstk->s[anstk->top] = 'F';anstk->i[anstk->top] = next;}else if(tmp == 10) {y = getIndex('V');next = table[anstk->i[anstk->top]][y];anstk->top++;anstk->s[anstk->top] = 'V';anstk->i[anstk->top] = next;}else if(tmp == 11) {return 1; }SLR_display(str, anstk, i);}}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源节点框架STNodeEditor使用

节点&#xff0c;一般都为树形Tree结构&#xff0c;如TreeNode&#xff0c;XmlNode。 树形结构有其关键属性Parent【父节点】&#xff0c;Children【子节点】 LinkedListNode为链表线性结构&#xff0c;有其关键属性Next【下一个】&#xff0c;Previous【上一个】&#xff0c…

1978-2022年人民币汇率(年平均价)数据

1978-2022年人民币汇率&#xff08;年平均价&#xff09;数据 1、时间&#xff1a;1978-2022年&#xff0c;其中人民币对欧元汇率时间为2002-2022年 2、指标&#xff1a;人民币对美元汇率(美元100)(元)、人民币对日元汇率(日元100)(元)、人民币对港元汇率(港元100)(元)、人民…

华为突然官宣:新版鸿蒙系统,正式发布

华为&#xff0c;一家始终引领科技创新潮流的全球性企业&#xff0c;近日再次引发行业震动——全新HarmonyOS NEXT&#xff0c;被誉为“纯血版鸿蒙”的操作系统正式官宣。这是华为在操作系统领域迈出的坚实且具有突破性的一步&#xff0c;标志着华为正逐步摆脱对安卓生态系统的…

3D力导向树插件-3d-force-graph学习002

一、实现效果&#xff1a;节点文字同时展示 节点显示不同颜色节点盒label文字并存节点上添加点击事件 二、利用插件&#xff1a;CSS2DRenderer 提示&#xff1a;以下引入文件均可在安装完3d-force-graph的安装包里找到 三、关键代码 提示&#xff1a;模拟数据可按如下格式填…

Node.js 包管理工具

一、概念介绍 1.1 包是什么 『包』英文单词是 package &#xff0c;代表了一组特定功能的源码集合 1.2 包管理工具 管理『包』的应用软件&#xff0c;可以对「包」进行 下载安装 &#xff0c; 更新 &#xff0c; 删除 &#xff0c; 上传 等操作。 借助包管理工具&#xff0…

视频美颜SDK开发指南:从入门到精通的技术实践

美颜SDK是一种强大的工具&#xff0c;它不仅仅可以让用户在实时视频中获得光滑的肌肤和自然的妆容&#xff0c;从简单的滤镜到复杂的人脸识别&#xff0c;美颜SDK涵盖了广泛的技术领域。 一、美颜SDK的基本原理 美颜SDK包括图像处理、人脸检测和识别、滤镜应用等方面。掌握这些…

uniapp中使用EelementPlus

uniapp的强大是非常震撼的&#xff0c;一套代码可以编写到十几个平台。这个可以在官网上进行查询uni-app官网。主要还是开发小型的软件系统&#xff0c;使用起来非常的方便、快捷、高效。 uniapp中有很多自带的UI&#xff0c;在创建项目的时候&#xff0c;就可以自由选择。而E…

Unity类银河恶魔城学习记录1-11 PlayerPrimaryAttack P38

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Player.cs using System.Collections; using System.Collections.Generic…

苹果公司宣布,为Apple Vision Pro打造了超过600款新应用

深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领域的领跑者。点击订阅&#xff0c;与未来同行&#xff01; 订阅&#xff1a;https://rengongzhineng.io/ 。 2月…

JavaWeb之HTML-CSS --黑马笔记

什么是HTML ? 标记语言&#xff1a;由标签构成的语言。 注意&#xff1a;HTML标签都是预定义好的&#xff0c;HTML代码直接在浏览器中运行&#xff0c;HTML标签由浏览器解析。 什么是CSS ? 开发工具 VS Code --安装文档和安装包都在网盘中 链接&#xff1a;https://p…

git整合分支的两种方法——合并(Merge)、变基(Rebase)

问题描述&#xff1a; 初次向git上传本地代码或者更新代码时&#xff0c;总是会遇到以下两个选项。有时候&#xff0c;只是想更新一下代码&#xff0c;没想到&#xff0c;直接更新了最新的代码&#xff0c;但是自己本地的代码并没有和git上的代码融合&#xff0c;反而被覆盖了…

机器学习系列——(六)数据降维

引言 在机器学习领域&#xff0c;数据降维是一种常用的技术&#xff0c;旨在减少数据集的维度&#xff0c;同时保留尽可能多的有用信息。数据降维可以帮助我们解决高维数据带来的问题&#xff0c;提高模型的效率和准确性。本文将详细介绍机器学习中的数据降维方法和技术&#…

浅谈——开源软件的影响力

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a…

数据结构与算法:图论(邻接表板子+BFS宽搜、DFS深搜+拓扑排序板子+最小生成树MST的Prim算法、Kruskal算法、Dijkstra算法)

前言 图的难点主要在于图的表达形式非常多&#xff0c;即数据结构实现的形式很多。算法本身不是很难理解。所以建议精通一种数据结构后遇到相关题写个转换数据结构的接口&#xff0c;再套自己的板子。 邻接表板子&#xff08;图的定义和生成&#xff09; public class Graph…

Java I/O 流

内容体系图 文件基础 说明&#xff1a;输入输出是针对内存来说的 常用的文件操作

zabbix监控mariadb数据库

zabbix监控mariadb数据库 1.创建监控用户及授权 [rootchang ~]# mysql -uroot -p123qqq.A MariaDB [(none)]> CREATE USER monitor% IDENTIFIED BY 123qqq.A; MariaDB [(none)]> GRANT REPLICATION CLIENT,PROCESS,SHOW DATABASES,SHOW VIEW ON *.* TO monitor%; Maria…

Coil:Android上基于Kotlin协程的超级图片加载库

Coil&#xff1a;Android上基于Kotlin协程的超级图片加载库 1. coil简介 在当今移动应用程序的世界中&#xff0c;图片加载是一个不可或缺的功能。为了让应用程序能够高效地加载和显示图片&#xff0c;开发人员需要依赖于强大的图片加载库。而今天&#xff0c;我将向大家介绍…

爱上算法:每日算法(24-2月4号)

&#x1f31f;坚持每日刷算法&#xff0c;&#x1f603;将其变为习惯&#x1f91b;让我们一起坚持吧&#x1f4aa; 文章目录 [232. 用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/)思路CodeJavaC 复杂度 [225. 用队列实现栈](https://leetcode.cn/…

使用java -jar命令运行jar包提示“错误:找不到或无法加载主类“的问题分析

用maven把普通java项目打包成可运行的jar后&#xff0c;打开cmd用java -jar运行此jar包时报错&#xff1a; 用idea运行该项目则没有问题 。 其实原因很简单&#xff0c;我们忽略了2个细节。 java指令默认在寻找class文件的地址是通过CLASSPATH环境变量中指定的目录中寻找的。我…

Seata介绍

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 Seata 中有三⼤模块&#xff0c;分别是 TM、RM 和 TC。其中 TM 和 RM 是作为 Seata 的客户端与业务系统集成在⼀起&#xff0c;TC 作为 Seata 的服务端独⽴部署…