亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

【PHP源碼學(xué)習(xí)】2019-03-20 PHP詞法分析

SolomonXie / 2116人閱讀

摘要:詞法分析它是編譯過程的第一個階段。可以使用等自動化詞法分析工具,來幫助我們完成。在中,使用的詞法分析器是,語法分析器是。其實(shí)進(jìn)行詞法分析和語法分析并生成某種數(shù)據(jù)結(jié)構(gòu)的過程,就是一個解碼的過程。

baiyan

全部視頻:https://segmentfault.com/a/11...

原視頻地址:http://replay.xesv5.com/ll/24...

基本概念

在PHP7中,當(dāng)一個腳本運(yùn)行請求或到來時,PHP代碼首先會被加載到內(nèi)存中,隨后進(jìn)行詞法分析和語法分析并生成抽象語法樹(AST),然后進(jìn)行深度優(yōu)先遍歷并生成opcodes,并在zend虛擬機(jī)中執(zhí)行這些opcode,返回最終的執(zhí)行結(jié)果。

詞法分析:它是編譯過程的第一個階段。這個階段會將代碼從左到右按字符掃描并讀入,然后將代碼劃分成一個又一個的詞法單元(token),方便后續(xù)的語法分析以及編譯優(yōu)化等操作。這就好比用菜刀去切一塊肉,將這塊大肉切分成一小塊一小塊肉,方便人們后續(xù)食用。可以使用Re2c、lex等自動化詞法分析工具,來幫助我們完成。

語法分析:語法分析是編譯過程的一個邏輯階段。語法分析的任務(wù)是在詞法分析的基礎(chǔ)上將詞法單元token,組合成各類語法短語,如“程序”,“語句”,“表達(dá)式”等等,它能夠判斷源程序在結(jié)構(gòu)上是否正確。

在PHP中,使用的詞法分析器是Re2c,語法分析器是Bison。

其實(shí)進(jìn)行詞法分析和語法分析并生成某種數(shù)據(jù)結(jié)構(gòu)的過程,就是一個解碼的過程。

之所以需要做這種從字符串到數(shù)據(jù)結(jié)構(gòu)(AST)的轉(zhuǎn)換,是因?yàn)榫幾g器是無法直接操作“1+2”這樣的字符串的。實(shí)際上,代碼的本質(zhì)根本就不是字符串,它本來就是一個具有復(fù)雜拓?fù)涞臄?shù)據(jù)結(jié)構(gòu),就像電路一樣?!?+2”這個字符串只是對這種數(shù)據(jù)結(jié)構(gòu)的一種“編碼”,就像ZIP或者JPEG只是對它們壓縮的數(shù)據(jù)的編碼一樣。
這種編碼可以方便你把代碼存到磁盤上,方便你用文本編輯器來修改它們(對人友好,方便人們編寫代碼,但是對編譯器不友好),然而你必須知道,文本并不是代碼本身。所以從磁盤讀取了文本之后,你必須先“解碼”,才能方便地操作代碼的數(shù)據(jù)結(jié)構(gòu)。比如,如果上面的Java代碼生成的AST節(jié)點(diǎn)叫node,你就可以用node.operator來訪問加號ADD,用node.left來訪問1,node.right來訪問2。這是很方便的。對于程序語言,這種解碼的動作就叫做parsing,用于解碼的那段代碼就叫做parser。

關(guān)于語法分析與詞法分析的具體概念解釋,這篇文章寫得較好:對 Parser 的誤解

我們先利用PHP內(nèi)置函數(shù)token_get_all()來取出一段PHP代碼的token:


打印結(jié)果為:

Line 1: T_OPEN_TAG ("

觀察以上結(jié)果,可以看有OPEN_TAG/VARIABLE/WHITESPACE等等詞法單元token。

如何取出token

那么讓我們你自己去設(shè)計(jì)一個算法,從一個字符串中識別并取出token,應(yīng)該怎么做?

使用兩個指針,一個標(biāo)記開始位置,一個往后挪,然后回溯。(較麻煩)

使用正則表達(dá)式進(jìn)行匹配

當(dāng)用較簡單的字符串匹配正則表達(dá)式的時候,可以用人眼很容易地看出來。但是如果用很復(fù)雜的字符串(成千上萬行代碼)去匹配一個正則,是相當(dāng)麻煩并且非常慢的,編譯原理中提出了這樣一個概念用以解決這個問題:有窮狀態(tài)機(jī)。

有窮狀態(tài)機(jī):必須有一個起始狀態(tài),用一個箭頭加圓圈表示;也得有一個結(jié)束,用兩個圓圈表示。 如果滿足某個條件,就會從一個狀態(tài)躍遷到另一個狀態(tài),也用箭頭來表示。

例:觀察下面這個正則表達(dá)式:

(a|b)*abb

根據(jù)這個正則表達(dá)式,我們可以畫出它的有窮狀態(tài)機(jī):

- 對于a,只能到狀態(tài)0或者1,不能到達(dá)結(jié)束的3,所以不匹配
- 對于abb,第一個a可以使?fàn)顟B(tài)0躍遷到1,第二個b可以從1躍遷到2,最后一個b結(jié)束,所以匹配
- 對于aabb,第一個a可以選擇從0躍遷到0,第二個從0躍遷到1,后面兩個b同上,匹配
- 對于cabb,第一個c就無法滿足,不匹配

這里有個問題,輸入第一個a的時候,可以從0躍遷到自己,也可以從0躍遷到1,所以這種狀態(tài)機(jī)就叫不確定有窮狀態(tài)機(jī)(NFA)

NFA是有缺陷的,比如aabb,有可能一直從0躍遷到0,共重復(fù)了4次這樣的操作,也沒有到達(dá)最終的結(jié)束狀態(tài)3。這就會導(dǎo)致本應(yīng)該符合匹配要求的字符串,在不確定有窮狀態(tài)機(jī)中,錯誤地被判定為不符合匹配要求。解決此問題的辦法就是將不確定有窮狀態(tài)機(jī)轉(zhuǎn)化為確定有窮狀態(tài)機(jī)(DFA)。

這樣一來,一個確定的輸入就對應(yīng)著一個確定的輸出(假設(shè)如給一個a,一定躍遷到1;給一個b,一定躍遷回0),不存在歧義問題。

但是,將一個NFA轉(zhuǎn)化成DFA是相當(dāng)復(fù)雜的,所以有工具已經(jīng)為我們做好了這個事情:Re2c。你只需要輸入一個正則表達(dá)式,就能夠?yàn)槟闵梢粋€確定有窮狀態(tài)機(jī)(DFA),在Re2c工具中以C/C++代碼體現(xiàn),詳情見:re2c中文手冊

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/31326.html

相關(guān)文章

  • 【LNMPR源碼學(xué)習(xí)】筆記匯總

    摘要:此文用于匯總跟隨陳雷老師及團(tuán)隊(duì)的視頻,學(xué)習(xí)源碼過程中的思考整理與心得體會,此文會不斷更新視頻傳送門每日學(xué)習(xí)記錄使用錄像設(shè)備記錄每天的學(xué)習(xí)源碼學(xué)習(xí)源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)內(nèi)存管理筆記源碼學(xué)習(xí)基本變量筆記 此文用于匯總跟隨陳雷老師及團(tuán)隊(duì)的視頻,學(xué)習(xí)源碼過程中的思考、整理與心得體會,此文會不斷更新 視頻傳送門:【每日學(xué)習(xí)記錄】使用錄像設(shè)備記錄每天的學(xué)習(xí) PHP7...

    Barrior 評論0 收藏0
  • PHP源碼學(xué)習(xí)2019-03-21 AST

    摘要:全部視頻原視頻地址引入抽象語法樹是中新引入的,在許多其他語言中早已有實(shí)現(xiàn)。例,怎么用抽象語法樹來表達(dá)那么使用中序遍歷就可以得到上述表達(dá)式。 baiyan 全部視頻:https://segmentfault.com/a/11... 原視頻地址:http://replay.xesv5.com/ll/24... 引入 抽象語法樹(AST)是PHP7中新引入的,在許多其他語言中早已有實(shí)現(xiàn)。 ...

    everfight 評論0 收藏0
  • PHP7源碼分析PHP7語言的執(zhí)行原理

    摘要:在中,源代碼首先將進(jìn)行詞法分析,將源代碼切割為多個字符串單元,分割后的字符串稱之為。圖以為例解釋型語言的執(zhí)行示意圖第步源碼通過詞法分析得到第步基于語法分析器生成抽象語法樹第步抽象語法樹轉(zhuǎn)換為指令集合,解釋執(zhí)行。 順風(fēng)車運(yùn)營研發(fā)團(tuán)隊(duì) 李志 發(fā)表在程序人生 公眾號我們常用的高級語言有很多種,比較出名的有CC++、Python、 PHP、Go、Pascal等。而這些語言根據(jù)運(yùn)行的方式不同,...

    VEIGHTZ 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<