LL(1)分析演算法

-风间琉璃-發表於2024-11-16

LL(1) 分析演算法

  • 從左(L)向右讀入程式,最左(L)推導,採用一個(1)前看符號.
    • 分析高效(線性時間)
    • 錯誤定位和診斷資訊準確
    • 有很多開源或商業的生成工具
      • ANTLR
  • 演算法基本思想
    • 表驅動的分析演算法
graph LR x1["詞法分析器"]--"記號\n\n"-->x2["語法分析器"]---->x3["樹"] x2---->x4["分析棧"] x2---->x5["分析表"] x6["語法分析器"]---->x5

一般條件下 LL(1) 分析表構造

  • 一般情況下需要知道某個非終結符是否可以推出空串

  • NULLABLE

  • 並且一般需要知道在某個非終結符後面跟著什麼符號

    • 跟隨集FOLLOW

NULLABLE集合

歸納定義:

非終結符X屬於集合 NULLABLE ,當且僅當:

  • 基本情況:
    • \(X \rightarrow \epsilon\)
  • 歸納情況
    • \(X\rightarrow Y_1 \cdots Y_n\)
      • \(Y_1 \cdots Y_n\) 是n個非終結符,且都屬於NULLABLE 集

FIRST 集合的完整計算公式

  • 基於歸納的計算規則:

    • 基本情況:

      • \(X\rightarrow a\)

        • \(FIRST(X) \cup = \{a\}\)
      • 歸納情況:

      • \(X \rightarrow Y_1 Y_2\cdots Y_n(Y_i \subset NULLABLE)\)

        • \(FIRST(X) \cup = FIRST(Y_i) (i=1,2,3,4,5....,n)\)

不動點演算法計算FOLLOW集合:

\(while(some set is changing):\)

\(foreach(production p: N->\beta_1 \cdots \beta_n )\)

\(foreach(\beta_i from \beta_1 to \beta_n)\)

\(if(\beta_i == a...)\)

\(FIRST(N) \cup = \{a\}\)

\(break\)

\(if(\beta_i == M)\)

\(FIRST(N)\ \ \cup = FIRST(M)\)

\(break\)


First集定義:

\(First\)集合是對產生式右部的字串而言的,求取的是非終結符\(V_T\)(或終結符、空字元、文法符號串)的開始符號集合,集合中包含的是由左部非終結符\(V_T\)推導得到的終結符\(V_N\)或空字元ε。以α表示一個文法的字串,FIRST(α) 表示由α推匯出的串的首個終結符或空字元組成的集合。

​ 本質就是一條關係能夠出現的能確定的字首

Follow集定義:

​ Follow集合是對某個非終結符而言的,求取的是非終結符\(V_T\)的後繼符號集合,集合中包含的是由非終結符VT後面緊跟的終結符\(V_N\)和結束符,不能出現空字元ε 。以X表示一個非終結符,FOLLOW(X) 表示當X透過規約出現時,接下來的輸入可能是哪些終結符。

​ 本質就是一條關係可能產生的後隨符號集

First_s集合的計算:

​ 對於每一條產生式規則的而言,即產生式能夠產生的所有 First 的集合

​ 指一組關係中能夠產生的所有的字首的集合,右部,從左往右的NULLABLE產生式的First集的並集,直到遇到第一個非NULLABLE產生式或最後一個產生式,再並上該產生式的First集,就是整個關係的First_s集.

處理LL(1)文法中的衝突:
  • 消除左遞迴,存在左遞迴的文法會引起 \(LL(1)\) 衝突

LR(0)分析演算法

  • 自底向上分析的基本思想:
    • \(\epsilon\)

相關文章