编译原理 [0x03][0x03] ==(4.4) 语法分析_自上而下分析_LL(1)分析法

                                                  LL(1)文法

                                           

构造不带回溯的自上而下分析的文法

扩充的巴科斯范式

预测分析程序


首先根据前面的消除回溯和左递归

 

构造不带回溯的自上而下分析的文法条件
 

1. 文法不含左递归

2. 对于文法中每一个非终结符A的各个产生式的候选首符集两两不相交。即,若

                                                          A→ a1|a2|…|an

                                                          则  FIRST(ai)∩FIRST(aj)\phi   (i  ≠ j)

3. 对文法中的每个非终结符A,若它存在某个候选首符集包含 \varepsilon,则

                                                          FIRST(ai)∩FOLLOW(A)=\phi i=1,2,...,n

                                                          如果一个文法G满足以上条件,则称该文法GLL(1)文法

 

  • 对于LL(1)文法,可以对其输入串进行有效的无回溯的自上而下分析。
  • 假设要用非终结符A进行匹配,面临的输入符号为aA的所有产生式为

A→a1 | a2 | … | an

1. aFIRST(ai),则指派a i执行匹配任务;

2. a不属于任何一个候选首符集,则:

  (1)  \varepsilon属于某个FIRST(ai )a∈FOLLOW(A), 则让Ae自动匹配。

           (2) 否则,a的出现是一种语法错误。

 

 

如何构造一个递归下降子程序呢?

eg

①首先,根据第一条产生式得到(产生啥非终结符就写在begin后面,格式就这样,别问为什么)

②其次根据第二条得到(SYM是当前指针,因为+号是终结符,所以指针向下一位移动即ADVANCE,这里因为有或运算的存在,\varepsilon情况下存在 \varepsilon 实现了没有的问题,如果没实现即指针目前指向的不是“#”或者“)”,报错,分析程序即为ELSE IF 那一段

③④同理可得

⑤其实也差不多,略,有需求再说

综上所述,这就是一个完整的Pascal语言递归下降子程序的构造

 

扩充的巴科斯范式

在元符号“→”或“::=”和“|”的基础上,扩充几个元语言符号:
 
  • 用花括号{a}表示闭包运算a*。
  • 用表示{a}0^{n}可任意重复0次至n次。
  • 用方括号[a]表示{a}0^{1 },即表示a的出现可有可无(等价于a|\varepsilon)

PS: 即替换或者新增了描述关系的符号,使状态机图容易描述

 

Eg: 

 

预测分析程序

       

预测分析程序构成

  • 总控程序:根据现行栈顶符号和当前输入符号,执行动作(即递归下降分析子程序)
  • 分析表 M[Aa]矩阵:A ∈V_{N},a∈ V_{T} 是终结符或‘#’
  • 分析栈 STACK:用于存放文法符号

预测分析过程

  • 总控程序根据当前栈顶符号X和输入符号a,执行下列三动作之一:

         1. Xa=‘#’,则宣布分析成功,停止分析。

         2. Xa ≠‘#’,则把XSTACK栈顶逐出,让a指向下一个输入符号。

         3. X是一个非终结符,则查看分析表M。         

  •    M[Xa]中存放着关于X的一个产生式,把X逐出STACK栈顶,把产生式的右部符号串按反序一一推进STACK(若右部符号为e ,则意味不推什么东西进栈
  • M[Xa]中存放着“出错标志”,则调用出错诊察程序ERROR

 

总控程序实现

分析表M[Aa]的构造算法

构造G的分析表M[Aa], 确定每个产生式A→a在表中的位置

1. 对文法G的每个产生式A→a执行第2步和第3步;

2. 对每个终结符a FIRST(a),把A→a加至M[Aa]中;

3. \varepsilonFIRST(a),则对任何bFOLLOW(A)A→a加至M[Ab]中。

4. 把所有无定义的M[Aa]标上“出错标志”。

 

 

eg:

对于文法G(E):

                         E→T{E}'

                         {E}'→+T{E}' | \varepsilon

                          T→F{T}'              

                          {T}'  →*F{T}'  | \varepsilon

                          F→(E) | i 

构造每个非终结符的FIRSTFOLLOW集合:

 根据上述步骤构造预测分析表

 对于文法G(E),当输入串为i1*i2+i3时,有以下的预测分析 



LL(1)文法与二义性

  • 如果G是左递归或二义的,那么,M至少含有一个多重定义入口。因此,消除左递归和提取左因子将有助于获得无多重定义的分析表M
  • 可以证明,一个文法G的预测分析表M不含多重定义入口,当且仅当该文法为LL(1)的。
  • LL(1)文法不是二义的。 

 

eg:

          G(S):

                           S iCtS | iCtSeS | a

                           C b

提取左因子之后,改写成:

 

          G(S):

                           S iCtSS’ | a

                           S eS | e

                           C b

 

2019-11-18

 

发布了43 篇原创文章 · 获赞 7 · 访问量 3336

猜你喜欢

转载自blog.csdn.net/Zeroooooo/article/details/103127093