作业11 LL(1)文法的判断,递归下降分析程序

1. 文法 G(S):

(1)S -> AB

(2)A ->Da|ε

(3)B -> cC

(4)C -> aADC |ε

(5)D -> b|ε

验证文法 G(S)是不是 LL(1)文法?

 答:

  FIRST(Da)={b,a}

  FIRST(ε)={ε}

  FIRST(aADC)={a}

  FIRST(b)={b}

  FOLLOW(A)={c,b,a,#}

  FOLLOW(C)={#,}

  FOLLOW(D)={a,#}

  SELECT(A->Da)=FIRST(Da)={b,a}

  SELECT(A->ε)=FIRST(ε)-{ε}UFOLLOW(A)=FOLLOW(A)={c,b,a,#}

  因为SELECT(A->Da) ∩ SELECT(A->ε) ≠ Ø

  所以G(S)不是 LL(1)文法。

2.(上次作业)消除左递归之后的表达式文法是否是LL(1)文法?

答:表达式文法为:

  (1)E->TE'

  (2)E'->+TE' | ε

  (3)T->FT'

  (4)T'->*FT' | ε

  (5)F->(E) | i

  FIRST(+TE')={+}

  FIRST(ε)={ε}

  FIRST(*FT')={*}

  FIRST((E))={ ( }

  FIRST(i)={i}

  FOLLOW(E')={ ),# }

  FOLLOW(T')={+,),#}

  FOLLOW(F)={*,+,),#}

  SELECT(E'->+TE')=FIRST(+TE')={+}

  SELECT(E'->ε)=FIRST(ε)-{ε}UFOLLOW(E')=FOLLOW(E')={ ),# }

  SELECT(T'->*FT')=FIRST(*FT')={*}

  SELECT(T'->ε)=FIRST(ε)-{ε}UFOLLOW(T')=FOLLOW(T')={ +,),# }

  SELECT(F->(E))=FIRST((E))={ ( }

  SELECT(F->i)=FIRST(i)={i}

  因为SELECT(E'->+TE') ∩ SELECT(E'->ε) = Ø

    SELECT(T'->*FT') ∩ SELECT(T'->ε) = Ø

    SELECT(F->(E)) ∩ SELECT(F->i) = Ø

  所以此表达式文法是LL(1)文法。

3.接2,如果是LL(1)文法,写出它的递归下降语法分析程序代码。

E()

    {T();

       E'();

     }

E'()

T()

T'()

F()

答:

  SELECT集:

  SELECT(E->TE')=FIRST(TE')={ (, i }

  SELECT(E'->+TE')=FIRST(+TE')={+}

  SELECT(E'->ε)=FIRST(ε)-{ε}UFOLLOW(E')=FOLLOW(E')={ ),# }

  SELECT(T->FT')=FIRST(FT')={ (,i }

  SELECT(T'->*FT')=FIRST(*FT')={*}

  SELECT(T'->ε)=FIRST(ε)-{ε}UFOLLOW(T')=FOLLOW(T')={ +,),# }

  SELECT(F->(E))=FIRST((E))={ ( }

  SELECT(F->i)=FIRST(i)={i}

  递归下降语法分析程序:

  void ParseE(){

    switch(lookahead){

      case '(','i':

        ParseT();

        ParseE'();

        break;

      default:

        print("syntax error ");

        exit(0);

    }

  }

  void ParseE'(){

    switch(lookahead){

      case '+':

        MatchToken('+');

        ParseT();

        ParseE'();

        break;

      case ')','#':

        break;

      default:

        print("syntax error ");

        exit(0);

    }

  }

  void ParseT(){ 

    switch(lookahead){

      case '(','i':

        ParseF();

        ParseT'();

        break;

      default:

        print("syntax error ");

        exit(0);

    }

  }

  void ParseT'(){

    switch(lookahead){

      case '*':

        MatchToken('*');

        ParseF();

        ParseT'();

        break;

      case '+',')','#':

        break;

      default:

        print("syntax error ");

        exit(0);

    }

  }

  void ParseF(){

    switch(lookahead){

      case '(':

        MatchToken('(');

        ParseE();

        MatchToken(')');

        break;

      case 'i':

        MatchToken('i');

        break;

      default:

        print("syntax error ");

        exit(0);

    }

  }

 4.加上实验一的词法分析程序,形成可运行的语法分析程序,分析任意输入的符号串是不是合法的表达式。

  1 //引入头文件 
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 //声明变量 
  6 char prog[800],dc[8]; //程序段  单词 
  7 char ch;  //单词中的字符 
  8 int syn,p,m=0; //单词符号种别码   指针p 
  9 int n,sum=0;  //整数sum 
 10 char *word[6]={"begin","if","then","while","do","end"};  //保留字 
 11 int kk=0; //判断是否有错误 
 12 //声明函数 
 13 void scaner();
 14 void E();
 15 void T();
 16 void E1();
 17 void T1();
 18 void F();
 19 void error();
 20 
 21 void scaner(){  //读取一个字符 
 22     m=0;
 23     //初始化数组dc 
 24     for(n=0;n<8;n++){
 25         dc[n]=NULL;
 26     }
 27     ch=prog[p++];
 28     //遇到空格指针加1 
 29     while(ch==' '){
 30         ch=prog[p];
 31         p++;
 32     }
 33     //标识符 
 34     if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
 35         m=0;
 36         while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
 37             dc[m++]=ch;
 38             ch=prog[p++];
 39         }
 40         p--;
 41         syn=10;
 42         //保留字 
 43         for(n=0;n<6;n++){
 44             if(strcmp(dc,word[n])==0){
 45                 syn=n+1;
 46                 break;
 47             }
 48         }
 49     }
 50     //数字 
 51     else if((ch>='0'&&ch<='9')){
 52         sum=0;
 53         while((ch>='0'&&ch<='9')){
 54             sum=sum*10+ch-'0';
 55             ch=prog[p++];
 56         }
 57         p--;
 58         syn=11;
 59     }
 60     else{
 61         switch(ch){
 62             case '<':m=0;
 63                 dc[m++]=ch;
 64                 ch=prog[p++];
 65                 if(ch=='>'){
 66                     syn=22;
 67                     dc[m++]=ch;
 68                 }
 69                 else if(ch=='='){
 70                     syn=21;
 71                     dc[m++]=ch;
 72                 }
 73                 else{
 74                     syn=20;
 75                     p--;
 76                 }
 77                 break;
 78             case '>':m=0;
 79                 dc[m++]=ch;
 80                 ch=prog[p++];
 81                 if(ch=='='){
 82                     syn=24;
 83                     dc[m++]=ch;
 84                 }
 85                 else{
 86                     syn=23;
 87                     p--;
 88                 }
 89                 break;
 90             case ':':m=0;
 91                 dc[m++]=ch;
 92                 ch=prog[p++];
 93                 if(ch=='='){
 94                     syn=18;
 95                     dc[m++]=ch;
 96                 }
 97                 else{
 98                     syn=17;
 99                     p--;
100                 }
101                 break;
102             case '*':syn=15;dc[0]=ch;break;
103             case '/':syn=16;dc[0]=ch;break;
104             case '+':syn=13;dc[0]=ch;break;
105             case '-':syn=14;dc[0]=ch;break;
106             case '=':syn=25;dc[0]=ch;break;
107             case ';':syn=26;dc[0]=ch;break;
108             case '(':syn=27;dc[0]=ch;break;
109             case ')':syn=28;dc[0]=ch;break;
110             case '#':syn=0;dc[0]=ch;break;
111             case '
':syn=-2;dc[0]=ch;break;        
112         }
113     }
114 }
115 void E(){
116     T();
117     E1();
118 }
119 void T(){
120     F();
121     T1();
122 }
123 void E1(){
124     if(syn==13){
125         scaner();
126         T();
127         E1();
128     }
129     else if(syn==0 || syn==28){
130     } 
131     else{
132         kk=1;
133         error();
134         exit(0);
135     }
136 }
137 void T1(){
138     if(syn==15){
139         scaner();
140         F();
141         T1();
142     }
143     else if(syn==0 || syn==28 || syn==13){
144     }
145     else{
146         kk=1;
147         error();
148         exit(0);
149     }
150 }
151 void F(){
152     if(syn==27){
153         scaner();
154         E();
155         if(syn==28){
156             scaner();
157         }
158         else{
159             kk=1;
160             printf("出错,缺少 ')' , 不是合法的表达式! 
");
161             exit(0);
162         }
163     }
164     else if(syn==11 || syn==10){
165         scaner();
166     }
167     else{
168         kk=1;
169         error();
170         exit(0);
171     }
172 }
173 void error(){
174     printf("
(%s,出错!),不是合法的表达式!",dc);
175 }
176 int main(void){
177     //指针从0开始 
178     p=0;
179     printf("请输入符号串:");
180     //逐个字符读入,放入字符数组prog中,直到'#'停止 
181     do{
182         ch=getchar();
183         prog[p++]=ch;    
184     }while(ch!='#');
185     //指针从0开始 
186     p=0;
187     do{
188         scaner();
189         E();
190     }while(syn!=0);
191     if(kk=0){
192         printf("符号串是合法的表达式!");
193     }
194 } 
原文地址:https://www.cnblogs.com/hs01/p/11895443.html