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集:

FIRST(A)→FIRST(Da)→{a,b}               b是由DA得到的。

FIRST(A)→FIRST(ε)→{ε}

FIRST(B)→FIRST(cC)→{a,c}

FIRST(C)→FIRST(aADC)→{a}

FIRST(C)→FIRST(ε)→{ε}

FIRST(D)→FIRST(b)→{b}

FIRST(D)→FIRST(ε)→{ε}

FOLLOW集:

FOLLOW(S)→{#}

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

FOLLOW(B)→{#}

FOLLOW(C)→{#}

FOLLOW(D)→{a,#}

SELECT集:

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

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

SELECT(B->cC)={c}

SELECT(C->aADC)={a}

SELECT(C->ε)={#}

SELECT(D->b)={b}

 SELECT(D->ε)={a,#}

因为:

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

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

 

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

E -> E+T | T

     T -> T*F | F

     F -> (E) | i

 消除左递归:

 E -> TE' 

E' -> +TE' | ε

T -> FT'

T' ->*FT' | ε

 F -> (E) | i

FIRST集:

FIRST(E)→FIRST(T)→FIRST(F)→{ ( , i }

FIRST(E')→{+,ε}

FIRST(T)→FIRST(F)→{ ( , i }

FIRST(T')→{*,ε}

FIRST(F)→{ ( , i }

FOLLOW集:

FOLLOW(E)→{ ) , #  }                    可由 (E)得出

FOLLOW(E')→{ ) , # }               可由 (TE')得出

FOLLOW(T)→{ + , ) , # }           可由 (T+T)得出

FOLLOW(T')→{ + , ) , # }          可由 (T+FT')得出

FOLLOW(F)→{ * , + , ) , # }       可由 F+F 、F*F 、(i+i)得出

SELECT集:

SELECT(E→TE')={ ( , i }

SELECT(E'→+TE')={+}

SELECT(E'→ε)= FIRST(ε)-{ ε } U FOLLOW(E') = FOLLOW(E')= { ) , # }          FIRST(ε)不存在,所以等于FOLLOW(E')

SELECT(T→FT')={ ( , i }

SELECT(T'→*FT')={*}

SELECT(T'→ε)= FIRST(ε)-{ ε } U FOLLOW(T') = FOLLOW(T')={+,),#}        FIRST(ε)不存在,所以等于FOLLOW(T')

SELECT(F→(E))={(}

SELECT(F→i)={i}

因为:

SELECT(E'→+TE')∩SELECT(E'→ε)= ∅

SELECT(T'→*FT')∩SELECT(T'→ε)=∅

SELECT(F→(E))  SELECT(F→i)=∅

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

 

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

E()

    {T();

       E'();

     }

E'()

T()

T'()

F()

 

代码:

//在此程序中   E'  改为  E1   ,  T‘ 改为  T1

void ParseE(){

    switch(lookahead){

        case (,i:       //如果开始时的符号是 (,i   就对 ETE'进行解析

            ParseT();       //T 解析

            ParseE1();       //E' 解析

            break;

        default:         //其他形式开头的都是错误

            printf("syntax error \n");

            exit(0);

    }

}

void ParseE1(){

    switch(lookahead){       //对语法 E' -> +TE' | ε 进行解析

        case +:       //当  E' 开始时的符号是 +   就对 E+TE'进行解析

            MatchToken(+);       // 匹配当前终结符和正在扫描的单词符号

            ParseT();         // T 解析

            ParseE1();       // E'解析

            break;

        case #,):       // 当  E' 开始时的符号是 #,)   就对 E+TE'进行解析

            break;         //返回空窜

        default:         // 其他形式开头的都是错误

            printf("syntax error \n");

            exit(0);

    }

}

void ParseT(){   

    switch(lookahead){       //对语法 T -> FT' 进行解析

        case (,i:          //当  T 开始时的符号是 (,i   就对 T -> FT'进行解析

            ParseF();       // F 解析

            ParseT1();       // T’ 解析

            break;

        default:       // 其他形式开头的都是错误

            printf("syntax error \n");

            exit(0);

    }

     

}

void ParseE1(){

    switch(lookahead){           //对语法 T' ->*FT' | ε 进行解析

        case *:               //当  T‘ 开始时的符号是 *   就对 T' ->*FT'进行解析

            MatchToken(*);        // 匹配当前终结符和正在扫描的单词符号

            ParseF();          // F解析

            ParseT1();          // T' 解析

            break;

        case #,),+:              //当  T' 开始时的符号是 #,),+   就对 T' ->ε进行解析

            break;

        default:            // 其他形式开头的都是错误

            printf("syntax error \n");

            exit(0);

    }

}

void ParseF(){

    switch(lookahead){             //对语法  F -> (E) | i 进行解析

        case (:              //当  F 开始时的符号是  (   就对  F -> (E)进行解析

            MatchToken(();         // 匹配当前终结符和正在扫描的单词符号

            ParseE();         // E解析

            MatchToken());         // 匹配当前终结符和正在扫描的单词符号

            break;

        case i:            //当  F 开始时的符号是 i  就对  F ->i  进行解析

            MatchToken(i);         // 匹配当前终结符i

            break;

        default:           // 其他形式开头的都是错误

            printf("syntax error \n");

            exit(0);

    }

}

 

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

posted @ 2019-11-20 10:38  皎月星辰  阅读(280)  评论(0编辑  收藏  举报