编译原理中中间代码生成---C语言实现
一.前言
今天有点累,就不想废话了。直接进入正题吧。(新增)第二次实验课还是这个内容,不过新增了一个功能和再处理了一下其他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语言实现相关推荐
- 编译原理中词法分析的递归下降分析法实例--能被5整除的二进制数---c语言实现
一.前言 又到了一周一度的编译原理实验课,一次实验课上完了,又是大学生必备技能-写实验报告.行了,废话不多说,我直接展现,如何实现编译原理中词法分析的递归下降分析法实例–能被5整除的二进制数的思路.作 ...
- 逆波兰式 java_Java 实现《编译原理》中间代码生成 -逆波兰式生成与计算 - 程序解析...
Java 实现<编译原理>中间代码生成 -逆波兰式生成与计算 - 程序解析 编译原理学习笔记 (一)逆波兰式是什么? 逆波兰式(Reverse Polish notation,RPN,或逆 ...
- 编译原理实验:代码生成作业(1)
编译原理实验4:中间代码生成实验包-C++文档类资源-CSDN下载编译原理实验4:中间代码生成实验包更多下载资源.学习资料请访问CSDN下载频道.https://download.csdn.net/d ...
- 编译原理算符分析器实现 -* c语言代码,C语言实现算符优先文法源代码(编译原理)...
下面教大家用C语言实现编译原理中的算符优先文法.求出FIRSTVT集和LASTVT集,并判断该文法是否是算符优先文法. 一.知识解析 1.定义 算符优先文法是一种自下而上的分析方法,其文法的特点是文法 ...
- [编译原理学习笔记2-2] 程序语言的语法描述
[编译原理学习笔记2-2] 程序语言的语法描述 文章目录 [编译原理学习笔记2-2] 程序语言的语法描述 [2.3.1] 上下文无关文法 [2.3.2] 语法分析树与二义性 [2.3.3] 形式语言鸟 ...
- 编译原理算符分析器实现 -* c语言代码,编译原理论文-词法分析器的设计与实现...
<编译原理论文-词法分析器的设计与实现>由会员分享,可在线阅读,更多相关<编译原理论文-词法分析器的设计与实现(13页珍藏版)>请在人人文库网上搜索. 1.编译原理论文题 目 ...
- 编译原理课程设计-对pl0语言进行扩充
文章目录 一. 设计目的及要求 1.1 设计目的 1.2 设计要求 1.2.1 要求一 1.2.2 要求二 1.2.3 要求三 二.程序设计 2.1 程序的组织结构 2.1.1 PL/0编译程序函数定 ...
- 编译原理拉链回填技术c语言,编译原理笔记1:概述编译相关的基本知识
本系列为个人编译原理学习笔记,谬误之处恳请高人指点,感激不尽! 内容整理自西安电子科技大学 王小兵.张南.鱼滨老师的编译原理课程. 编译器的工作步骤 在开始说任何东西之前,我们先来大致看一下编译器是怎 ...
- 《编译原理》实验报告——TINY语言的词法分析
TINY语言的词法分析 实验目的 (评价依据,描述是否准确到位) 构造tiny语言的词法分析器(扫描器),要求利用第三方的lex工具进行构造. 构造出的扫描器,能够读入教材样例中给出的tiny语言的示 ...
最新文章
- 软件工程个人作业01
- 在数据库‘master’中拒绝CREATE DATABASE权限 的问题
- 数据库崩溃后对redo log的使用
- 漫画:什么是布隆算法
- 你还认识变量吗?Java基础学习不可略过的基本语法,简而不漏,变量的定义赋值和分类,系统认识Java中的变量有哪些?
- 【Eclipse】eclipse在线安装反编译插件
- Q104:怎么用ray tracing画基于磨边楔形的“花环(Rosette)”
- 图形图像会议期刊文章查询
- Java的break和continue关键字
- win10虚拟服务器安装xp,win10 Hyper-V 安装winxp虚拟机
- python海词查单词
- JAVA招聘管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
- Premiere 视频基本调色
- c++自动抢购_软件神器—全网口罩监控抢购
- 下行法求最小割集案例_故障树中最小割集和最小径集的改进算法
- 群控进化史,黑产攻击效率提升带来的防守困境
- java微信小程序接口openid过期_Java微信小程序登录接口获取openid
- 全文搜索 full-text search
- 还在用excel做应收应付管理吗?你的痛苦我都知道
- SinaWeibo Oauth2.0授权问题
热门文章
- 突破传统生物3D打印技术局限-王秀杰/Charlie C.L. Wang/刘永进团队合作开发新型生物3D打印体系...
- 鸟类南飞,去的是哪个“南方”?
- 快速卷积与快速相关——MATLAB
- 《信息学奥赛一本通 提高篇》
- RTX5 | 线程管理02 - 创建线程(动态堆栈方式)
- STM32H743+CubeMX-计算FDCAN2上的MessageRAMOffset(使两路FDCAN正常工作)
- Qt文档阅读笔记-Threaded Fortune Server Example解析
- C++工作笔记-hiredis中关于ERR wrong number of arguments for HMSET问题的解决
- Qt creator5.7 OpenCV249之图片灰度处理(含源码下载)
- C/C++信息隐写术(一)之认识文件结构