<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                LLVM平臺,短短幾年間,改變了眾多編程語言的走向,也催生了一大批具有特色的編程語言的出現,不愧為編譯器架構的王者,也榮獲2012年ACM軟件系統獎 —— 題記 版權聲明:本文為 西風逍遙游 原創文章,轉載請注明出處 西風世界 [http://blog.csdn.net/xfxyy_sxfancy](http://blog.csdn.net/xfxyy_sxfancy) # 棧式符號表的構建 棧式符號表對于一款編譯器,無疑是核心的組件。 無論你在做什么符號掃描,那么都離不開符號表,如何得知一個符號是否定義,以及它的類型,那么唯有查看符號表中的記錄。 棧式符號表并不復雜,但思想精妙,本文,將介紹一款棧式符號表的原理及簡單構建。 ### 源代碼的例子 首先我們來看一段C代碼 ~~~ int a[3] = { 100, 10, 1}; int work() { if (a[0] == 100) { // 這里的a指向的是全局符號a int a = 99999; // 重新定義了局部符號 下圖的符號表是掃描到這里后的情況 for (int i = 0; i< 10; ++i) { a /= 3; // 由于局部符號優先級較高,引用局部符號 } return a; // 局部符號 } return a[0]; // 局部符號生命周期已過,找到全局符號 } ~~~ 于是我們發現,符號表在局部聲明變量后,將局部符號增加了,這和全局符號并不沖突,而是優先級不同,越靠近棧頂,越先發現 ![棧式符號表](https://box.kancloud.cn/2016-06-03_5750ee1b9c1ed.jpg "") ### 用C++的map和stack構建符號表 如果考慮效率的話,最佳選擇是用C語言構建符號表,這樣操作起來會更快,但我們畢竟目前考慮開發的簡便型而言,用C++的map就可以方便地實現符號表。 首先我們做一個局部符號表,由于其中不會有重復的符號名,所以我們只要簡單的將其存放起來即可。 然后符號表還需要記錄很多類型信息、指針信息等,我們設計一個結構體表示它們: ~~~ enum SymbolType { var_t, type_t, struct_t, enum_t, delegate_t, function_t }; struct id { int level; SymbolType type; void* data; }; ~~~ 我們目前是簡單起見,由于還不知道都可能放哪些東西,例如數組符號,肯定要包含數組長度、維度等信息,各種變量都會包含類型信息,所以我們這里放了一個void*的指針,到時候需要的化,就強制轉換一下。 這里其實定義一個基類,需要存儲的內容去多態派生也是可以的,沒做主要是因為可能存放的東西類型很多,暫時先用一個void*,這樣可能方便一點。 于是我們的局部符號表就有了: ~~~ class IDMap { public: IDMap(); ~IDMap(); id* find(string& str) const; // 查找一個符號 void insert(string& str, int level, SymbolType type, void* data); // 插入一個符號 private: map<string,id*> ID_map; }; ~~~ 我想查找和插入都是C++中map的基礎函數,大家應該很輕松就能實現吧。 再弄一個棧來存儲一個IDMap: ~~~ class IDTable { public: IDTable(); id* find(string& str) const; void insert(string& str,SymbolType type, void* data); void push(); // 壓棧和彈棧操作,例如在函數的解析時,需要壓棧,一個函數解析完,就彈棧 void pop(); int getLevel(); // 獲取當前的層級,如果為0,則說明是只有全局符號了 private: deque<IDMap> ID_stack; }; ~~~ 這里用deque而沒用stack的原因是,deque支持隨機訪問,而stack只能訪問棧頂。 尋找時,就按照從棧頂到棧底的順序依次尋找符號: ~~~ id* IDTable::find(string& idname) const { for (auto p = ID_stack.rbegin(); p != ID_stack.rend(); ++p) { const IDMap& imap = *p; id* pid = imap.find(idname); if (pid != NULL) return pid; } return NULL; } ~~~ 插入時,就往棧頂,當前最新的符號表里面插入: ~~~ void IDTable::insert(string& str,SymbolType type, void* data) { IDMap& imap = ID_stack.back(); imap.insert(str,getLevel(), type, data); } ~~~ 這樣,一款簡易的棧式符號表就構建好了。 ### 附1:Github參考源碼 [idmap.h](https://github.com/sunxfancy/RedApple/blob/master/src/idmap.h) [idmap.cpp](https://github.com/sunxfancy/RedApple/blob/master/src/idmap.cpp) [idtable.h](https://github.com/sunxfancy/RedApple/blob/master/src/idtable.h) [idtable.cpp](https://github.com/sunxfancy/RedApple/blob/master/src/idtable.cpp) ### 附2:Graphviz的繪圖源碼 Graphviz繪圖真的非常爽,上面的數據結構圖就是用它的dot畫的,想了解的朋友可以參考我之前寫的 [結構化圖形繪制利器Graphviz](http://blog.csdn.net/xfxyy_sxfancy/article/details/49641825): ~~~ digraph g { graph [ rankdir = "LR" ]; node [ fontsize = "16" shape = "ellipse" ]; edge [ ]; "node0" [ label = "<f0> stack | <f1> | <f2> | ..." shape = "record" ]; "node1" [ label = "<f0> 全局符號 | a | work | | ..." shape = "record" ] "node2" [ label = "<f0> 局部符號 | a | | ..." shape = "record" ] "node0":f1 -> "node1":f0 [ id = 0 ]; "node0":f2 -> "node2":f0 [ id = 1 ]; } ~~~
                  <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>

                              哎呀哎呀视频在线观看