• 编译原理 十一


    1. 文法 G(S):

    (1)S -> AB

    (2)A ->Da|ε

    (3)B -> cC

    (4)C -> aADC |ε

    (5)D -> b|ε

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

    解:

    SELECT(A->Da)=FIRST(Da)={b,a}
    SELECT(A->ε)=(FIRST(A)-ε) ∪ FOLLOW(A)={c,b,a,#}
    SELECT(A->Da) ∩ SELECT(A->ε) ={b,a} ≠ ∅
    所以该文法不是LL(1)文法

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

    解:

    SELECT(E->TE')=FIRST(TE')={(,i,*}
    SELECT(E'->ε)=(FIRST(E')-ε) ∪ FOLLOW(E')={#,)}
    SELECT(E->TE') ∩ SELECT(E'->ε) =∅
    SELECT(T'->*FT')=FIRST(*FT')={*}
    SELECT(T'->ε)=(FIRST(T')-ε) ∪ FOLLOW(T')={#,),+}
    SELECT(T'->*FT') ∩ SELECT(T'->ε) =∅
    SELECT(F->(E))=FIRST((E))={(}
    SELECT(F->i)=FIRST(i)={i}
    SELECT(F->(E)) ∩ SELECT(F->i) =∅
    所以该文法是LL(1)文法

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

    E()

        {T();

           E'();

         }

    E'()

    T()

    T'()

    F()

    解:

    Select(E->TE') =First(TE’)=First(T)={ ( , i }
    
    Select(E'->+TE') =First(+TE’)= { + }
    
    Select(E'->ε) = (First(ε) -{ε}) U Follow(E') = { ) , # }
    
    Select(T->FT') = First(FT’)=First(F)={ ( , i }
    
    Select(T'->*FT') = First(*FT')={ * }
    
    Select(T'->ε) = First(ε) -{ε} U Follow(T') = { + , ) , # }
    
    Select( F->(E)) = First((E))={ ( }
    
    Select( F->i )=First(i)= { i }

    伪代码:

    void ParseE()
    {
        switch(lookahead)
        {
            case (,i:
                ParseT();
                Parse_E();
                break;
            default:
                print("syntax error 
    ");
                exit(0);    
        }
    }
    void Parse_E()
    {
        switch(lookahead)
        {
            case +:
                MatchToken(+);
                ParseT();
                Parse_E();
                break;
            case ),#:
                break;
            default:
                print("syntax error 
    ");
                exit(0);    
        }
    }
    
    void ParseT()
    {
        switch(lookahead)
        {
            case (,i:
                
                ParseF();
                Parse_t();
                break;
            default:
                print("syntax error 
    ");
                exit(0);    
        }
    }
    void Parse_T()
    {
        switch(lookahead)
        {
            case *:
                MatchToken(*);
                ParseF();
                Parse_T();
                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);    
        }
    }
  • 相关阅读:
    shell面试题整理
    用循环链表实现Josephus问题
    in与exists的区别
    单链表的建立/测长/打印/删除/排序/逆序/寻找中间值
    float在内存中的存放
    crontab定时任务详解
    螺旋队列问题之二
    螺旋队列问题之一
    android网络编程--从网络下载图片,并保存到内存卡
    android Shader类简介_渲染图像示例
  • 原文地址:https://www.cnblogs.com/huangwenshuo/p/11895657.html
Copyright © 2020-2023  润新知