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