今天做了一道題,感覺比較有意思,就是編譯原理裡面的。剛好也總結回顧一下編譯原理方面的知識
文法語言:一共分為四類,0,1,2,3型
文法G為一個四元組,G=(Vn,Vt,P,S),其中Vn,Vt分別為非空有限的非終結符和終結符號集,Vn交Vt為空白集
P為產生式集,S為文法識別符號或開始符號
1 0型文法
A ->B 其中A為 終結符解和非終結符集組成 B為終結符集和非終結符集和空集組成
A,B不做任何限制。又稱短語結構文法,它的能力相當於圖靈機
2 1型文法(上下文有關文法)
如果文法G的產生式具有以下形式
A->B 其中 A = r1Fr2 ;B=r1Xr2; r1,r2是終結符或非終結符組成的符號, A屬於非終結符,X為終結符和非終結符的並集
上面的例2.2就是一個1型文法
3 2型文法(上下文無關文法)
也就是將1型文法中的r1和r2同時去掉,就是不收內容相關的影響。
2型文法產生式的左部是單個非終結符,右部是由終結符和非終結符組成的符號串。
4 3型文法(右線性文法或正規文法)
是對2型文法添加限制,產生式右部由單一終結符或單一終結符和單一非終結符組成
今天這道題目描述主要是使用遞迴來解決
-
描述
-
一個文法G[Z]有如下五條規則:
(1)Z→(U)
(2)Z→aUb
(3)U→dZ
(4)U→bU
(5)U→e
由此文法可以產生語言:比如:ad(be)b就是此文法的語言,因為有如下推導序列:
Z→aUb→adZb→ad(U)b→ad(bU)b→ad(be)b
-
輸入
-
有n+1行,第一行為測試資料的組數n。 下面有n行,每行為一個字串。
-
輸出
-
對每一組測試資料有一行輸出,如果語言Σ是G[Z]產生的語言,則輸出"Yes."如果不是則 輸出"No".
-
範例輸入
-
2abcsdf324sdad(be)b
-
範例輸出
-
No.Yes.
由以上介紹的文法性質可以判斷為一個2型文法 ( 2型文法產生式的左部是單個非終結符,右部是由終結符和非終結符組成的符號串。)
代碼如下:
#include "stdio.h"#define MAX 1024 int index;int error;void algor(char *str);char scanner(char *str){return str[index];} void U(char *str){char c;c=scanner(str);index+=1;switch(c){case 'd':algor(str);break;case 'b':U(str);break;case 'e':break;default :error=1;break;}}void algor(char *str){char c;c=scanner(str);switch(c){case '(':index+=1;U(str);c=scanner(str);index+=1;if(c!=')'){error=1;}break;case 'a':index+=1;U(str);c=scanner(str);index+=1;if(c!='b'){error=1;} break;default:index+=1;error=1;break;} if(str[index]=='\0'){return;}}int main(){int testCase;char *str;scanf("%d",&testCase);str = (char *)malloc(sizeof(char)*MAX);while(testCase--){scanf("%s",str);index=0;error=0;algor(str);if(error==0){printf("Yes.\n");} else{printf("No.\n");}} free(str);return 0;}
其實如果不瞭解文法的含義,單純的通過題目描述使用遞迴,也是比較容易處理的~