[譯] 自頂向下解析和自底向上解析的區別

原文算法

The difference between top-down parsing and bottom-up parsing
http://qntm.org/topcode


給定一套形式化文法和這套文法生成的字符串
parsing (解析)就是分析出字符串產生的過程遞歸

對於上下文無關文法, 生成過程以 parse tree 的形式出現
我買開始前, 先要知道 parse tree 的兩件事:
根節點, 字符衍生出來的初始的符號
葉節點, 字符串按照順序的全部字符
咱們所不知道的是二者之間的節點和分支token

好比對於字符串 acddf, 咱們已經知道的是字符串

S
   /|\

   ???

| | | | |
a c d d f

這篇文章做爲例子的文法:get

  • S → xyz | aBCclass

  • B → c | cdtop

  • C → eg | dfdi

自底向上解析

這個方案和拼圖沒有本質差異
咱們從 parse tree 的底部開始, 從單個的字符開始
隨後是有規則將字符盡本身所能拼接成更大的 token
字符串最終的結果, 一切都應該被結合到一個單個巨大的 S
並且 S 應該是咱們剩下的惟一的內容
若是不是, 那麼就須要回溯嘗試用別的辦法嘗試合併出 tokenco

在自底向上解析中,通常會維護一個 stack
也就是已經讀取的全部的字符和 token
每個步驟, 一個新的字符會被插圖到 stack 頂部
而後儘量地結合字符並概括爲更大的 token

例子

字符串是 acddf

步驟
  • ε 沒法概括

  • a 沒法概括

  • ac 能夠被概括, 以下:

  • 概括 acaB

    • aB 沒法概括

    • aBd 沒法概括

    • aBdd 沒法概括

    • aBddf 能夠被概括, 以下:

    • 概括 aBddfaBdC

      • aBdC 沒法概括

      • 字符串完. Stack 爲 aBdC, 非 S. 失敗! 須要回溯.

    • aBddf 沒法概括

  • ac 沒法概括

  • acd 能夠被概括, 以下:

  • 概括 acdaB

    • aB 沒法概括

    • aBd 沒法概括

    • aBdf 能夠被概括, 以下:

    • 概括 aBdfaBC

      • aBC 能夠被概括, 以下:

      • 概括 aBCS

        • 字符串完. Stack 爲 S. 成功!

Parse trees
|
a
| |
a c
  B
| |
a c
  B
| | |
a c d
  B
| | | |
a c d d
  B
| | | | |
a c d d f
  B   C
| | | |\
a c d d f
| |
a c
| | |
a c d
    B
|  /|
a c d
    B
|  /| |
a c d d
    B
|  /| | |
a c d d f
    B C
|  /| |\
a c d d f
    S
   /|\
  / | |
 /  B C
|  /| |\
a c d d f

例子 2

若是全部符合都失敗, 那麼字符串沒法被解析

字符串爲 acdg

步驟
  • ε 沒法概括

  • a 沒法概括

  • ac 能夠被概括, 以下:

  • 概括 acaB

    • aB 沒法概括

    • aBd 沒法概括

    • aBdg 沒法概括

    • 字符串完. Stack 爲 aBdg, 非 S. 失敗! 須要回溯.

  • ac 沒法概括

  • acd 能夠被概括, 以下:

  • 概括 acdaB

    • aB 沒法概括

    • aBg 沒法概括

    • 字符串完. Stack 爲 aBg, 非 S. 失敗! 須要回溯.

  • acd 沒法概括

  • acdg 沒法概括

  • 字符串完. Stack 爲 acdg, 非 S. 沒有可用的回溯. 失敗!

Parse trees
|
a
| |
a c
  B
| |
a c
  B
| | |
a c d
  B
| | | |
a c d g
| |
a c
| | |
a c d
    B
|  /|
a c d
    B
|  /| |
a c d g
| | |
a c d
| | | |
a c d g

自頂向下解析

這套方案中設想字符串匹配 S 並查看這個假設的內部邏輯提示
好比當字符串匹配 S 邏輯上按時或者
(1) 字符串匹配 xyz 或 (2) 字符串匹配 aBC
當知道 (1) 不對, 那麼 (2) 必須是對的, 而 (2) 內部有更深的邏輯提示
這些必須逐個檢查以驗證基本的假設

例子

字符串是 acddf

步驟
  • 斷言 1: acddf 匹配 S

    • 斷言 2: acddf 匹配 xyz:

    • 斷言 爲否. 嘗試其餘.

    • 斷言 2: acddf 匹配 aBC, 即 cddf 匹配 BC:

      • 斷言 3: cddf 匹配 cC, 即 ddf 匹配 C:

        • 斷言 4: ddf 匹配 eg:

        • 否.

        • 斷言 4: ddf 匹配 df:

        • 否.

      • 斷言 3 爲否. 嘗試其餘.

      • 斷言 3: cddf 匹配 cdC, 即 df 匹配 C:

        • 斷言 4: df 匹配 eg:

        • 否.

        • 斷言 4: df 匹配 df:

        • 斷言 4 爲真.

      • 斷言 3 爲真.

    • 斷言 2 爲真.

  • 斷言 1 爲真. 成功!

Parse trees
S
    |
    S
   /|\
  a B C
    | |
    S
   /|\
  a B C
    | |
    c
    S
   /|\
  a B C
   /| |
  c d
    S
   /|\
  a B C
   /| |\
  c d d f

例子 2

若是, 試驗了全部邏輯線索, 依然沒法驗證基本假設("字符串匹配 S")
那麼字符串沒法被解析

字符串爲 acdg

步驟
  • 斷言 1: acdg 匹配 S:

    • 斷言 2: acdg 匹配 xyz:

    • 否.

    • 斷言 2: acdg 匹配 aBC, 即 cdg 匹配 BC:

      • 斷言 3: cdg 匹配 cC, 即 dg 匹配 C:

        • 斷言 4: dg 匹配 eg:

        • 否.

        • 斷言 4: dg 匹配 df:

        • 否.

      • 否.

      • 斷言 3: cdg 匹配 cdC, 即 g 匹配 C:

        • 斷言 4: g 匹配 eg:

        • 否.

        • 斷言 4: g 匹配 df:

        • 否.

      • 否.

    • 否.

  • 斷言 1 爲否. 失敗!

Parse trees
S
    |
    S
   /|\
  a B C
    | |
    S
   /|\
  a B C
    | |
    c
    S
   /|\
  a B C
   /| |
  c d

爲何作遞歸是自頂向下解析器的一個問題

若是規則是作遞歸, 好比這樣的內容

  • S → Sb

能夠注意到算法的行爲是:

步驟

  • 斷言 1: acddf 匹配 S:

    • 斷言 2: acddf 匹配 Sb:

      • 斷言 3: acddf 匹配 Sbb:

        • 斷言 4: acddf 匹配 Sbbb:

          • ...無窮無盡

Parse trees

S
  |
  S
  |\
  S b
  |
  S
  |\
  S b
  |\
  S b
  |
  S
  |\
  S b
  |\
  S b
  |\
  S b
  |
...
相關文章
相關標籤/搜索