初識抽象語法樹(AST)

  • 基本概念
  1. 基本字:阿拉伯數(shù)字、大小寫拉丁字母蜓竹、其他字符(~箕母、!俱济、%嘶是、&、_姨蝴、-俊啼、+、=左医、{}授帕、[]同木、:、跛十;彤路、<、>芥映、洲尊,、.奈偏、坞嘀?、/惊来、|丽涩、\)、空格符裁蚁、換行符矢渊、制表符等。
  2. 關鍵字(keyword):提前被定義枉证,并賦予有特殊的含義的單詞
  3. 保留字: 提前被定義矮男,但還未被賦值(保留字與關鍵字有時等價)
  4. 標識符(identifier): 由數(shù)字、字母室谚、下劃線組成毡鉴,且不能以數(shù)字開頭,用于給變量舞萄、常量眨补、函數(shù)、語句塊等命名倒脓。
  • c語言中標識符包括:關鍵字(如int撑螺、while)、預定義標識符(如printf)和用戶自定義標識符崎弃。

當下的編譯器都做了純文本轉(zhuǎn)AST的事情甘晤。

一款編譯器的編譯流程是很復雜的,但我們只需要關注詞法分析語法分析饲做,這兩步是從代碼生成AST的關鍵所在线婚。

  • 詞法分析器(scanner)
詞法分析器結構

在掃描器的驅(qū)動下,預處理子程序?qū)⒌捷斎刖彌_區(qū)中源代碼的字符處理后由
掃描緩沖區(qū)讀入盆均。掃描器在掃描緩沖區(qū)中識別單詞符號塞弊,然后輸出。

其中預處理子程序的作用是:

  1. 剔除源代碼中的空格、回車符游沿、換行符等編輯性字符
  2. 區(qū)分標號區(qū)饰抒、捻接續(xù)行,給出句末符等等

現(xiàn)代程序設計語言在最初設計時就遵循了一些規(guī)則:

  1. 所有基本字都是保留字诀黍,不可再作為標識符
  2. 基本字作為特殊的標識符處理
  3. 基本字袋坑、標識符和常數(shù)間若沒有確定的運算符或界符作間隔,必須使用一個空白符作間隔眯勾,一方面避免了超前搜索枣宫、方便編譯程序進行詞法分析,另一方面增加代碼的可讀性

  • 詞法分析器設計:
  1. 確定語言單詞規(guī)范——單詞表
  2. 有單詞表得到該語言所有字的狀態(tài)轉(zhuǎn)換圖
  3. 根據(jù)狀態(tài)轉(zhuǎn)換圖實現(xiàn)詞法分析器

詞法分析器會讀取代碼吃环,它會一個一個字母地讀取代碼也颤,所以很形象地稱之為掃描(scanner)。然后把它們按照預定的規(guī)則合并成一個個的標識(tokens)模叙,當它遇到空格歇拆、操作符鞋屈,或者特殊符號的時候范咨,它會認為一個話已經(jīng)完成了。同時厂庇,它會移除空白符渠啊、注釋等。最后权旷,整個代碼將被分割進一個 tokens 列表(或者說一維數(shù)組)

//詞法分析器典型輸入輸出
const a = 5;
// 轉(zhuǎn)換成
[{value: 'const', type: 'keyword'}, {value: 'a', type: 'identifier'}, ...]

  • 語法分析器(parser)

語法分析會將詞法分析出來的列表轉(zhuǎn)換成樹形的形式替蛉,同時驗證語法。語法如果有錯的話拄氯,拋出語法錯誤躲查。

[{value: 'const', type: 'keyword'}, {value: 'a', type: 'identifier'}, ...]
// 語法分析后的樹形形式
{
   type: "VariableDeclarator", //變量聲明
   id: {
       type: "Identifier",//標識符
       name: "a"
   },
   ...

當生成樹的時候,解析器會刪除一些沒必要的標識 tokens(比如:不完整的括號)译柏,因此 AST 不是 100% 與源碼匹配的镣煮。


  • 語法分析相關概念
  1. 巴克斯范式(EBNF)【巴克斯范式(Backus Form)簡單例子-from知乎
EBNF元符號 含義
::= 可解釋為,可推導為
|
() 一項鄙麦,一次重復
[] 0次和1次重復
{} 0次或任意多次重復
. 一條生成規(guī)則的結束
<> 非終結符
“” 終結符
  1. 翻譯單元: 什么是翻譯單元?

酷文章: ==C實現(xiàn)詞法分析及語法分析==


現(xiàn)在典唇,我們拆解一個簡單的add函數(shù)

function add(a, b) {
    return a + b
}

首先,我們拿到的這個語法塊胯府,是一個FunctionDeclaration(函數(shù)定義)對象介衔。

用力拆開,它成了三塊:

  • 一個id骂因,就是它的名字炎咖,即add
  • 兩個params,就是它的參數(shù),即[a, b]
  • 一塊body乘盼,也就是大括號內(nèi)的一堆東西
{
    name: 'add'
    type: 'identifier'
    ...
}

params繼續(xù)拆下去急迂,其實是兩個Identifier組成的數(shù)組。之后也沒辦法拆下去了蹦肴。

[
    {
        name: 'a'
        type: 'identifier'
        ...
    },
    {
        name: 'b'
        type: 'identifier'
        ...
    }
]
  • 接下來僚碎,我們繼續(xù)拆開body,我們發(fā)現(xiàn)阴幌,body其實是一個BlockStatement(塊狀域)對象勺阐,用來表示是\color{blue}{\{return\ a + b\}}

  • 打開Blockstatement,里面藏著一個ReturnStatement(Return域)對象矛双,用來表示\color{blue}{return\ a + b}

  • 繼續(xù)打開ReturnStatement,里面是一個BinaryExpression(二項式)對象渊抽,用來表示\color{blue}{a + b}

  • 繼續(xù)打開BinaryExpression,它成了三部分议忽,\color{blue}{left}懒闷、\color{blue}{operator}\color{blue}{right}

  • \color{blue}{operator }\color{blue}{+}

  • \color{blue}{left} 里面裝的栈幸,是Identifier對象 \color{blue}{a}

  • \color{blue}{right }里面裝的愤估,是Identifer對象 \color{blue}

就這樣速址,我們把一個簡單的add函數(shù)拆解完畢玩焰,用圖表示就是

"add" `s AST

酷文章:

詞法分析器中的預處理程序部分

詞法分析器中的詞法分析程序部分

詞法分析器
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末昔园,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子并炮,更是在濱河造成了極大的恐慌默刚,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逃魄,死亡現(xiàn)場離奇詭異荤西,居然都是意外死亡,警方通過查閱死者的電腦和手機嗅钻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門皂冰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人养篓,你說我怎么就攤上這事秃流。” “怎么了柳弄?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵舶胀,是天一觀的道長概说。 經(jīng)常有香客問我,道長嚣伐,這世上最難降的妖魔是什么糖赔? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮轩端,結果婚禮上放典,老公的妹妹穿的比我還像新娘。我一直安慰自己基茵,他們只是感情好奋构,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拱层,像睡著了一般弥臼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上根灯,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天径缅,我揣著相機與錄音,去河邊找鬼烙肺。 笑死纳猪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的茬高。 我是一名探鬼主播兆旬,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怎栽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宿饱,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤熏瞄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谬以,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體强饮,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年为黎,在試婚紗的時候發(fā)現(xiàn)自己被綠了邮丰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡铭乾,死狀恐怖剪廉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情炕檩,我是刑警寧澤斗蒋,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響泉沾,放射性物質(zhì)發(fā)生泄漏捞蚂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一跷究、第九天 我趴在偏房一處隱蔽的房頂上張望姓迅。 院中可真熱鬧,春花似錦俊马、人聲如沸队贱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柱嫌。三九已至,卻和暖如春屯换,著一層夾襖步出監(jiān)牢的瞬間编丘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工彤悔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嘉抓,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓晕窑,卻偏偏與公主長得像抑片,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子杨赤,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容