實驗三:遞歸下降語法分析實驗
一、 實驗目的
編制一個遞歸下降分析程序。
二、 實驗內容和要求
輸入:算術表達式;
輸出:判斷結果(輸入正確/錯誤)。
三、實驗方法、步驟及結果測試
1.源程序名:遞歸下降語法分析.c
可執行程序名:遞歸下降語法分析.exe
2. 原理分析及流程圖
采用遞歸子程序方法進行語法分析,對文法中的每個非終結符號按其產生式結構產生相應的語法分析子程序,完成相應的識別任務。其中終結符產生匹配命令,非終結符則產生調用命令。
流程圖:
3. 主要程序段及其解釋:
#include<stdio.h> #include<string.h> char prog[100],token[8],ch; char *rwtab[6]={"begin","if","then","while","do","end"}; int syn,p,m,n,sum; void E(); //E->TE1; void E1(); //E1->+TE1|-TE1|ε void T(); //T->FT1 void T1(); //T1->*FT1 |/FT1|ε void F(); //F->(E) | i error(); void scaner(); int main() { p=0; printf("\nplease input a string (end with '#'): \n"); do { scanf("%c",&ch); prog[p++]=ch; }while(ch!='#'); p=0; scaner(); E(); } void E() { T(); E1(); } void E1() { if((syn==13)||(syn==14)) { scaner(); T(); E1(); } else { if(syn!=28 && syn!=0) error(); } } void T() { F(); T1(); } void T1() { if((syn==15)||(syn==16)) { scaner(); F(); T1(); } else { if(syn!=28 && syn!=0 && syn!=13) error(); } } void F() { if(syn==27) { scaner(); E(); if(syn==28) { scaner(); E(); if(syn==0) printf("\nTrue!\n"); } else error(); } else if(syn==11||syn==10) scaner(); } error() { printf("\n Syn Error!\n"); } void scaner() { sum=0; for(m=0;m<8;m++) token[m++]=NULL; m=0; ch=prog[p++]; while(ch==' ') ch=prog[p++]; if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) { while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) { token[m++]=ch; ch=prog[p++]; } p--; syn=10; token[m++]='\0'; for(n=0;n<6;n++) if(strcmp(token,rwtab[n])==0) { syn=n+1; break; } } else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0'; ch=prog[p++]; } p--; syn=11; } else switch(ch) { case '<': m=0; ch=prog[p++]; if(ch=='>') { syn=21; } else if(ch=='=') { syn=22; } else { syn=20; p--; } break; case '>': m=0; ch=prog[p++]; if(ch=='=') { syn=24; } else { syn=23; p--; } break; case ':': m=0; ch=prog[p++]; if(ch=='=') { syn=18; } else { syn=17; p--; } break; case '+': syn=13; break; case '-': syn=14; break; case '*': syn=15; break; case '/': syn=16; break; case '(': syn=27; break; case ')': syn=28; break; case '=': syn=25; break; case ';': syn=26; break; case '#': syn=0; break; default: syn=-1; break; } }
4. 運行結果及分析