一.前言

今天有点累,就不想废话了。直接进入正题吧。(新增)第二次实验课还是这个内容,不过新增了一个功能和再处理了一下其他bug。

二.内容

一、授课内容:
(一) 授课科目:编译原理
(二) 授课内容:实验三 代码生成
(三) 授课类型:实 验
二、教学目的要求:
1.目的:通过设计、编制、调试一个具体的算术表达式求值的程序,加深对编译器计算表达式方法的理解,并掌握从中缀式到后缀式的转换方法。
2.要求:
(1)输入一个算术表达式 ,求出对应的后缀式(逆波兰式);
(2)选择数据结构——栈结构,计算表示的值;
(3)输出中缀式和求得的后缀式以及计算出的值;

(4)输出后缀式的四元式(新增)
三、教学设想:
1.教学方法设想:举例说明中缀式到后缀式的转换方法,并把主要算法进行解释,然后让学生进行变程。实验为主。
2.教具运用设想:多媒体(或远程教学软件)。
四、教学过程:
1、课题:逆波兰式求值。
2、算法:将中缀式放入char str[max]中,转换后的逆波兰式存放在char ex[max]中,根据优先级和结合关系使用栈结构完成后缀式的转换,再根据逆波兰式求值,(每个操作数后都加了一个‘#’作为特殊标记,方便后面的计算)。

三.效果图

(1)面对输入非法报错提示:

(2)正常输入

(3)小数输入

(4)输出后缀式的四元式(新增)


(5)面对括号不匹配,忽略括号,直接算结果。(括号是英文状态下的括号,否则会被认为是非法字符)(新增)

(5)用户忘记输入#结束标志,系统自动加上(新增)

四.代码

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define max 100
char ex[max];       /*存储后缀表达式*/
void trans(){        /*将算术表达式转化为后缀表达式*/char str[max];   /*存储原算术表达式*/   //str数组循环变量,指针从0开始char stack[max];       /*作为栈使用*/char ch;int sum,i,j,t,top=0;printf("*****************************************\n");printf("*输入一个求值的表达式,以#结束。*\n");printf("******************************************\n");printf("算数表达式:");i=0;                      /*获取用户输入的表达式*/scanf("%c",&str[i]);while(str[i]!='#' && i!=max){i++;//1scanf("%c",&str[i]);}
//  strcat(str,"#");//加上的   //3sum=i;//sum为输入字符长度//  printf("\n\t原来表达式:");
//  for(j=0;j<=sum;j++)//7
//      printf("%c",str[j]);t=1;//ex数组循环变量,指针从1开始i=0;//2ch=str[i];
//  i++;while(ch!='#'){switch(ch){case '(':                 /*判定为左括号*/top++;//栈顶指针从1开始stack[top]=ch;break;case ')':                 /*判定为右括号*/while(stack[top]!='('){ ex[t]=stack[top];//)低于+ - * / ,出栈top--;t++;}top--; //(遇到) (出栈break;case '+':                 /*判定为加减号*/case '-':       while(top!=0&&stack[top]!='('){  //+ - 运算符低于 ),*,/运算符,出栈ex[t]=stack[top];top--;t++;}top++;//+ - 运算符高于( ,入栈stack[top]=ch;break;case '*':                  /*判定为乘除号*/   case '/':             //*,/ 运算符遇到* /运算符,出栈while(stack[top]=='*'||stack[top]=='/'){ex[t]=stack[top];top--;t++;}//* / 运算符高于( ) + - ,入栈top++;stack[top]=ch;//stack[top]=ch;//7break;case ' ':break; //遇到空格跳过default:if(ch>='0'&&ch<='9'||ch=='.'){/*判定为数字*/
//              flag=0;while(ch>='0'&&ch<='9'){    ex[t]=ch;t++;//为ex数组下一个做准备 i++;ch=str[i];//               i++;//5//i++;}if(ch=='.'){//识别小数 ex[t]=ch;t++;//为ex数组下一个做准备 i++;ch=str[i];while(ch >='0'&&ch<='9'){ex[t]=ch;t++;//为ex数组下一个做准备 i++;ch=str[i];}}i--;ex[t]='#';//每个操作数后都加了一个'#'作为特殊标记,方便后面的计算t++;}else if(ch!='('||ch!=')'||ch!='+'||ch!='-'||ch!='*'||ch!='/') {printf("输入非法字符!!\n");//新增的    应对非法字符 exit(0); }}i++;ch=str[i];//i++;//6}while(top!=0){//运算栈中有东西ex[t]=stack[top];t++;top--;}ex[t]='#';printf("\n\t原来表达式:");for(j=0;j<sum;j++)//7printf("%c",str[j]);printf("\n\t后缀表达式:",ex);for(j=1;j<t;j++)printf("%c",ex[j]);
}
void compvalue(){                       /*计算后缀表达式的值*/double stack[max],d;                    /*作为栈使用*/char ch;int t=1,top=0;              /*t为ex下标,top为stack下标*/double _num;//小数部分int len;//小数个数 double num; ch=ex[t];t++;while(ch!='#'){switch(ch){case '+':stack[top-1]=stack[top-1]+stack[top];top--;break;case '-':stack[top-1]=stack[top-1]-stack[top];top--;break;case '*':stack[top-1]=stack[top-1]*stack[top];top--;break;case '/':if(stack[top]!=0)stack[top-1]=stack[top-1]/stack[top];else{  printf("\n\t除零错误!\n");exit(0);                   /*异常退出*/}top--;break;default:   //新增 应对小数点 d=0;_num=0;len=0; num=0;while(ch>='0'&&ch<='9'){//整数部分 d=10*d+ch-'0';   /*将数字字符转化为对应的数值*/    ch=ex[t];t++;}if(ch=='.'){//小数部分
//                  t++;ch=ex[t];t++;while(ch >='0'&&ch<='9'){_num=_num*10+ch-'0';        //小数部分 len++;ch=ex[t];t++;}}num=d+_num/(pow(10,len));top++;stack[top]=num;}ch=ex[t];t++;}printf("\n\t计算结果:%g\n",stack[top]);
}
main(){ trans();compvalue();return 0;
}

新增的功能的完整代码:(新增)

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define max 100
typedef struct {char operate_sign;//算符double operator_1;//操作数1double operator_2;//操作数2double result;//结果
} S;//四元元式类型
S siyuan[max];//四元式数组,存放四元式   //四元数组下标从0开始
int siyuan_flag=0;//记录四元式数
char ex[max];       /*存储后缀表达式*/
void trans(){        /*将算术表达式转化为后缀表达式*/char str[max];   /*存储原算术表达式*/   //str数组循环变量,指针从0开始char stack[max];       /*作为栈使用*/char ch;//int flag_1=0;//左括号标志位//int flag_2=0;//右括号标志位int sum,i,j,t,top=0;printf("*****************************************\n");printf("*输入一个求值的表达式,以#结束。*\n");printf("******************************************\n");printf("算数表达式:");i=0;                      /*获取用户输入的表达式*///scanf("%c",&str[i]);//while(str[i]!='#' && i!=max){//  i++;//1// scanf("%c",&str[i]);//}
//  strcat(str,"#");//加上的   //3gets(str);//获取用户输入的表达式           //新增功能   用户忘记输入#结束标志,系统自动加上sum=strlen(str);//sum为输入字符长度strcat(str,"#");//如果用户忘记输入#结束标志,系统自动加上//    printf("\n\t原来表达式:");
//  for(j=0;j<=sum;j++)//7
//      printf("%c",str[j]);t=1;//ex数组循环变量,指针从1开始i=0;//2ch=str[i];
//  i++;while(ch!='#'){switch(ch){case '(':                 /*判定为左括号*/top++;//栈顶指针从1开始stack[top]=ch;
//              flag_1=1;break;case ')':                 /*判定为右括号*///    if(flag_1){while(stack[top]!='('){ ex[t]=stack[top];//)低于+ - * / ,出栈top--;t++;}// }// else{//     printf("missing (\n");//  }top--; //(遇到) (出栈break;case '+':                 /*判定为加减号*/case '-':       while(top!=0&&stack[top]!='('){  //+ - 运算符低于 ),*,/运算符,出栈ex[t]=stack[top];top--;t++;}top++;//+ - 运算符高于( ,入栈stack[top]=ch;break;case '*':                  /*判定为乘除号*/   case '/':             //*,/ 运算符遇到* /运算符,出栈while(stack[top]=='*'||stack[top]=='/'){ex[t]=stack[top];top--;t++;}//* / 运算符高于( ) + - ,入栈top++;stack[top]=ch;//stack[top]=ch;//7break;case ' ':break; //遇到空格跳过default:if(ch>='0'&&ch<='9'||ch=='.'){/*判定为数字*/
//              flag=0;while(ch>='0'&&ch<='9'){    ex[t]=ch;t++;//为ex数组下一个做准备 i++;ch=str[i];//               i++;//5//i++;}if(ch=='.'){//识别小数 ex[t]=ch;t++;//为ex数组下一个做准备 i++;ch=str[i];while(ch >='0'&&ch<='9'){ex[t]=ch;t++;//为ex数组下一个做准备 i++;ch=str[i];}}i--;ex[t]='#';//每个操作数后都加了一个'#'作为特殊标记,方便后面的计算t++;}else if(ch!='('||ch!=')'||ch!='+'||ch!='-'||ch!='*'||ch!='/') {printf("输入非法字符!!\n");//新增的    应对非法字符 exit(0); }}i++;ch=str[i];//i++;//6}while(top!=0){//运算栈中有东西ex[t]=stack[top];t++;top--;}ex[t]='#';printf("\n\t原来表达式:");for(j=0;j<sum;j++)//7printf("%c",str[j]);printf("\n\t后缀表达式:",ex);for(j=1;j<t;j++)printf("%c",ex[j]);
}void compvalue(){                       /*计算后缀表达式的值*/int i;//循环变量double stack[max],d;                    /*作为栈使用*/char ch;int t=1,top=0;              /*t为ex下标,top为stack下标*/double _num;//小数部分int len;//小数个数 double num; ch=ex[t];t++;while(ch!='#'){switch(ch){case '+':siyuan[siyuan_flag].operate_sign ='+';//开始记录四元式siyuan[siyuan_flag].operator_1=stack[top];siyuan[siyuan_flag].operator_2=stack[top-1];stack[top-1]=stack[top-1]+stack[top];siyuan[siyuan_flag].result=stack[top-1];siyuan_flag++;//为记录下一个四元式做准备top--;break;case '-':siyuan[siyuan_flag].operate_sign ='-';//开始记录四元式siyuan[siyuan_flag].operator_1=stack[top];siyuan[siyuan_flag].operator_2=stack[top-1];stack[top-1]=stack[top-1]-stack[top];siyuan[siyuan_flag].result=stack[top-1];siyuan_flag++;//为记录下一个四元式做准备top--;break;case '*':siyuan[siyuan_flag].operate_sign ='*';//开始记录四元式siyuan[siyuan_flag].operator_1=stack[top];siyuan[siyuan_flag].operator_2=stack[top-1];stack[top-1]=stack[top-1]*stack[top];siyuan[siyuan_flag].result=stack[top-1];siyuan_flag++;//为记录下一个四元式做准备top--;break;case '/':if(stack[top]!=0){siyuan[siyuan_flag].operate_sign ='/';//开始记录四元式siyuan[siyuan_flag].operator_1=stack[top];siyuan[siyuan_flag].operator_2=stack[top-1];stack[top-1]=stack[top-1]/stack[top];siyuan[siyuan_flag].result=stack[top-1];siyuan_flag++;//为记录下一个四元式做准备}else{  printf("\n\t除零错误!\n");exit(0);                   /*异常退出*/}top--;break;default:   //新增 应对小数点 d=0;_num=0;len=0; num=0;while(ch>='0'&&ch<='9'){//整数部分 d=10*d+ch-'0';   /*将数字字符转化为对应的数值*/    ch=ex[t];t++;}if(ch=='.'){//小数部分
//                  t++;ch=ex[t];t++;while(ch >='0'&&ch<='9'){_num=_num*10+ch-'0';        //小数部分 len++;ch=ex[t];t++;}}num=d+_num/(pow(10,len));top++;     //栈顶指针从1开始stack[top]=num;}ch=ex[t];t++;}printf("\n\t计算结果:%g\n",siyuan[siyuan_flag-1].result);printf("\n\t四元式:\n");for(i=0;i<siyuan_flag;i++){printf("\t(%c,%g,%g,%g)\n",siyuan[i].operate_sign,siyuan[i].operator_2,siyuan[i].operator_1,siyuan[i].result);}
}
main(){ trans();compvalue();return 0;
}

编译原理中中间代码生成---C语言实现相关推荐

  1. 编译原理中词法分析的递归下降分析法实例--能被5整除的二进制数---c语言实现

    一.前言 又到了一周一度的编译原理实验课,一次实验课上完了,又是大学生必备技能-写实验报告.行了,废话不多说,我直接展现,如何实现编译原理中词法分析的递归下降分析法实例–能被5整除的二进制数的思路.作 ...

  2. 逆波兰式 java_Java 实现《编译原理》中间代码生成 -逆波兰式生成与计算 - 程序解析...

    Java 实现<编译原理>中间代码生成 -逆波兰式生成与计算 - 程序解析 编译原理学习笔记 (一)逆波兰式是什么? 逆波兰式(Reverse Polish notation,RPN,或逆 ...

  3. 编译原理实验:代码生成作业(1)

    编译原理实验4:中间代码生成实验包-C++文档类资源-CSDN下载编译原理实验4:中间代码生成实验包更多下载资源.学习资料请访问CSDN下载频道.https://download.csdn.net/d ...

  4. 编译原理算符分析器实现 -* c语言代码,C语言实现算符优先文法源代码(编译原理)...

    下面教大家用C语言实现编译原理中的算符优先文法.求出FIRSTVT集和LASTVT集,并判断该文法是否是算符优先文法. 一.知识解析 1.定义 算符优先文法是一种自下而上的分析方法,其文法的特点是文法 ...

  5. [编译原理学习笔记2-2] 程序语言的语法描述

    [编译原理学习笔记2-2] 程序语言的语法描述 文章目录 [编译原理学习笔记2-2] 程序语言的语法描述 [2.3.1] 上下文无关文法 [2.3.2] 语法分析树与二义性 [2.3.3] 形式语言鸟 ...

  6. 编译原理算符分析器实现 -* c语言代码,编译原理论文-词法分析器的设计与实现...

    <编译原理论文-词法分析器的设计与实现>由会员分享,可在线阅读,更多相关<编译原理论文-词法分析器的设计与实现(13页珍藏版)>请在人人文库网上搜索. 1.编译原理论文题 目 ...

  7. 编译原理课程设计-对pl0语言进行扩充

    文章目录 一. 设计目的及要求 1.1 设计目的 1.2 设计要求 1.2.1 要求一 1.2.2 要求二 1.2.3 要求三 二.程序设计 2.1 程序的组织结构 2.1.1 PL/0编译程序函数定 ...

  8. 编译原理拉链回填技术c语言,编译原理笔记1:概述编译相关的基本知识

    本系列为个人编译原理学习笔记,谬误之处恳请高人指点,感激不尽! 内容整理自西安电子科技大学 王小兵.张南.鱼滨老师的编译原理课程. 编译器的工作步骤 在开始说任何东西之前,我们先来大致看一下编译器是怎 ...

  9. 《编译原理》实验报告——TINY语言的词法分析

    TINY语言的词法分析 实验目的 (评价依据,描述是否准确到位) 构造tiny语言的词法分析器(扫描器),要求利用第三方的lex工具进行构造. 构造出的扫描器,能够读入教材样例中给出的tiny语言的示 ...

最新文章

  1. 软件工程个人作业01
  2. 在数据库‘master’中拒绝CREATE DATABASE权限 的问题
  3. 数据库崩溃后对redo log的使用
  4. 漫画:什么是布隆算法
  5. 你还认识变量吗?Java基础学习不可略过的基本语法,简而不漏,变量的定义赋值和分类,系统认识Java中的变量有哪些?
  6. 【Eclipse】eclipse在线安装反编译插件
  7. Q104:怎么用ray tracing画基于磨边楔形的“花环(Rosette)”
  8. 图形图像会议期刊文章查询
  9. Java的break和continue关键字
  10. win10虚拟服务器安装xp,win10 Hyper-V 安装winxp虚拟机
  11. python海词查单词
  12. JAVA招聘管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
  13. Premiere 视频基本调色
  14. c++自动抢购_软件神器—全网口罩监控抢购
  15. 下行法求最小割集案例_故障树中最小割集和最小径集的改进算法
  16. 群控进化史,黑产攻击效率提升带来的防守困境
  17. java微信小程序接口openid过期_Java微信小程序登录接口获取openid
  18. 全文搜索 full-text search
  19. 还在用excel做应收应付管理吗?你的痛苦我都知道
  20. SinaWeibo Oauth2.0授权问题

热门文章

  1. 突破传统生物3D打印技术局限-王秀杰/Charlie C.L. Wang/刘永进团队合作开发新型生物3D打印体系...
  2. 鸟类南飞,去的是哪个“南方”?
  3. 快速卷积与快速相关——MATLAB
  4. 《信息学奥赛一本通 提高篇》
  5. RTX5 | 线程管理02 - 创建线程(动态堆栈方式)
  6. STM32H743+CubeMX-计算FDCAN2上的MessageRAMOffset(使两路FDCAN正常工作)
  7. Qt文档阅读笔记-Threaded Fortune Server Example解析
  8. C++工作笔记-hiredis中关于ERR wrong number of arguments for HMSET问题的解决
  9. Qt creator5.7 OpenCV249之图片灰度处理(含源码下载)
  10. C/C++信息隐写术(一)之认识文件结构