编译原理LL(1)递归下降子程序

【实验名称】              LL(1)递归下降子程序的实现                   

【实验目的】

 结合书本p87页分析步骤,尝试就某一个类型,构造其递归下降子程序

【实验原理】

 已知的文法为

S->FP

P->+FP

P->#

F->a

通过计算select集合,易证明是LL(1)文法

First(S)={a},First(P)={+,#},First(F)={a}

下面按照课本P88面构造递归下降程序。

【实验内容】


[if !supportLists]1. [endif]构造S()

S后面有两种可能,一种是匹配到F的first集合,一种是匹配不到,则直接报错。注意,MatchToken(a),应该发生在F()的函数种。

void S(){

    ch=str.at(temp);

    if(ch=='a'){

        cout<<"S->FP;"<<endl;

        F();

        P();

    }else{

        error();

    }

}

2.构造F()与P()的

F的比较简单,直接接受a的值就可以了,缜密一点也可以加上一个判断,不是a的话报错。

P的较为复杂一点,判断是否为‘+’后,还需要判断是不是到了‘a’,以执行F(),否则什么也不做。还要判断是否为‘#’,是的话直接接受‘#’

void F(){


    cout<<"F->a;"<<endl;

    MatchToken('a');

}


void P(){

    ch= str.at(temp);

    if(ch=='+'){

        cout<<"P->+FP;"<<endl;

        MatchToken('+');

    // cout<<"hello"<

        if (ch=='a'){

            F();

            P();

        }

        else{

    // cout<

        }

    }

    else if(ch=='#'){  

        cout<<"P->#;"<<endl;

        MatchToken('#');

    }

    else{

        error();

    }

}


3.接受函数MatchToken()


就是接受字符,然后指针先后移一位,但是传值有点问题,所以我在判断接受后,重新将指针赋值了。


void MatchToken(char s)//判断字符串匹配

{

    ch= str.at(temp);

    if(ch!=s){

        cout<<"syntax error"<<endl;

    }

    else

    {

    // cout<<"hello2"<

    temp++;

    ch= str.at(temp);

    }

}

【小结或讨论】

这次实验本来是想实现对于所有的通用类型的LL(1)文法,构造出来一个通用的递归下降伪代码。但是实验难度比较大,我断断续续数个星期也没有解决关于First集合读取后再匹配问题。后来上课中有两处地方,给出了具体事例的LL(1)文法,一处是第四章,一处是第七章带语义分析的。就退而求其次,根据了一个具体的LL(1)文法,分析出来具体的递归下降程序。

在写程序时候,逻辑方面没有太大问题,因为在书本上给出了详尽的解释,在传参的时候出现了bug,后来我就直接从字符串中按位数取值,所以代码冗余了数行。

【实验截图】

[if !supportLists]1.  [endif]a+a

[if !supportLists]2.  [endif]a+a+a

[if !supportLists]3.  [endif]a+b

代码:

/*

给定的LL(1)文法:

S->FP

P->+FP

P->#

F->a


First(S)={a},First(P)={+,#},First(F)={a}

*/

#include

using namespace std;

int temp = 0;//指针

string str;//输入串

char ch;//指针指向的字符


void F();

void P();


void error(){

    cout<<"error!";

    exit(1);

}


void MatchToken(char s)//判断字符串匹配

{

    ch= str.at(temp);

    if(ch!=s){

        cout<<"syntax error"<<endl;

    }

    else

    {

    // cout<<"hello2"<

    temp++;

    ch= str.at(temp);

    }

}


void S(){

    ch=str.at(temp);

    if(ch=='a'){

        cout<<"S->FP;"<<endl;

        F();

        P();

    }else{

        error();

    }

}


void F(){


    cout<<"F->a;"<<endl;

    MatchToken('a');

}


void P(){

    ch= str.at(temp);

    if(ch=='+'){

        cout<<"P->+FP;"<<endl;

        MatchToken('+');

    // cout<<"hello"<

        if (ch=='a'){

            F();

            P();

        }

        else{

    error();

        }

    }

    else if(ch=='#'){  

       cout<<"P->#;"<

        MatchToken('#');

    }

    else{

        error();

    }

}

int main(){

    cin>>str;

    str=str+'#';

    S();


}

你可能感兴趣的:(编译原理LL(1)递归下降子程序)