?
このドキュメントでは、 php中國語ネットマニュアル リリース
分析器階段含兩個部分:
1.在gram.y和scan.l里 定義的分析器(parser)是 使用 Unix 工具bison 和flex創(chuàng)建的
轉(zhuǎn)換處理(transformation process) 對分析器返回的數(shù)據(jù)結(jié)構(gòu)進(jìn)行修改和增補。
分析器必須檢查(以純 ASCII 文本方式到來的)查詢字符串的語法。 如果語法正確,則創(chuàng)建一個分析樹(parse tree)并將之傳回, 否則,返回一個錯誤。 實現(xiàn)分析器和詞法器使用了著名的 Unix 工具bison 和flex.
詞法器(lexer)在文件scan.l里定義, 負(fù)責(zé)識別標(biāo)識符(identifiers) 和 SQL 關(guān)鍵字(SQL key words)等。 對于發(fā)現(xiàn)的每個關(guān)鍵字或者標(biāo)識符都會生成一個記號并且傳遞給分析器。
分析器在文件gram.y里定義 并且包含一套語法規(guī)則(grammar rules) 和觸發(fā)規(guī)則(actions)時執(zhí)行的動作。 動作代碼(實際上是 C 代碼)用于建立分析樹。
文件 scan.l 用flex轉(zhuǎn)換成 C 源文件scan.c, 而gram.y用bison 轉(zhuǎn)換成gram.c。 在完成這些轉(zhuǎn)換后,一個通用的 C 編譯器就可以用于創(chuàng)建分析器。 千萬不要對生成的 C 源文件做修改,因為下一次調(diào)用flex 或bison時會把它們覆蓋。
Note: 上面提到的轉(zhuǎn)換和編譯是使用跟隨 PostgreSQL 發(fā)布的 makefiles自動完成的。
對bison或者gram.y里 的語法規(guī)則的詳細(xì)描述超出本文的范圍。 有很多關(guān)于flex和bison的書籍和文檔。 你在開始研究gram.y里給出的語法之前應(yīng)該對bison很熟悉, 否則你是看不懂那里面的內(nèi)容,理解不了發(fā)生了什么事情的。
分析器階段只使用和 SQL 語法結(jié)構(gòu)相關(guān)的固定規(guī)則創(chuàng)建一個分析樹。 它不會查找任何系統(tǒng)表,因此就不可能理解請求查詢里面的詳細(xì)的語意。 在分析器技術(shù)之后,轉(zhuǎn)換處理接受分析器(transformation process) 傳過來的分析樹然后做進(jìn)一步處理, 解析哪些查詢中引用了哪個表、哪個函數(shù)、哪個操作符的語意。 所生成的表示這個信息的數(shù)據(jù)結(jié)構(gòu)叫做查詢樹(query tree)。
把裸分析和語意分析分成兩個過程的原因是系統(tǒng)表查找只能在一個事務(wù)中進(jìn)行, 而不想在一接收到查詢字符串就發(fā)起一個事務(wù)。 裸分析階段已經(jīng)足夠可以標(biāo)識事務(wù)控制命令(BEGIN,ROLLBACK等), 并且這些東西不用任何進(jìn)一步的分析就可以執(zhí)行。 一旦知道正在處理一個真正的查詢(比如SELECT或UPDATE), 就可以發(fā)起一個事務(wù)了(如果還沒開始這么一個)。 只有這個時候可以調(diào)用轉(zhuǎn)換處理。
轉(zhuǎn)換處理生成的查詢樹結(jié)構(gòu)上在很大程度上類似于裸分析樹,但是在細(xì)節(jié)上有很多區(qū)別。 比如,在分析樹里的FuncCall節(jié)點代表那些看上去像函數(shù)調(diào)用的東西。 根據(jù)引用的名字是一個普通函數(shù)還是一個聚集函數(shù), 這個可能被轉(zhuǎn)換成一個FuncExpr或Aggref節(jié)點。 同樣,有關(guān)字段和表達(dá)式結(jié)果的具體數(shù)據(jù)類型也添加到查詢樹中。