关于相互递归调用

在编译原理的语法分析中,不少文法都是递归形式给出的。函数

假设有以下文法: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 这样的就知足条件了。

可见,相互递归调用有可行输出的条件是,一个函数的可行输出不是惟一的。

相关文章
相关标签/搜索