📜  LL(1)解析算法

📅  最后修改于: 2021-06-28 07:36:53             🧑  作者: Mango

前提条件— LL(1)解析表的构造。
LL(1)解析是编译器设计的语法分析阶段中的自上而下的解析方法。 LL(1)解析所需的组件是输入字符串,堆栈,给定语法的解析表和解析器。在这里,我们讨论一个解析器,该解析器确定是否可以从给定的语法(或解析表)生成给定的字符串。
让给定的语法是G =(V,T,S,P)
其中V变量符号集,T端子符号集,S-起始符号,P-生产集。

LL(1)解析器算法:
输入-1 . stack = S //堆栈最初仅包含S。
2.输入字符串= w $
其中S是语法的开始符号,w是给定的字符串,$是字符串。
3. PT是矩阵或2D数组形式的给定语法的解析表。

输出-确定给定的字符串可以由给定的语法(解析表)生成,否则,将产生错误。

脚步:

1. while(stack is not empty) {

       // initially it is S
2.     A = top symbol of stack;  

       //initially it is first symbol in string, it can be $ also
3.     r = next input symbol of given string; 
4.     if (A∈T or A==$) {
5.         if(A==r){
6.             pop A from stack;
7.             remove r from input;
8.         }
9.         else
10.             ERROR();
11.     }
12.     else if (A∈V) {
13.         if(PT[A,r]= A⇢B1B2....Bk) {
14.             pop A from stack;
             
                // B1 on top of stack at final of this step
15.             push Bk,Bk-1......B1 on stack  
16.         }
17.         else if (PT[A,r] = error())
18.             error();
19.     }
20. } 
// if parser terminate without error() 
// then given string can generated by given parsing table.

时间复杂度
众所周知,一种语言的语法大小是有限的。例如,有限数量的变量,终端和生产。如果语法是有限的,则其LL(1)解析表的大小也是O(V * T)。让

  • p是所有产品的RHS中字符串最大长度,并且
  • l是给定字符串的长度,并且

lp大很多。 if算法第4行的块始终运行O(1)时间。否则,如果算法中第12行的块采用O(| P | * p)作为单个下一个输入符号的上限。而且while循环可以运行l次以上,但是我们考虑了O(| P | * p)中单个下一个输入符号的重复while循环。因此,总时间复杂度为

T(l) = O(l)*O(|P|*p)
              = O(l*|P|*p)
              = O(l)           { as l >>>|P|*p }

该算法的时间复杂度是输入字符串长度的顺序。

与上下文无关语言(CFL)的比较:
LL(1)语法中的语言是CFL的适当子集。使用CYK算法,我们可以找到给定上下文无关文法(CFG)的字符串成员。 CYK花费O(l 3 )时间进行CFG成员资格测试。但是对于LL(1)语法,我们可以使用上述算法在O(l)时间进行线性隶属度测试。如果我们知道给定的CFG是LL(1)语法,则使用LL(1)解析器进行解析,而不是使用CYK算法。

例子 –
令文法G =(V,T,S’,P )为

S' → S$
S → xYzS | a
Y → xYz | y

语法分析表( PT )

  a x y z $
S’ S’ → S$ S’ → S$ error error error
S S → a S → xYzS error error error
Y error Y → xYz Y → y error error
Let string1 = xxyzza,

我们必须在此字符串加上$
我们将使用上面的解析算法,为过程图:

对于string1,我们得到了一个空堆栈,而while循环或算法终止了,没有错误。因此, string1属于给定语法G的语言。

Let string2 = xxyzzz,

与上面相同,我们将使用算法来解析string2,这是示意图

对于string2 ,如上图所示,在最后阶段,当堆栈的顶部为S且字符串的下一个输入符号为z时,但PT [S,z] = error 。该算法因错误而终止。因此, string2不是语法G的语言。