在
c語言裡,有一種語句叫做復合語句。它是由
把一些語句括起來的,如下面的例子:
在lcc
裡處理這樣的復合語句的函式是
compound
,它在上面函式定義函式
funcdefn
是這樣呼叫的:
#150labels = table(null, labels);
#151stmtlabs = table(null, labels);
#152refinc = 1.0;
#153regcount = 0;
#154codelist = &codehead;
#155codelist->next = null;
#156
#157if (!ir->wants_callb && isstruct(rty))
#158 retv = genident(auto, ptr(unqual(rty)), param);
#159
上面的**是準備生成**。
#160//
分析函式定義裡的復合語句。
#161compound(0, null, 0); 在第
161行裡就是呼叫
compound
函式,第乙個引數設定為
0,第二個引數也是設定為空
null
,第三個引數是
0。那麼
compound
又是怎麼樣去分析復合語句,以及生成什麼樣的中間表示,以便後面生成彙編**的呢?帶著這幾個疑問去看它的**,就很容易理解了。
它的**如下:
#001//
復合語句分析函式。
#002void compound(int loop, struct swtch *swp, int lev)
#003
#030 第
20行是測試是否復合語句的開始。 第
22行到第
29行是處理函式返回值。
#031//
區域性變數宣告處理.
#032while (kind[t] == char || kind[t] == static
#033 || istypename(t, tsym) && getchr() != ':')
#034
#037 第
32行到第
36行就是處理復合語句裡所有區域性變數的宣告,區域性變數的宣告跟前面分析全域性變數的宣告是差不多的,不過它是呼叫函式
dcllocal
來處理區域性變數的。這裡也是遞迴地呼叫
decl
來處理宣告。後面再仔細地分析區域性變數的宣告。
#038//
#039
#047
上面**是處理自動型別和暫存器型別的區域性變數的。
#048
#049if (events.blockentry)
#051
上面處理定義了事件響應處理。
#052while (kind[t] == if || kind[t] == id)
#053
#056
上面**是呼叫語句分析函式
statement
來處理,當然它也遞迴呼叫的。
#057walk(null, 0, 0);
#058
#059foreach(identifiers, level, checkref, null);
#060
#069}
#070 第
57行復位所有使用全部變數。 第
59行到第
69行是統計變數的引用計數。
#071if (level == local)
#072
#084 else
#085 retcode(null);
#086 }
#087}
#088 第
71行處理區域性函式返回值,如果在第
77行裡**的型別不是跳轉,就需生成返回**。
#089if (events.blockexit)
#091
#092cp->u.block.level = level;
#093cp->u.block.identifiers = identifiers;
#094cp->u.block.types = types;
#095
#096code(blockend)->u.begin = cp;
#097
#098if (reachable(gen))
#099 definept(null);
#100
#101if (level > local)
#102');
#105}
#106}
上面儲存復合語句的**屬性,就處理完成了復合語句。
這樣就可以把復合語句分析完成,下一次再去仔細地分析在復合語句實現區域性變數和簡單語句的分析。
LCC編譯器的源程式分析 12 13
語法分析是比較複雜的處理,下面再來分析乙個例子,它的 如下 typedef unsigned short wchar t typedef wchar t wint t 第一句語句在lcc裡的處理,前面已經解釋清楚,主要生成wchar t儲存符號表裡,並且記錄這個id的型別屬性。那麼第二句是怎麼樣通過...
LCC編譯器的源程式分析 18 19
lcc編譯器的源程式分析 19 全域性函式的定義 函式定義funcdefn處理裡,已經準備好呼叫引數和引數返回,接著就是呼叫全域性函式宣告來處理。如下面的 132 宣告函式。133 cfunc dclglobal sclass,id,ty,pt 134 上面的 是處理函式全域性定義。現在就去就分析d...
LCC編譯器的源程式分析 37 default語句
default 語句是使用在 switch 語句的復合語句裡,它是所有其它分支不能處理時的分支處理。在 lcc裡是如下處理的 001case default 002 if swp null 003 error illegal default label n 004 else if swp defla...