摘要:語法分析解析字符如果類型為數字,則解析數字,不為浮點數,所以執行分支。解析函數會調用函數返回代表數字的類型同樣為的節點,這點同解析數字的過程,不再贅述。參數為類型為的代表數字的節點,會生成將載入寄存器,返回。函數將彈入寄存器。
1.? 要編譯的測試代碼:
int main(void){ 2+3*4;}
?
2. 詞法分析
詞法分析將字符變成token,其中很重要的是token的類型,如字符2的token類型為TK_NUM,這在后面的語法分析階段有用。
?
3. 語法分析
?
3.1 解析字符"2"
if (tok->kind == TK_NUM) { Node *node; if (is_flonum(tok->ty)) { node = new_node(ND_NUM, tok); node->fval = tok->fval; } else { node = new_num(tok->val, tok); } node->ty = tok->ty; *rest = tok->next; return node; }
如果token類型為數字,則解析數字,2不為浮點數,所以執行else分支。
static Node *new_num(int64_t val, Token *tok) { Node *node = new_node(ND_NUM, tok); node->val = val; return node;}
創建一個類型為ND_NUM的node節點,這個節點就代表了數字2,數字2存儲在node節點的val變量中。
?
3.2 解析"+"
static Node *add(Token **rest, Token *tok) { Node *node = mul(&tok, tok); for (;;) { Token *start = tok; if (equal(tok, "+")) { node = new_add(node, mul(&tok, tok->next), start); continue; } if (equal(tok, "-")) { node = new_sub(node, mul(&tok, tok->next), start); continue; } *rest = tok; return node; }}
數字2的node節點由mul函數返回,此時tok為"+",所以會調用new_add函數,在這個函數中會創建類型為ND_ADD的node節點,
這個節點的左表達式為代表數字2的node節點,右表達式為代表乘法運算的node節點。
static Node *new_add(Node *lhs, Node *rhs, Token *tok) {
if (is_numeric(lhs->ty) && is_numeric(rhs->ty)) return new_binary(ND_ADD, lhs, rhs, tok);
...
}
static Node *new_binary(NodeKind kind, Node *lhs, Node *rhs, Token *tok) { Node *node = new_node(kind, tok); node->lhs = lhs; node->rhs = rhs; return node;}
?
3.3 解析"*"
static Node *mul(Token **rest, Token *tok) { Node *node = cast(&tok, tok); for (;;) { Token *start = tok; if (equal(tok, "*")) { node = new_binary(ND_MUL, node, cast(&tok, tok->next), start); continue; } if (equal(tok, "/")) { node = new_binary(ND_DIV, node, cast(&tok, tok->next), start); continue; } if (equal(tok, "%")) { node = new_binary(ND_MOD, node, cast(&tok, tok->next), start); continue; } *rest = tok; return node;: }}
mul函數會調用cast函數返回代表數字3的類型同樣為ND_NUM的node節點,這點同解析數字2的過程,不再贅述。
由于tok此時為"*",所以會創建類型為ND_MUL的乘法node節點,這個節點的左表達式為代表數字3的類型為
ND_NUM的node節點,右表達式為cast函數返回的代表數字4的類型為ND_NUM的node節點。
?
4. 解析上一步生成的語法樹生成匯編代碼
static void gen_expr(Node *node) { switch (node->kind) { case ND_NUM: { println(" mov $%ld, %%rax", node->val); return; ... } gen_expr(node->rhs); push(); gen_expr(node->lhs); pop("%rdi"); switch (node->kind) { case ND_ADD: println(" add %s, %s", di, ax); return; case ND_MUL: println(" imul %s, %s", di, ax); return; ... }...}
4.1 gen_expr的參數為類型為ND_ADD的node節點,首先遞歸調用gen_expr,傳入的參數為類型為ND_MUL的node節點,又會遞歸調用
gen_expr,傳入的參數為類型為ND_NUM的代表數字4的node節點,此時會生成匯編語句"mov rax, 4",將4載入rax寄存器,gen_expr返回。
4.2 push函數生成"push? ? rax",將4壓入棧。
4.3 gen_expr的參數為類型為ND_NUM的代表數字3的node節點,會生成"mov? ? ?rax, 3",將3載入rax寄存器,gen_expr返回。
4.4 pop("%rdi")函數將4彈入rdi寄存器。
4.5 由于node節點類型為ND_MUL,所以生成"imul? ? eax, edi",計算3*4,結果保存在eax寄存器中,并從gen_expr返回。
4.6 回到參數為ND_ADD的gen_expr函數中。
4.7 push函數生成"push? ? rax",將3*4壓入棧。
4.8 gen_expr參數為類型為ND_NUM的代表數字2的node節點,會生成"mov? ? ?rax, 2",將2載入rax寄存器,gen_expr返回。
4.9 pop("%rdi");函數將3*4彈入rdi寄存器。
4.10 由于node節點類型為ND_ADD,所以生成"add? ? ?eax, edi",計算2+3*4,結果保存在eax寄存器中,并從gen_expr返回。
?
?
?
?
?
?
?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/124823.html
直接進入核心現在說說baseCompile核心代碼: //`createCompilerCreator`allowscreatingcompilersthatusealternative //parser/optimizer/codegen,e.gtheSSRoptimizingcompiler. //Herewejustexportadefaultcompilerusingthede...
let和const let和const兩者并不存在變量提升 這里要說明的是變量一定要在聲明后使用,否則報錯。 vara=[]; for(vari=0;i<10;i++){ a[i]=function(){ console.log(i); }; } a[6]();//10 變量i是var聲明的,我們要知道這里在全局范圍內都有效。我們要知道在每一次循環中,新的...
關于parseHTML 函數源碼解析 AST 相關知識已做過介紹,下面可以看看Vue start鉤子函數源碼。 start:functionstart(tag,attrs,unary){ //checknamespace. //inheritparentnsifthereisone varns=(currentParent&¤tParent.ns)||...
小編寫這篇文章的主要目的,主要是給大家解讀關于python接口自動化的一些詳細代碼實例,具體是什么呢?下面就給各位讀者詳細的解答下。 前言 我們做接口自動化的過程中,解決端口依賴的相關數據時,一般會采用正則匹配去進行獲取有關的信息。 正則匹配,又被稱為正規表示式、正規表示法、正規表達式、規則表達式、常規表示法(RegularExpression,在編碼中常縮寫為regex、regexp或...
閱讀 1131·2021-11-24 09:38
閱讀 3236·2021-11-19 09:56
閱讀 2959·2021-11-18 10:02
閱讀 730·2019-08-29 12:50
閱讀 2572·2019-08-28 18:30
閱讀 864·2019-08-28 18:10
閱讀 3670·2019-08-26 11:36
閱讀 2646·2019-08-23 18:23