原文算法
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
能夠被概括, 以下:
概括 ac
爲 aB
aB
沒法概括
aBd
沒法概括
aBdd
沒法概括
aBddf
能夠被概括, 以下:
概括 aBddf
爲 aBdC
aBdC
沒法概括
字符串完. Stack 爲 aBdC
, 非 S
. 失敗! 須要回溯.
aBddf
沒法概括
ac
沒法概括
acd
能夠被概括, 以下:
概括 acd
爲 aB
aB
沒法概括
aBd
沒法概括
aBdf
能夠被概括, 以下:
概括 aBdf
爲 aBC
aBC
能夠被概括, 以下:
概括 aBC
爲 S
字符串完. Stack 爲 S
. 成功!
| 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
若是全部符合都失敗, 那麼字符串沒法被解析
字符串爲 acdg
ε
沒法概括
a
沒法概括
ac
能夠被概括, 以下:
概括 ac
爲 aB
aB
沒法概括
aBd
沒法概括
aBdg
沒法概括
字符串完. Stack 爲 aBdg
, 非 S
. 失敗! 須要回溯.
ac
沒法概括
acd
能夠被概括, 以下:
概括 acd
爲 aB
aB
沒法概括
aBg
沒法概括
字符串完. Stack 爲 aBg
, 非 S
. 失敗! 須要回溯.
acd
沒法概括
acdg
沒法概括
字符串完. Stack 爲 acdg
, 非 S
. 沒有可用的回溯. 失敗!
| 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 爲真. 成功!
S | S /|\ a B C | | S /|\ a B C | | c S /|\ a B C /| | c d S /|\ a B C /| |\ c d d f
若是, 試驗了全部邏輯線索, 依然沒法驗證基本假設("字符串匹配 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 爲否. 失敗!
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
:
...無窮無盡
S | S |\ S b | S |\ S b |\ S b | S |\ S b |\ S b |\ S b | ...