日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 编译原理中中间代码生成---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语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。