• 作业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 } 
  • 相关阅读:
    Vue 静态资源文件下载 以pdf为例
    高德地图POI搜索
    矩阵转置(二维列表行列互换)
    列表动态填加元素
    关于判断值为None的处理
    第2章 小程序项目结构配置
    Python 基础编码风格
    Visual Studio — 模块计算机类型“x64”与目标计算机类型“x86”冲突
    Visual Studio — 无法解析的外部符号的几种可能
    Visual Studio — 包含目录、附加包含目录、库目录、附加库目录、附加依赖项之详解
  • 原文地址:https://www.cnblogs.com/hs01/p/11895443.html
Copyright © 2020-2023  润新知