zoukankan      html  css  js  c++  java
  • 自上而下的LL(1)语法分析法

    LL(1)文法:从文法的开始符,向下推导,推出句子。

    对文法G的句子进行确定的自顶向下语法分析的充分必要条件是,G的任意两个具有相同左部的
    产生式A—>α|β 满足下列条件:
    (1)如果α、β均不能推导出ε,则 FIRST(α) ∩ FIRST(β) = ∅。
    (2)α 和 β 至多有一个能推导出 ε。
    (3)如果 β *═> ε,则 FIRST(α) ∩ FOLLOW(A) = ∅。
    将满足上述条件的文法称为LL(1)文法。
     
    一、消除左递归
    由于自上而下的分析方法不允许文法含有左递归。
    因此对于包含直接左递归和间接左递归的文法都要消除左递归。
    直接消除左递归比较容易。
    例如:
      P->Pa | b
    直接消除左递归
      P->bP'
      P'->aP' | ε
     
    二、提左因子
    如果不提左因子,当面临两个相同的前缀,不知道选择哪条,必然会产生回溯。为了消除回溯,我们需要提左因子。
    例如
     
     
    三、实验

    已知算术表达式文法 G[E]:

    E → T E'

    E' → + T E'|ε

    T → F T'

    T' → * F T'|ε

    F → ( E )|i

    判断该文法是否为 LL(1)文法,计算 FIRST 集合和 FOLLOW 集合

    SELECT(E→T E')= FIRST(T)= {(, i}

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

    SELECT(E'→ε)= FOLLOW(E')= {), #}

    SELECT(T→F T')= FIRST(F)= {(, i}

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

    SELECT(T'→ε)= FOLLOW(T')= {+, ), #}

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

    SELECT(F → i)= {i}

    具有相同左部产生式的 SELECT 集合交集为空

    SELECT(E'→+ T E')∩SELECT(E'→ε)= {+}∩{), #}=Φ

    SELECT(T' →* F T')∩SELECT(T'→ε) = {*}∩{+, ), #}=Φ

    SELECT(F → ( E ))∩SELECT(F → i) = {(}∩{i}=Φ

    所以,转换后的文法是 LL(1)文法。

        此外,我们构造LL(1)分析表

    表1-1 LL(1)分析表

    i

    +

    *

    #

    E

    E->TE’

    E->TE’

    E’

    E’->+TE’

    E’->ε

    E’->ε

    T

    T->FT’

    T->FT’

    T’

    T’->ε

    T’->*FT’

    T’->ε

    T’->ε

    F

    F->i

    F->(E)

     
    程序如下:
     1 #include<bits/stdc++.h>
     2 #define ROW 6
     3 #define COLUMN 9
     4 using namespace std;
     5 string table[ROW][COLUMN]={
     6 {"","(",")","*","+","-","/","i","#"},
     7 {"E","Te","","","","","","Te",""},
     8 {"e","","ε","","+Te","-Te","","","ε"},
     9 {"T","Ft","","","","","","Ft",""},
    10 {"t","","ε","*Ft","ε","ε","/Ft","","ε"},
    11 {"F","(E)","","","","","","i",""}};
    12 string Get_table(string x,string a){
    13     string ans="";
    14     for(int i=0;i<ROW;i++){
    15         for(int j=0;j<COLUMN;j++){
    16             if(x==table[i][0]&&a==table[0][j]){
    17                 ans=table[i][j];
    18                 return ans;
    19             }
    20         }
    21     }
    22     return ans;
    23 }
    24 bool check_LL1(string input){
    25     bool flag=true;
    26     stack < string > s;
    27     s.push("#");
    28     s.push("E");
    29     int i=0;
    30     string a=input.substr(i,1);
    31     string x;
    32     while(flag){
    33         string RS;
    34         x=s.top();
    35         if(x==a && a=="#"){
    36             break;
    37         }else if(x==a && a!="#"){
    38             s.pop();
    39             i++;
    40             a=input.substr(i,1);
    41         }else if((RS=Get_table(x,a))!=""){
    42             if(RS!="ε"){
    43                 s.pop();
    44                 for(int j=RS.length()-1;j>=0;j--){
    45                     string tmp=RS.substr(j,1);
    46                     s.push(tmp);
    47                 }
    48             }else{
    49                 s.pop();
    50             }
    51         }else{
    52             flag=false;
    53             break;
    54         }
    55     }
    56     return flag;
    57 }
    58 int main(){
    59     string input;
    60     while(cin>>input){
    61         input=input+"#";
    62         if(check_LL1(input)){
    63             cout<<"correct"<<endl;
    64         }else{
    65             cout<<"error"<<endl;
    66         }
    67     }
    68     return 0;
    69 }

    实验截图:

     
     
  • 相关阅读:
    IntelliJ破解
    IDEA的配置
    已解决No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
    逆向工程,调试Hello World !程序(更新中)
    一种离谱到极致的页面侧边栏效果探究
    前端H5如何实现分享截图
    我女儿说要看雪,但是我家在南方,于是我默默的拿起了键盘,下雪咯。
    Web基本教程~05.CSS属性
    送你一朵小红花,CSS实现一朵旋转的小红花
    Vue 项目性能优化 —实战—面试
  • 原文地址:https://www.cnblogs.com/ISGuXing/p/11114576.html
Copyright © 2011-2022 走看看