語法分析是比較複雜的處理,下面再來分析乙個例子,它的**如下:
typedef unsigned short wchar_t;
typedef wchar_t wint_t;
第一句語句在
lcc裡的處理,前面已經解釋清楚,主要生成
wchar_t
儲存符號表裡,並且記錄這個
id的型別屬性。
那麼第二句是怎麼樣通過上面的函式來分析的呢?接下來就去分析
c編譯器怎麼處理它。
與第一句語句一樣,先識別
typedef
出來,接著就調函式
decl(dclglobal)
,然後呼叫函式
specifier
來處理。在函式
specifier裡:
#001 //說明
#002 static type specifier(int *sclass)
#003
#101 assert(cp == rcp);
#102 token = (char *)rcp - 1;
#103 while (map[*rcp]&(digit|letter))
#104 rcp++;
#105 token = stringn(token, (char *)rcp - token);
#106 tsym = lookup(token, identifiers);
#107 cp = rcp;
#108 return id; 在第
96行到第
99行是重新填充字元緩衝區,以便識別完整的變數
id出來。 在第
102行到第
105行裡,就獲取
id的字串,並儲存到
token裡。
在第106
行裡查詢這個
id是否已經宣告,如果沒有宣告返回是空指令給
tsym。
在第108
行裡返回
id這個記號來標識當前已經識別出乙個
id了。
再仔細地看一下第
106行,它通過函式
lookup
到符號表
identifiers
查詢當前的
id是否已經宣告,如果已經宣告就返回給
tsym
儲存。由於語句(
typedef wchar_t wint_t;
)中的wchar_t
在前面已經宣告,那麼這裡的
tsym
肯定就是返回它了,這樣就得到了
wchar_t
的型別屬性了。有了型別屬性,在函式
specifier
的處理**如下:
#079 case id:
#080 if (istypename(t, tsym) && type == 0
#081 && sign == 0 && size == 0)
#082
#098
#099 p = &type;
#100 t = gettok();
#101 }
#102 else
#103
#106 break;
由於在詞法分析函式
gettok()
獲取到了
tsym
,也就是已經宣告的型別
wchar_t
,所以在第
80行和第
81行判斷它是型別,而不是變數
id了,就進入第
83行裡面處理,並在第
84行儲存當前的型別
ty,也就是
wchar_t
宣告的型別。再獲取下乙個記號,它是
wint_t
,接著的處理就跟其它宣告處理是一樣的了,在
specifier
返回型別,在
decl
函式裡儲存到符號表
identifiers。
現在再來總結一下處理語句(
typedef wchar_t wint_t;
),先識別
typedef
,接著通過詞法分析裡查詢符號表可以知道
wchar_t
已經宣告為型別,接著就可以儲存
wint_t
到符號表,它的型別就是
wchar_t
所宣告的型別。
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編譯器的源程式分析 20 復合語句
在 c語言裡,有一種語句叫做復合語句。它是由 把一些語句括起來的,如下面的例子 在lcc 裡處理這樣的復合語句的函式是 compound 它在上面函式定義函式 funcdefn 是這樣呼叫的 150labels table null,labels 151stmtlabs table null,lab...