<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 手把手教你做一個 C 語言編譯器(7):語句 整個編譯器還剩下最后兩個部分:語句和表達式的解析。它們的內容比較多,主要涉及如何將語句和表達式編譯成匯編代碼。這章講解語句的解析,相對于表達式來說它還是較為容易的。 **本系列:** 1. [手把手教你做一個 C 語言編譯器(0):前言](http://blog.jobbole.com/97332/) 2. [手把手教你做一個 C 語言編譯器(1):設計](http://blog.jobbole.com/97350/) 3. [手把手教你做一個 C 語言編譯器(2):虛擬機](http://blog.jobbole.com/97359/) 4. [手把手教你做一個 C 語言編譯器(3):詞法分析器](http://blog.jobbole.com/97375/) 5. [手把手教你做一個 C 語言編譯器(4):遞歸下降](http://blog.jobbole.com/97382/) 6. [手把手教你做一個 C 語言編譯器(5):變量定義](http://blog.jobbole.com/97401/) 7. [手把手教你做一個 C 語言編譯器(6):函數定義](http://blog.jobbole.com/97407/) ## 語句 C 語言區分“語句”(statement)和“表達式”(expression)兩個概念。簡單地說,可以認為語句就是表達式加上末尾的分號。 在我們的編譯器中共識別 6 種語句: 1. `if (...) &lt;statement&gt; [else &lt;statement&gt;]` 2. `while (...) &lt;statement&gt;` 3. `{ &lt;statement&gt; }` 4. `return xxx;` 5. `&lt;empty statement&gt;`; 6. `expression;` (expression end with semicolon) 它們的語法分析都相對容易,重要的是去理解如何將這些語句編譯成匯編代碼,下面我們逐一解釋。 ### IF 語句 IF 語句的作用是跳轉,跟據條件表達式決定跳轉的位置。我們看看下面的偽代碼: ``` if (...) <statement> [else <statement>] if (<cond>) <cond> JZ a <true_statement> ===> <true_statement> else: JMP b a: a: <false_statement> <false_statement> b: b: ``` 對應的匯編代碼流程為: 1. 執行條件表達式 `&lt;cond&gt;`。 2. 如果條件失敗,則跳轉到 `a` 的位置,執行 `else` 語句。這里 `else` 語句是可以省略的,此時 `a` 和 `b` 都指向 IF 語句后方的代碼。 3. 因為匯編代碼是順序排列的,所以如果執行了 `true_statement`,為了防止因為順序排列而執行了 `false_statement`,所以需要無條件跳轉 `JMP b`。 對應的 C 代碼如下: ``` if (token == If) { match(If); match('('); expression(Assign); // parse condition match(')'); *++text = JZ; b = ++text; statement(); // parse statement if (token == Else) { // parse else match(Else); // emit code for JMP B *b = (int)(text + 3); *++text = JMP; b = ++text; statement(); } *b = (int)(text + 1); } ``` ### While 語句 While 語句比 If 語句簡單,它對應的匯編代碼如下: ``` a: a: while (<cond>) <cond> JZ b <statement> <statement> JMP a b: b: ``` 沒有什么值得說明的內容,它的 C 代碼如下: ``` else if (token == While) { match(While); a = text + 1; match('('); expression(Assign); match(')'); *++text = JZ; b = ++text; statement(); *++text = JMP; *++text = (int)a; *b = (int)(text + 1); } ``` ### Return 語句 Return 唯一特殊的地方是:一旦遇到了 Return 語句,則意味著函數要退出了,所以需要生成匯編代碼 `LEV` 來表示退出。 ``` else if (token == Return) { // return [expression]; match(Return); if (token != ';') { expression(Assign); } match(';'); // emit code for return *++text = LEV; } ``` ### 其它語句 其它語句并不直接生成匯編代碼,所以不多做說明,代碼如下: ``` else if (token == '{') { // { <statement> ... } match('{'); while (token != '}') { statement(); } match('}'); } else if (token == ';') { // empty statement match(';'); } else { // a = b; or function_call(); expression(Assign); match(';'); } ``` ## 代碼 本章的代碼可以在 [Github](https://github.com/lotabout/write-a-C-interpreter/tree/step-5) 上下載,也可以直接 clone ``` git clone -b step-5 https://github.com/lotabout/write-a-C-interpreter ``` 本章的代碼依舊無法運行,還剩最后一部分沒有完成:`expression`。 ## 小結 本章講解了如何將語句編譯成匯編代碼,內容相對容易一些,關鍵就是去理解匯編代碼的執行原理。 同時值得一提的是,編譯器的語法分析部分其實是很簡單的,而真正的難點是如何在語法分析時收集足夠多的信息,最終把源代碼轉換成目標代碼(匯編)。我認為這也是初學者實現編譯器的一大難點,往往比詞法分析/語法分析更困難。 所以建議如果沒有學過匯編,可以學習學習,它本身不難,但對理解計算機的原理有很大幫助。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看