在編譯原理的語法分析中,不少文法都是遞歸形式給出的。函數
假設有以下文法:spa
G[F]:code
F→fGblog
G→gF遞歸
判斷字符串 a 是否知足的程序以下:ci
int F(int pos) { if(a[pos] == 'f') return G(pos+1); return -1; } int G(int pos) { if(a[pos] == 'g') return F(pos+1); return -1; } int main(){ //freopen("1.in","r",stdin); while(cin>>a){ printf("%d\n", F(0)); } return 0; }
易知,這個程序輸出總爲 -1,由於不存在有限長的 F,F = fgF.字符串
反過來,要想結果輸出的不是 -1,F的結果是G(pos+1),G的結果又是F,不可能從這個圈推出。編譯
若是咱們給 F/G 增長一個可行出口,就能找到知足條件的有限長的字符串。class
例如文法改爲:編譯原理
G[F]:
F→fG | a
G→gF
int F(int pos) { if(a[pos] == 'a') return pos+1; if(a[pos] == 'f') return G(pos+1); return -1; } int G(int pos) { if(a[pos] == 'g') return F(pos+1); return -1; }
此時,像 fgfga 這樣的就知足條件了。
可見,相互遞歸調用有可行輸出的條件是,一個函數的可行輸出不是惟一的。