符號表和語義分析
一、語義分析的內容
1. 遇到名稱 (變數名,函式名) 定義時
檢查是否重定義。(redefined)
2. 遇到名稱使用時
檢查是否未定義。(undefined)
3. 型別檢查
表示式中的運算,賦值,函式呼叫中的引數,都要檢查型別是否匹配或相容。
二、符號表
為了實現語義分析,使用符號表。
當定義乙個名稱時,需要查詢符號表,看該名稱是否重定義。若是,報錯 redefined;否則把該名稱插入到符號表中。
當使用乙個名稱時,需要查詢符號表,看該名稱是否未定義。若是,報錯 undefined。
為簡單起見,用鍊錶實現符號表。產品級編譯器中,通常使用hash表來實現符號表。
三、作用域 (scope)
為了減少名稱的衝突,程式語言中使用作用域的概念。作用域指名稱(變數名,函式名等)的有效引用範圍。
在不同作用域中,可定義相同的名稱。在內層作用域中,可定義與外層作用域相同的名稱。
四、c語言中的作用域
有三種:
1. 全域性作用域
1) 全域性變數
2) 函式
函式內不能定義函式,所有函式是全域性的。從定義處直到檔案結束的範圍內,函式有效、可以引用。
2. 函式作用域
包括函式引數和函式內定義的區域性變數。只在該函式範圍內有效。
3. 塊作用域。
在塊語句(花括號)內定義的變數。只在該塊語句範圍內有效。
示例。1 #include
2 // 進入全域性作用域:level = 0
3 int a, b;
45 int add(int a, int b) // 退出函式作用域:level = 0
1011 int main() // 退出塊作用域:level = 1
2324 printf("a=%d b=%d c=%d\n", a, b, c);
25 } // 退出函式作用域:level = 0
五、最內巢狀作用域規則
在外層作用域定義的名稱,在內層作用域裡可見,除非內層作用域裡定義了相同的名稱。
在使用乙個名稱時,按照從內層到外層的順序,來查詢該名稱的定義之處。
滿足這種規則的作用域,稱靜態作用域,也稱詞法作用域。
六、符號表的實現
用鍊錶實現。每次插入符號,插入到表頭。
設定乙個全域性變數 level,記錄當前作用域的層次 (深度)。
用一例加以說明。
$ cat -n t4.cmm
1 int a, b;
23 int add(int a, int b)
89 int main()
1) 一開始,進入全域性作用域, level = 0;
2) 分析到乙個函式,從參數列開始,進入函式作用域,level++;
分析完第4行後,符號表:
3) 每退出乙個函式,釋放該函式加入到符號表的符號,level--;
分析完第7行後,符號表:(乙個函式結束後,)
4) 進入下乙個函式
分析完第10行後,符號表:
語法分析 編譯原理
實驗目的 對迴圈語句和條件判斷語句編寫詞法分析編譯程式,只能通過一遍掃瞄完成。用c 實現 實驗要求 1 關鍵字 for if then else while do 所有關鍵字都是小寫。2 運算子和分隔符 3 其他識別符號 id 和整型常數 num 通過以下正規式定義 id letter letter...
編譯原理 語法分析
根據上課內容順序寫的部落格,並不是按照書的目錄來的 使用龍書以及編譯程式設計原理 第二版 金成植 金英編著 老師的ppt是英文的,我自己隨便翻的,不一定對 上下文無關文法 語法分析書和抽象語法樹 二義性簡單語言的語法 知識圖譜 語法分析器的功能輸入 詞法單元 詞法單元序列 輸出 語法結構的內在表示式...
編譯原理 語法分析(二)
在第一篇文章中,我們介紹了如何用上下文無關文法描述一種語言的語法,和如何使用推導和規約構造一棵語法分析樹,以及如何對文法進行轉換使之能夠更適用於語法分析。在本篇文章中,我們將介紹如何使用自頂向下的方法進行語法分析,進一步的,我們將介紹一種更高效的 分析方法。為了下文需要和減少重複,我們先給出在下文中...