java 中文 语义分析,了解Javac编译器 - xinlan1964的个人页面 - OSCHINA - 中文开源技术交流社区...
本文屬筆記,《深入分析JavaWeb》許令波,第4章,僅記錄看得懂的部分。(這本書內容很多都在IBM上發表過)。如果有侵權請告訴博主,會馬上刪除。
Javac的工作流程:
源碼——詞法分析器——Token流——語法分析器——語法樹——語義分析器——注解語法樹——代碼生成器——字節碼
1)詞法分析
讀取源代碼,一個字節一個字節地讀進來,找到這些字節中哪些是定義的語法關鍵詞,如Java中的if、else、for、while等關鍵詞,要識別哪些if是合法的關鍵詞、哪些不是。
從源碼中找到一些規范化的Token流,就像人類語言中,給你一句話要能分辨出哪些是一個詞語、哪些是標點符號、哪些是動詞、哪些是名詞等。
Scanner負責具體讀取和歸類不同詞法的操作,判斷哪些字符組合是一個Token。JavacParser規定了哪些詞是符合Java語言規范規定的詞:package語法、import語法、類定義、field定義、method定義、變量定義、表達式定義等,每個語法表達式用分號結束。
2)語法分析
對Token流進行語法分析,檢查這些關鍵詞組合在一起是不是符合Java語言規范,如if的后面是不是緊跟著一個布爾判斷表達式。就像人類語言中,是不是有主謂賓,主謂賓結合得是不是正確,語法是不是正確。
形成一個符合Java語言規范的抽象語法樹,抽象語法樹是一個結構化的語法表達式形式,它的作用是把語言的主要詞法用一個結構化的形式組織在一起。這顆語法樹可以被我們后面按照新的規則重新組織。
將token流組建成更加結構化的語法樹,也就是間一個個單詞組裝成一句話,一個完整的語句。哪些詞語組合在一起是主語、哪些是謂語、哪些是賓語、哪些是定語,要做進一步區分。Java語法樹使得Java源代碼更加結構化:每個語法樹上的節點都是com.sun.tools.javac.tree.JCTree的一個實例,①每個語法節點都會實現一個接口xxxTree,這個接口又繼承于com.sun.source.tree.Tree接口,如IfTree語法節點表示一個if類型的表達式,BinaryTree語法節點代表一個二元操作表達式等;②每個語法節點都是com.sum.tools.javac.tree.JCTree的子類,并且會實現xxxTree接口類,這個類的類名類似于JCxxx,如實現IfTree接口的實現類為JCIf,實現BinaryTree接口的類為JCBinary等;③所有的JCxxx類都作為一個靜態內部類在JCTree類中。
3)語義分析
把一些難懂的、復雜的語法轉化成更加簡單的語法。這個步驟類似將難懂的文言文轉化成大家都能懂的白話文或者注解一下一些成語,便于人們更好地理解。
將復雜的語法轉化成最簡單的語法,對應到Java中,如將foreach轉成for循環結構,還有注解等,最后形成一個注解過后的抽象語法樹,這顆語法樹更接近目標語言的語法規則。
com.sum.tools.javac.comp.Enter:符號表的構建
1)將Java類中的符號輸入到符號表中
1)給類添加默認的構造函數
com.sun.tools.javac.processing.JavacProcessingEnvironment:annotation處理
2)處理annotation注解
com.sun.tools.javac.comp.Attr:標注和語法檢查
3)檢查操作變量類型是否匹配,操作數|方法返回值類型匹配com.sun.tools.javac.comp.Check
3)檢查變量、方法或類的訪問是否合法、變量是否是靜態變量、變量在使用前是否已經初始化com.sun.tools.javac.comp.Resolve
3)推導出泛型方法中的參數類型com.sum.tools.javac.comp.Infer
3)將一些常量進行合并處理com.sum.tools.javac.comp.ConstFold
com.sun.tools.javac.comp.Flow數據流分析
4)檢查變量在使用前是否已經正確賦值
4)包裝final修飾的變量不會被重新賦值
4)方法的返回值類型都要確定
4)檢查所有的操作是否可達
4)檢查checked exception異常是否已經捕獲或拋出
5)解除Java的語法糖
5)去掉無用的代碼,如永假的if代碼塊
5)變量的自動轉換,如將int自動包裝成Integer類型或者相反的操作等;
4)代碼生成器
根據經過注解的抽象語法樹生成字節碼,將一個數據結構轉化為另一個數據結構,類似將所有的中文語句翻譯成英文單詞后按照英文語法組裝成英文語句。
com.sun.tools.javac.jvm.Gen
①將Java方法中的代碼塊轉成符合JVM語法的命令形式,JVM的操作都是基于棧的,所有的操作都必須經過出棧和進棧來完成。
②安裝JVM的文件組織格式將字節碼輸出到以class為擴展名的文件中。
2個類:
①Items:任何可尋址的操作項,這些包括本地變量、類實例變量或者常量池中用戶自定義的常量等,這些操作項都可以作為一個單位出現在操作棧上
②Code:存儲生成的字節碼和提供一些能夠映射操作碼的方法
Javac中訪問者模式的實現
詞法分析、語法分析、語義分析和代碼生成都要多次遍歷語法樹,但每次遍歷這顆語法樹都會進行不同的處理動作。Javac采用訪問者模式設計,每次遍歷都是一次訪問者的執行過程。
訪問者模式可以將數據結構和對數據結構的操作解耦,使得增加對數據結構的操作不需要去修改數據結構,也不必去修改原有的操作,而執行時再定義新的Visitor實現者就可以。在Javac中不同的編譯階段都定義了不同的訪問者模式實現。
①TreeScanner、Enter、Attr、Gen、Flow等都是作為具體訪問者角色,每個訪問者都定義了自己的訪問規則.
②EJCIf、JCTry、JCBreak、JCReturn都是具體節點元素,作為一個穩定的數據結構存在。
總結
以上是生活随笔為你收集整理的java 中文 语义分析,了解Javac编译器 - xinlan1964的个人页面 - OSCHINA - 中文开源技术交流社区...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux在A目录下创建B文件,Linu
- 下一篇: java汉字转化accic_Java自主