📜  LL(1)解析表的构建

📅  最后修改于: 2021-09-28 10:53:15             🧑  作者: Mango

先决条件——自顶向下解析器的分类、FIRST Set、FOLLOW Set
自顶向下的解析器从非终结符的 start 开始,自顶向下构建解析树。自顶向下的解析器有两种类型:

  1. 具有回溯功能的自顶向下解析器
  2. 没有回溯的自上而下的解析器

没有回溯的自顶向下解析器可以进一步分为两部分:

在本文中,我们将讨论非递归下降,也称为 LL(1) 解析器。

LL(1) 解析:
这里第 1 个L表示将按照从左到右的方式对 Input 进行扫描,第二个L表示在这种解析技术中我们将使用最左派生树。最后, 1代表前瞻的数量,这意味着当您要做出决定时,您将看到多少个符号。

构建LL(1)解析表的算法:

步骤1:首先检查语法中是否存在左递归,如果语法中有左递归,则将其删除并转到步骤2。

第 2 步:计算所有非终结符的 First() 和 Follow()。

  1.   First ():如果有一个变量,并且从那个变量开始,如果我们尝试驱动所有的字符串,那么开始的终端符号称为First。
  2. Follow():什么是推导过程中跟在变量后面的终结符。

第 3 步:对于每个产生式 A –> α。 (A 趋向于 alpha)

  1. 找到 First(α) 并对 First(α) 中的每个终端,在表中输入 A –> α。
  2. 如果 First(α) 包含 ε (epsilon) 作为终端比,找到 Follow(A) 并且对于 Follow(A) 中的每个终端,在表中输入 A –> α。
  3. 如果 First(α) 包含 ε 并且 Follow(A) 包含 $ 作为终结符,则在表中为 $ 输入 A –> α。
    为了构造解析表,我们有两个函数:

在表中,行将包含非终端,列将包含终端符号。 Grammars 的所有Null产生式将在 Follow 元素下,其余产生式将在 First set 的元素下。

现在,让我们通过一个例子来理解。

示例 1:
考虑语法:

E --> TE'
E' --> +TE' | ε                
T --> FT'
T' --> *FT' | ε
F --> id | (E)

*ε denotes epsilon

找到他们的 First 和 Follow 集合:

  First Follow
E –> TE’ { id, ( } { $, ) }
E’ –> +TE’/ε { +, ε } { $, ) }
T –> FT’ { id, ( } { +, $, ) }
T’ –> *FT’/ε { *, ε } { +, $, ) }
F –> id/(E) { id, ( } { *, +, $, ) }

现在,LL(1) 解析表是:

  id + * ( ) $
E E –> TE’     E –> TE’    
E’   E’ –> +TE’     E’ –> ε E’ –> ε
T T –> FT’     T –> FT’    
T’   T’ –> ε T’ –> *FT’   T’ –> ε T’ –> ε
F F –> id     F –> (E)    

如您所见,所有空产生式都放在该符号的 Follow 集合下,而所有剩余的产生式都位于该符号的 First 之下。

注意:对于 LL(1) 解析表,每种语法都不可行。一个单元格可能包含不止一种产品。

让我们看一个例子。

示例 2:
考虑语法

S --> A | a
A --> a 

找到他们的 First 和 Follow 集合:

  First Follow
S –> A/a { a } { $ }
A –>a { a } { $ }

解析表:

  a $
S S –> A, S –> a  
A A –> a  

在这里,我们可以看到在同一个单元格中有两个产生式。因此,这种语法对于 LL(1) Parser 是不可行的。