English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

guest
1 / ?
back to lessons

文法作為圖結構

編譯器通過構建分析樹來轉譯原始程式碼——一棵有根樹,其中每個節點代表應用的文法規則,每個葉子代表終端符號(變數名稱、字面值、運算子)。

樹的幾何學

具有 n 個節點與 n−1 條邊的樹。深度 d:從根到任何葉子的最大距離。對於深度為 d 的平衡二元樹:最多 2^d 個葉子與 2^(d+1)−1 個總節點。

典型表達式的分析樹不是平衡的:運算子優先級創建右偏或左偏樹。A + B C 產生一棵樹,其中 + 更深,編碼 * 結合得更緊密。

BNF 與 ALGOL

為指定 ALGOL 而發明的 Backus-Naur 形式 (BNF) 將文法形式化為生成規則:

`` <expr> ::= <term> | <expr> + <term> <term> ::= <factor> | <term> * <factor> <factor> ::= id | (<expr>) ``

每條生成規則定義樹的一個層級。文法是非終端符號上的有向圖;分析句子會沿著該圖從開始符號到葉子追踪路徑。

軟體幾何學:複雜性與冗餘性

分析樹深度與表達式複雜性

對於表達式 (A + B) * (C + D),分析樹在標準運算子優先級下具有特定的結構。

分析樹的深度影響編譯器性能:在遞歸下降分析期間,更深的樹需要更多的堆疊框架。

使用上面的文法為 `(A + B) * (C + D)` 繪製或描述分析樹。它有多少個內部節點?樹的深度是多少(根 = 深度 0)?然後:遞歸下降分析器使用 O(深度) 堆疊空間。對於具有 n 個運算子的完全括號化表達式(每個深度與 n 成正比),Big-O 堆疊空間是多少?

香農熵與冗餘

漢明注意到口語約 60% 冗餘,書面語言約 40%。這有精確的資訊理論含義。

香農熵

對於從字母表 A 生成符號的來源,概率為 {p₁, p₂, ..., pₙ}:

H = −Σ pᵢ log₂(pᵢ) (每個符號的位元數)

最大熵:均勻分佈(所有符號等可能)。n 個符號時 H_max = log₂(n)。

冗餘 R:不攜帶資訊的位元比例(可以移除而不失去內容):

R = 1 − H / H_max

如果 R = 0.4(40% 冗餘):40% 的位元可以從上下文預測。以每字符 8 位元傳輸英文文本的通道僅使用其信息容量的 60%;40% 是接收者已知的結構。

錯誤檢測使用冗餘:如果 40% 的位元是可預測的,傳輸錯誤可能產生違反冗餘結構的序列——即使沒有錯誤更正代碼也可以檢測到。

APL 的近乎零冗餘:單個字符更改幾乎從不從上下文單獨檢測到。英文的 60% 冗餘:即使缺少或錯誤的字母,你也可以經常從周圍上下文重建一個詞。

計算冗餘

英文字母頻率(約):'e' 出現約 12.7% 的時間;'z' 出現約 0.07%。英文的實際熵約為 H ≈ 1.0 位元/字符(考慮字級上下文)。26 字母字母表的最大熵:H_max = log₂(26) ≈ 4.70 位元/字符。

計算英文的冗餘 R = 1 − H/H_max,使用 H = 1.0 位元/字符及 H_max = log₂(26)。然後為具有 H = 3.5 位元/字符的語言計算 R,使用相同的 26 符號字母表。哪種語言有更多的錯誤檢測容量,以及倍數?

增長曲線作為幾何學

編譯器演算法處理大小為 n 的程式(標記、行或節點)。演算法的選擇決定編譯時間如何隨程式大小縮放。

常見複雜性類別

| 類別 | 執行時間 | 例子 | |---|---|---| | O(n) | 線性 | 詞法掃描 | | O(n log n) | 準線性 | 最優排序 | | O(n²) | 二次 | 天真重複檢測 | | O(n³) | 立方 | 矩陣乘法、CYK 分析 | | O(2ⁿ) | 指數 | 天真定理證明 |

幾何圖像:繪製執行時間與 n。O(n) 是一條直線。O(n²) 是拋物線。O(2ⁿ) 是一條指數曲線,在 n=0 附近看起來平坦,在 n=50 附近幾乎垂直。

通用上下文無關文法分析 (CYK 演算法) 在 O(n³) 中執行。對於大多數實用編程語言,文法設計為 LR(1) 可解析,允許 O(n) 分析。ALGOL 的文法比 FORTRAN 的更複雜,導致編譯器更慢——這是 1958 年編譯花費數小時時實際摩擦。

交叉點

天真符號表查詢對於 n 個識別符的程式使用 O(n²) 總操作(每個 n 次查詢進行線性掃描)。哈希表符號表使用 O(n) 預期總操作。

假設:O(n²) 演算法在 1958 年硬體上以 10⁶ 操作/秒運行。O(n) 演算法以相同速度運行,但需要 100n 設置操作(哈希表構造)。

對於具有 n = 1000 識別符的程式:計算兩種演算法的總時間(以秒為單位)。兩種演算法耗時相等的 n 值是多少?顯示代數。