编译原理实验日志

2023-11-12

编译原理--生成四元式

实验原理

在这里插入图片描述
在这里插入图片描述

构造SLR(1)分析表

首先求得follow集
follow(E)={#,+,-,)}
follow(T)={#,+,-,),,/}
follow(F)={#,+,-,),
,/}
画出DFA状态转换图
在这里插入图片描述

调试过程

在这里插入图片描述
没有判断
在这里插入图片描述

因为字符串中没有表示10以上的字符所以只能存之后的符号
在这里插入图片描述
最后就能得到正确答案

在这里插入图片描述

#include <stdio.h>
#include <string.h>
/**文法G[S]**/
//0 E'->E
//1 E->T
//2 E->E+T
//3 E->E-T
//4 T->F
//5 T->T*F
//6 T->T/F
//7 F->I
//8 F->(E)

//a*(b+c*(a-b))#
//a*b+c/d#


//四元式用到的全局变量
char sem[50]; //语义栈,存放id(指向标识符地址的指针)或四元式编号
int sem1=0;   //语义栈指针
char t='1';      //假设为结果集变量
char id;
char Tri[15][30];  //存放四元式
int tr=0;          //四元式集指针


//状态栈
int s1=0;
int states1[50]={0};
//符号栈
int f1=0;
char fuhao1[50]={'#'};
//输入栈
int in1=0;
char input1[50];

char flag; //定位action表或goto表中的某一个位置


//定义SLR(1)_action表
char action1[16][8]=
//数字:下一个状态集编号(10:':' 11:';' 12:'<' 13:'=' 14:'>' 15:'?') 字母:规约的产生式编号 *:结束规约
{//   +   -   *   /   (   )   i   #
    {' ',' ',' ',' ','5',' ','4',' '}, //0
    {'6','7',' ',' ',' ',' ',' ','*'}, //1
    {'a','a','8','9',' ','a',' ','a'}, //2
    {'d','d','d','d',' ','d',' ','d'}, //3
    {'g','g','g','g',' ','g',' ','g'}, //4
    {' ',' ',' ',' ','5',' ','4',' '}, //5
    {' ',' ',' ',' ','5',' ','4',' '}, //6
    {' ',' ',' ',' ','5',' ','4',' '}, //7
    {' ',' ',' ',' ','5',' ','4',' '}, //8
    {' ',' ',' ',' ','5',' ','4',' '}, //9
    {'6','7',' ',' ',' ','?',' ',' '}, //10
    {'b','b','8','9',' ','b',' ','b'}, //11
    {'c','c','8','9',' ','c',' ','c'}, //12
    {'e','e','e','e',' ','e',' ','e'}, //13
    {'f','f','f','f',' ','f',' ','f'}, //14
    {'h','h','h','h',' ','h',' ','h'}, //15
};

//定义goto表
//数字:产生式编号(10:':' 11:';' 12:'<' 13:'=' 14:'>' 15:'?')
char go[16][3]=
{ //  E   T   F
    {'1','2','3'}, //0
    {' ',' ',' '}, //1
    {' ',' ',' '}, //2
    {' ',' ',' '}, //3
    {' ',' ',' '}, //4
    {':','2','3'}, //5
    {' ',';','3'}, //6
    {' ','<','3'}, //7
    {' ',' ','='}, //8
    {' ',' ','>'}, //9
    {' ',' ',' '}, //10
    {' ',' ',' '}, //11
    {' ',' ',' '}, //12
    {' ',' ',' '}, //13
    {' ',' ',' '}, //14
    {' ',' ',' '}, //15
};

//将文法存入二维数组
char G[9][20]=
{
  {" "},
  {"ET"},
  {"EE+T"},
  {"EE-T"},
  {"TF"},
  {"TT*F"},
  {"TT/F"},
  {"Fi"},
  {"F(E)"},
};

//根据当前输入符号确定action表列号
int number_action(char c)
{
    int n;
    switch(c)
    {
        case '+':n=0;break;
        case '-':n=1;break;
        case '*':n=2;break;
        case '/':n=3;break;
        case '(':n=4;break;
        case ')':n=5;break;
        case 'i':n=6;break;
        case '#':n=7;break;
        default:n=-1;break;
    }
    return n;
}

//根据规约后的栈顶符号确定go表列号
int number_go(char c)
{
    int n;
    switch(c)
    {
        case 'E':n=0;break;
        case 'T':n=1;break;
        case 'F':n=2;break;
        default:n=-1;break;
    }
    return n;
}

//生成四元式的函数
void GenQT(char w)
{
    Tri[tr][0]=w;
    Tri[tr][1]=sem[sem1-2];
    Tri[tr][2]=sem[sem1-1];
    Tri[tr][3]=t;
    //if(tr==0) printf("\t(%c,%c,%c,%c)\n",Tri[tr][0],Tri[tr][1],Tri[tr][2],Tri[tr][3]);
    //else printf("\t(%c,%c,%c,%c)\n",Tri[tr][0],Tri[tr][1],Tri[tr][2],Tri[tr][3]);
    tr++;
    sem[sem1-2]=t;
    sem1--;
    t++;
}

//四元式语义子程序
void four(int f)
{
    switch(f)
    {
        case 0: break;              //E'->E
        case 1: break;              //E->T
        case 2: GenQT('+'); break;  //E->E+T
        case 3: GenQT('-'); break;  //E->E-T
        case 4: break;              //T->F
        case 5: GenQT('*'); break;  //T->T*F
        case 6: GenQT('/'); break;  //T->T/F
        case 7: sem[sem1++]=id; break; //F->i
        case 8: break;              //F->(E)
    }
}


//输出分析过程
void print(int step,int state[],int s,char fuhao[],int f,char input[],int in)
{
    int i=0;
    printf("%3d\t",step); //步骤号
    while(i<=s) //状态栈
    {
        if(state[i]>9) printf(" ");
        printf("%d",state[i++]);
    }
    printf("\t\t");
    i=0;
    while(i<=f) //符号栈
    {
        printf("%c",fuhao[i++]);
    }
    printf("\t\t");
    i=in;
    while(input[i]!='\0')
    {
        printf("%c",input[i++]);
    }
    printf("\t");
}

void SLR1()
{
    int m,n; //m->action、goto表行号 n->action、goto表列号
    int step=1;
    printf("\n\n\t\t\tSLR(1)分析");
    printf("\n步骤  状态栈          符号栈          剩余串         action     goto\n");
    while(1)
    {

        m=states1[s1]; /**state为整型数组**/
        //n=number_action(input1[in1]);
        //将输入中除'终结符'及'非终结符'以外的符号换位'i'
        if(input1[in1]!='+' && input1[in1]!='-' && input1[in1]!='*' &&
           input1[in1]!='/' && input1[in1]!='(' && input1[in1]!=')' &&
           input1[in1]!='i' && input1[in1]!='#' && input1[in1]!='E' &&
           input1[in1]!='T' && input1[in1]!='F')  { n=number_action('i'); }
        else n=number_action(input1[in1]);

        flag=action1[m][n];

        /**当前操作数 op(四元式**/
        if(n==6) id=input1[in1];  //6为'i'的列号,说明当前输入符号为操作数

        if(('0'<=flag && flag<='9') || flag==':' || flag==';' || flag=='<'
           || flag=='=' || flag=='>' || flag=='?') //移进
        {
            print(step,states1,s1,fuhao1,f1,input1,in1);

             //
            if('0'<=flag && flag<='9') printf("\tS%c\n",flag);
            if(flag==':') printf("\tS10\n");
            if(flag==';') printf("\tS11\n");
            if(flag=='<') printf("\tS12\n");
            if(flag=='=') printf("\tS13\n");
            if(flag=='>') printf("\tS14\n");
            if(flag=='?') printf("\tS15\n");

            states1[++s1]=flag-'0'; /**state为整型数组**/
            fuhao1[++f1]=input1[in1++];
            step++;
        }
        else if('a'<=flag && flag<='z') //规约
        {
            print(step,states1,s1,fuhao1,f1,input1,in1);
            int f=flag-'a'+1;  //产生式编号
            printf("\tr%d",f);

            //从状态栈和符号栈中弹出产生式右部
            int len=strlen(G[f])-1; //-1是因为G[][0]记录产生式左部
            f1=f1-len;
            s1=s1-len;
            fuhao1[++f1]=G[f][0];
            m=states1[s1];  //goto表的行号
            n=number_go(fuhao1[f1]); //goto表的列号
            flag=go[m][n];

            //
            if('0'<=flag && flag<='9') printf("\t%c\n",flag);
            if(flag==':') printf("\t10\n");
            if(flag==';') printf("\t11\n");
            if(flag=='<') printf("\t12\n");
            if(flag=='=') printf("\t13\n");
            if(flag=='>') printf("\t14\n");
            if(flag=='?') printf("\t15\n");

            /**四元式语义子程序**/
            four(f);

            states1[++s1]=flag-'0';
            step++;
        }
        else if(flag=='*') //规约成功,接受
        {
            print(step,states1,s1,fuhao1,f1,input1,in1);
            printf("\t接受!\n");

            return;
        }
        else    //查action表为空
        {
            print(step,states1,s1,fuhao1,f1,input1,in1);
            printf("\t出错");
            return;
        }
    }
}



int main()
{
    printf("请输入:\n");
    gets(input1);
    SLR1();
    printf("四元式序列:\n");
    for(int i=0;i<(t-'0'-1);i++)  //t是从'1'开始
    {

        if(i==0) printf("\t%d.(%c,%c,%c,%c)\n",i+1,Tri[i][0],Tri[i][1],Tri[i][2],Tri[i][3]);
        else printf("\t%d.(%c,%c,%c,%c)\n",i+1,Tri[i][0],Tri[i][1],Tri[i][2],Tri[i][3]);

    }
}
//a+b-c/d#
//A*(B+C*(A-B))#
//A*(B+C)#

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

编译原理实验日志 的相关文章

  • centos 内核升级

    首先查看centos版本 cat etc centos release 或者 rpm q centos release 查看内核版本 uname sr 查看官方内核 https www kernel org 接下来升级内核 大多数现代发行版
  • 太牛叉了!解决“卡脖子”的国产自主 IDE [狗头.jpg]

    推荐关注 综合整理 程序员的那些事 ID iProgrammer 解决 卡脖子 的自主创新 IDE 最近有一个的国产自主创新的 CEC IDE 震动了程序员圈子 在 CEC IDE 官网简介中的 安全可控 条目自称 国企品牌 自主研发 注意

随机推荐

  • k8s运维 pod、node、namespace、pv处于terminating的原因及处理方法

    1 概述 node pod ns pv由于一些原因在生产中处于terminating的状态 常规方法无法删除 一下总结了一些原因以及删除方法 2 node处于Terminating状态原因及处理方法 node节点不可达的情况下 kubect
  • MATLAB嵌套循环求解1到1000的素数和

    熬夜打卡 代码都跑过一遍的 没有任何问题啦 方法一 matlab的嵌套循环 重在理解 clc clear s 0 for i 2 1000 for j 2 32 if mod i j break end end if j gt i j s
  • 【华为OD机试】阿里巴巴找黄金宝箱(IV)(C++ Python Java)2023 B卷

    时间限制 C C 1秒 其他语言 2秒 空间限制 C C 262144K 其他语言524288K 64bit IO Format lld 题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上 无意中发现了强盗集团的藏宝地 藏宝地有编号从0 N的箱
  • 常用的BOM属性 - Kaiqisan

    终于出狱了 今天重新恢复博客的更新 大致谈谈我复习面试上面的查漏补缺的内容 首先讲讲什么是BOM BOM简单来说就是浏览器对象 只有js在浏览器环境运行时才会被赋予的对象 location对象 该对象内所有的属性都与URL有关 常常用于提取
  • 攻防世界————fileclude(内含php伪协议菜鸟讲解)

    先进去发现为一坨php代码 新手勉勉强强看得懂 接下来我们分析代码 WRONG WAY
  • Angular2-使用Augury来调试Angular2程序

    原文链接 http www jianshu com p efecaea287f2 推荐 Augury Angular专用的chrome 调试插件 如题 就在前几天的2016 12 8谷歌开发者大会上 angular2的leader来给我们演
  • idea字体主题集合

    http color themes com view index
  • 意念控制四旋翼 学习笔记

    第一部分 模块原始数据 拿到模块 在网上查了一圈 发现基本没什么有用的资料 很多都是一些相关但是没有实际价值的东西 许多论文都是再谈怎么去做 而没有实实在在的去完成这么一个过程 废话不多说 直接步入正题 昨天在网上才发现这个软件 据评论说是
  • 最近大火的「元宇宙」是什么?

    公众号后台回复 图书 了解更多号主新书内容 作者 腾讯技术工程特约撰稿人 李佳华 本文将介绍元宇宙的由来和底层技术 探讨海内外资本在这条赛道上的布局 元宇宙将会对哪些行业产生变革的影响 这些影响背后凸显了元宇宙的哪些价值 以及元宇宙逐步实现
  • openwrt reboot流程

    openwrt 系统中 当执行了 reboot 命令 系统将会发生什么事情呢 如何进行重启的呢 下面来一起看一下 reboot 应用层操作 首先 reboot 是由busybox 它是一个集成了常用Linux命令和工具的软件 提供的一个Li
  • leetcode算法面试题:串联所有单词的子串问题、单词拆分问题

    串联所有单词的子串问题 给定一个字符串 s 和一些 长度相同 的单词 words 找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置 注意子串要与 words 中的单词完全匹配 中间不能有其他字符 但不需要考虑 word
  • 数据挖掘算法基础-关联规则

    数据挖掘中 被常拿来说的啤酒尿布的例子就是一个很典型的运用关联算法来做购物来分析的例子 常被用于交易数据 关系数据的分析 发现数据集中隐藏的频繁模式 这些频繁模式可以用关联规则的形式表示 有效的关联规则对商家的商品进出货摆放都有很大的指导意
  • 直方图均衡化与直方图规定化

    一 认识图像 当我们面对图像的时候 我们面对的是抽象的矩阵 如下图 下面是0 255的灰度图像的表示 密密麻麻的 那么我们做的直方图 其实就是对这些像素值的统计 如下图所示 其中Bin表示条数 数据和范围是对图的解释 二 为什么要做直方图均
  • qt 嵌入web页面_Qt -在应用程序中嵌入Web内容之环境搭建

    一 Qt应用程序与Web结合的发展 1 从Qt5 5开始 Qt WebKit模块被废弃了 取而代之的是Qt WebEngine模块 当时可以使用该模块将应用程序与Web技术结合 2 Qt WebEngine模块提供了一个Web浏览器引擎 可
  • ChatGPT:概述Vue.js中data函数初始化和created钩子函数调用的顺序和问题解决方法

    ChatGPT 概述Vue js中data函数初始化和created钩子函数调用的顺序和问题解决方法 我将输入一段Vue代码 请你记住 created console log this queryInfo this getClueList
  • Libuv源码分析 —— 6. 事件循环【uv_run】

    通过之前的学习 咱们已经明白了在事件循环中的三个核心内容 分别是 Libuv源码分析 定时器 Libuv源码分析 idle prepare check Libuv源码分析 poll io 现在让咱们从头捋一遍事件循环到底完成了什么功能呢 u
  • scrapy里面的response.xpath(“用xpath插件找打的路径“)返回值为空?

    response xpath 用xpath插件找打的路径 返回值为空 1 可能是因为路径是有问题的 2 可能是start urls的路径是有问题的 可以从network中找找路径 复制一下
  • 使用vant2问题整理

    1 export createVNode imported as createVNode was not found in vue possible exports EffectScope computed customRef defaul
  • C++11移动语义解析

    当给函数传递对象当做函数参数时 可以使用引用类型来减少拷贝对象的代价 尤其是避免容器的拷贝等 但是当把函数内的局部对象当做返回值时 我们无法返回该局部对象的引用 导致每次返回局部对象都会进行拷贝 因为返回局部对象的引用是无意义的 当函数调用
  • 编译原理实验日志

    编译原理 生成四元式 实验原理 构造SLR 1 分析表 调试过程 实验原理 构造SLR 1 分析表 首先求得follow集 follow E follow T follow F 画出DFA状态转换图 调试过程 没有判断 因为字符串中没有表示