天天看點

編譯原理【3】文法分析概述

推導需要完成的兩個選擇:選擇替換目前句型的哪個非終結符,以及用哪個候選式去替換。

編譯原理【3】文法分析概述

最左推導與最右規約

(由于自頂向下的分析器自左向右掃描串,是以采用最左推導方式)

最左推導:替換每個句型最左端的非終結符

編譯原理【3】文法分析概述

最右推導與最左規約(規範推導與規範規約)

正好與上面描述的相反。

編譯原理【3】文法分析概述

最左推導與最右推導的唯一性:

由于最左推導和最右推導總是選擇一端的非終結符進行替換,是以最左推導和最右推導的結果都是唯一的。

重點!!

一個最左推導的例子詳解

編譯原理【3】文法分析概述

分析上面的例子,共有五種文法,其中 | 代表或的意思。

以E為開始進行推導,可以将E替換為T和E’:

E => T E’

由于是最左推導,是以我們選擇替換目前句型的最左端非終結符T為 F T’:

E => T E’

 => F T’ E’

觀察輸入串,首個終結符為id,而F對應可以推導出(E)或者id,為了比對輸入,選擇将F替換為id,此時id成功比對,是以輸入指針後移到加号+:

E => T E’

 => F T’ E’

 => id T’ E’

此時id為終結符,是以最左端非終結符變成 T’。T’可以推導出* F T’或空值 ε,而可推導出的符号中沒有+号,是以目前根節點選擇用空值ε 來代替。

E => T E’

 => F T’ E’

 => id T’ E’

 => id ε E’

最左非終結符變為了E’,對應可以推導出+ T E’或者空值ε,由于可推導出的符号中包含+号,是以将E’替換為+ T E’:

E => T E’

 => F T’ E’

 => id T’ E’

 => id ε E’

 => id ε + T E’

以此類推,最終成功比對。

自頂向下分析面臨的問題

由于要嘗試目前步驟的推導,當遇到一個文法裡多個以終結符A開頭的式子均可以比對A時,便需要挨個嘗試哪個式子能完整推導出輸出,若不能完整推導,就需要回溯,進而帶來了很大的開銷。

編譯原理【3】文法分析概述

預測分析

也就是OJ中常用的的“預判”方法。

比如讀取目前字元,判斷串是否結束(若是空格則代表讀取結束)。

如果不使用預判的方法,讀取到一個空格後,需要回退字元串下标指針來結束讀取。

如果采用if(curChar[i+1] == ’ ') break;的方法,則不需要進入下次循環,也就不需要回退指針。

編譯原理【3】文法分析概述