實驗四、語法分析實驗
一、 實驗目的
(1) 編制一個語義分析程序
(2) 語義分析程序是在語法分析程序的基礎上進行編寫的,主要任務是根據語法分析來插入中間代碼、語義規則以及生成四元式。
(3) 通過語義分析的練習,能夠進一步了解編譯原理。
(4) 通過了解語義分析程序的設計原則、語義規則的描述技術、識別機制及語義分析程序的自動構造原理。
二、 實驗內容和要求
(1) 根據語法分析程序進行改寫語義分析程序
(2) 根據語言的語義規則,插入中間代碼、語義規則以及生成四元式等
(3) 並在分析過程中進行語義檢查,四元式作為輸出或以某種形式的語法樹作報告錯誤
三、 實驗方法、步驟及結果測試
1、實驗方法、步驟:
完成靜態語義審查和處理
a) 上下文相關性審查
b) 類型匹配審查
c) 類型轉換
d) 如:s:=2*3.1416*r*(h+r);
i. 賦值語句的語義:計算賦值符號右邊表達式的值,送到賦值號左邊的變量中。
ii. 檢查賦值號左右兩邊的類型是否匹配
iii. 根據賦值語句的語義,將它翻譯成四元式中間代碼
2、原理分析:我是在語法分析程序的基礎上進行修改的,是根據語法分析來插入中間代碼、制定語義規則以及生成四元式。
void S(){ char y=str[t-1];int x; if(syn==10){ scaner(); if(syn==18){ scaner(); x=E();printf("\n(':=',%d, ,%c)\n",x,y); } } } int E(){ int x;printf("E "); x=T();return E1(x); } int E1(int x){ int y;printf("E1 "); if (syn==13) { scaner(); y=T();gen4('+',x,y);return E1(x+y); }else if (syn==14) { scaner();y=T();gen4('-',x,y);return E1(x-y); }else { if (syn==28 || syn==25)return(x); else error(); } } int T(){ int x;printf("T "); x=F();return T1(x); } int T1(int x){ int y;printf("T1 "); if (syn==15) { scaner();y=F();gen4('*',x,y);return T1(x*y); }else if (syn==16) { scaner();y=F();gen4('/',x,y);return T1(x/y); } else { if (syn==28 ||syn==25 || syn==13||syn==14)return (x); else error(); } } int F(){ int y; printf("F "); if (syn==27) { scaner();y=E(); if(syn==28) {scaner();return (y); }else error(); }else if (syn==11 || syn==10){ y=sum; scaner();return (y); } }
四、實驗總結
由於時間的關系,這次實驗我暫且做了語義分析的算術表達式與賦值語句,雖然做的不多,
但也算把算術表達式做的不錯,是有優先級的,我做的實驗是以’#’為結束語,輸出的四元式
是用(‘運算符’,操作數1,操作數2,運算結果);還有就是賦值語句是S:=E;這次實驗,
我學會了語法分析和語義分析程序,利用自上而下的遞歸下降分析法來分析語法,然后進行
賦予語義規則,再生產中間代碼,最后輸出四元式。
#include <stdio.h> //#include <string.h> #define M 100 #define N 20 char str[M], wrong[N]; char ch; int syn,t,m,n,sum,s=100; char *keyword[6]= {"begin","if","then","while","do","end"}; void scaner(); void error(); void gen4(char ch,int x,int y); void S(); int E(); int T(); int E1(int x); int F(); int T1(int x); main() { char c; t=0; printf("Please input the arithmetic expressions: "); do{ ch=getchar(); str[t++]=ch; }while (ch!='#'); t=0; do{ scaner(); switch(syn) { case 11: printf("\n(%d,%d)",syn,sum); break; case -1: printf("\n(%s,mistake)",wrong);break; default: printf("\n(%d,%s)",syn, wrong); } }while (syn!=0); getchar(); printf("\nWheter or not choice output grammer(y|n):"); scanf("%c",&c); if(c=='Y'||c=='y'){ t=0; scaner(); S(); E(); if (syn==25) printf("\nGrammer correct\n"); else printf("\nGrammer mistake\n"); } } void scaner() { for (n=0;n<20;n++) wrong[n]=NULL; m=0; sum=0; ch=str[t++]; while (ch==' ') {ch=str[t++];} if (ch>='a'&& ch<='z') {while (ch>='a'&& ch<='z'||ch>='0' && ch<='9') { wrong[m++]=ch; ch=str[t++]; } syn=10;t--; for (n=0;n<6;n++) if(strcmp(wrong,keyword[n])==0) {syn=n+1;break;} } else if(ch>='0' && ch<='9') {while (ch>='0' && ch<='9') {sum=sum*10+(ch-'0'); ch=str[t++];} syn=11;t--; } else switch(ch) { case '<': wrong[m++]=ch; ch=str[t++]; if (ch=='>') {syn=21;wrong[m++]=ch;} else if (ch=='=') {syn=22;wrong[m++]=ch;} else {syn=20;t--;} break; case '>': m=0; wrong[m++]=ch; ch=str[t++]; if (ch=='='){syn=24;wrong[m++]=ch;} else {syn=23;t--;} break; case ':': m=0; wrong[m++]=ch; ch=str[t++]; if (ch=='='){syn=18;wrong[m++]=ch;} else {syn=17;t--;} break; case '+': syn=13;wrong[0]=ch;break; case '-': syn=14;wrong[0]=ch;break; case '*': syn=15;wrong[0]=ch;break; case '/': syn=16;wrong[0]=ch;break; case '(': syn=27;wrong[0]=ch;break; case ')': syn=28;wrong[0]=ch;break; case '=': syn=25;wrong[0]=ch;break; case ';': syn=26;wrong[0]=ch;break; case '#': syn=0;wrong[0]=ch;break; default: syn=-1;wrong[0]=ch; } } void S() { char y=str[t-1];int x; if(syn==10) { scaner(); if(syn==18) { scaner(); x=E(); printf("\n(':=',%d, ,%c)\n",x,y); } } } int E() { int x; printf("E "); x=T();return E1(x); } int E1(int x) { int y; printf("E1 "); if (syn==13) { scaner(); y=T();gen4('+',x,y);return E1(x+y); }else if (syn==14) { scaner(); y=T();gen4('-',x,y);return E1(x-y); } else { if (syn==28 || syn==0)return(x); else error(); } } int T() { int x; printf("T "); x=F();return T1(x); } int T1(int x) { int y; printf("T1 "); if (syn==15) { scaner(); y=F();gen4('*',x,y);return T1(x*y); }else if (syn==16) { scaner(); y=F();gen4('/',x,y);return T1(x/y); } else { if (syn==28 ||syn==0 || syn==13||syn==14)return (x); else error(); } } int F() { int y; printf("F "); if (syn==27) { scaner(); y=E(); //gen4('+',x,y);return E1(x+y); if(syn==28) {scaner();return (y); } else error(); } else if (syn==11 || syn==10){ y=sum; scaner();return (y); } } void error() { printf("\n(%d,%s)mistake\n",syn, wrong); } void gen4(char ch,int x,int y) { int z; float f; switch(ch){ case '+':z=x+y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break; case '-':z=x-y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break; case '*':z=x*y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break; case '/':f=(float)x/y;printf("\n('%c',%d,%d,%0.1f)\n",ch,x,y,f);break; default:printf("mistakes!"); } }