编译原理本科课程 专题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.hqwc.cn/news/453948.html

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

相关文章

Matlab数字图像处理——图像复原与滤波算法应用方法

图像处理领域一直以来都是计算机科学和工程学的一个重要方向&#xff0c;图像复原则是其中一个重要的研究方向之一。图像复原旨在通过运用各种滤波算法&#xff0c;对图像进行去噪、恢复和改善&#xff0c;以提高图像的质量和可视化效果。在本文中&#xff0c;我们将介绍如下内…

数据库基础【数据库】

一、登录 mysql -h 127.0.0.1 -P 3306 -u root -p 也可以按默认配置的&#xff1a; 退出&#xff1a;\q或quit 二、mysql和mysqld mysql是数据库服务的客户端 mysqld是数据库服务的服务器端 mysql本质是基于C&#xff08;mysql&#xff09;S&#xff08;mysqld&#xff09;模式…

(十三)Java开发扩展之软件包与安装——JDK和MySQL

文章目录 1、RPM1.1、什么是RPM&#xff1f;1.2、RPM包的名称格式1.2.1、RPM查询命令1.2.2、RPM卸载命令1.2.3、RPM安装命令 2、YUM2.1、什么是YUM?2.2、yum安装程序命令 3、安装JDK4、安装MySQL 1、RPM 1.1、什么是RPM&#xff1f; RPM&#xff08;RedHat Package Manager&a…

前端excel带样式导出 exceljs 插件的使用

本来用的xlsx和xlsx-style两个插件&#xff0c;过程一步一个坑&#xff0c;到完全能用要消灭好多bug。这时发现了exceljs&#xff0c;真香&#x1f600; 案例 <!DOCTYPE html> <html><head><meta charset"utf-8" /><meta name"view…

IDEA插件ChatGPT - Easycode安装使用

IDEA插件ChatGPT - Easycode简介 ChatGPT - Easycode 是一个由 OpenAI 开发的 IntelliJ IDEA 插件&#xff0c;它可以利用 ChatGPT 的强大语言生成能力&#xff0c;帮助开发人员提高编码效率。 主要功能&#xff1a; 代码生成&#xff1a;可以根据自然语言描述生成代码&…

scikit-learn 1.3.X 版本 bug - F1 分数计算错误

如果您正在使用 scikit-learn 1.3.X 版本&#xff0c;在使用 f1_score() 或 classification_report() 函数时&#xff0c;如果参数设置为 zero_division1.0 或 zero_divisionnp.nan&#xff0c;那么函数的输出结果可能会出错。错误的范围可能高达 100%&#xff0c;具体取决于数…

PHP框架详解 - symfony框架

首先说一下为什么要写symfony框架&#xff0c;这个框架也属于PHP的一个框架&#xff0c;小编接触也是3年前&#xff0c;原因是小编接触Golang&#xff0c;发现symfony框架有PHP框架的东西也有Golang的东西&#xff0c;所以决定总结一下&#xff0c;有需要的同学可以参看小编的G…

我用JVS低代码平台,搭建了一套固定资产管理系统

随着企业规模的不断扩大和业务的快速发展&#xff0c;资产管理成为了企业运营中的重要环节。然而&#xff0c;传统的手工管理模式已经无法满足现代企业的需求&#xff0c;管理效率低下、信息不准确、流程不规范等问题逐渐凸显。为了解决这些问题&#xff0c;越来越多的企业开始…

(源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模

本篇文章是: 2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模的源码版本,包含具体建模代码到生成模型步骤。那么废话不多说直接开始展示建模过程建模: 数据预处理 之前我给大家提供的一年的风暴数据是远远不够的,要做时…

五部委将联合开展智能网联汽车“车路云一体化”应用试点工作

作者介绍 近期&#xff0c;工业和信息化部、公安部、自然资源部、住房和城乡建设部、交通运输部五部委联合发布《关于开展智能网联汽车“车路云一体化”应用试点工作的通知》&#xff0c;提出将建成一批架构相同、标准统一、业务互通、安全可靠的城市级应用试点项目&#xff0c…

架构学习(四):scrapy下载中间件实现动态切换User-Agent

scrapy下载中间件实现动态与固定UserAgent 前言关卡&#xff1a;实现动态切换User-Agentscrapy设置User-Agent方式梳理User-Agent生效梳理为何选择在下载中间件中实现自定义User-Agent下载中间件 结束 前言 请求头User-Agent是比较常规的反爬手段&#xff0c;不同站点对其检测…

vue项目集成booststrap

1.首先安装bootstrap npm install bootstrap 我安装的是4.3的版本 2.在main.js中引用bootstrap import bootstrap/dist/css/bootstrap.css import bootstrap/dist/css/bootstrap.min.css import bootstrap/dist/js/bootstrap.js import bootstrap/dist/js/bootstrap.min.…