函式裡的引數變數個數不固定,因此也需要檢查這些引數的名稱是否相同,還需要檢查型別的合法性。現在就來分析上次提到的函式
dclparam
,它的**如下:
#001 //
引數型別宣告處理
#002 static symbol dclparam(int sclass, char *id, type ty, coordinate *pos)
#003
#019 else if (isvolatile(ty) || isstruct(ty))
#020
#025 第
11行到第
24行都是判斷儲存型別。如果沒有宣告儲存型別,預設為
auto
型別。其它幾個識別為暫存器型別
register
、不可刪除屬性、結構型別。
#026 p = lookup(id, identifiers);
#027 if (p && p->scope == level)
#028 error("duplicate declaration for `%s' previously declared at %w/n", id, &p->src);
#029 else
#030 p = install(id, &identifiers, level, func);
#031 第
26行是查詢這個引數變數是否已經在其它地方宣告過,如果宣告過就從
lookup
返回給p
,如果作用域一樣的宣告肯定就是重複宣告,這是出錯的,在第
28行裡提示出錯資訊。如果沒有這個引數變數是合法的,就把它儲存到宣告**
identifiers裡。
#032 p->sclass = sclass;
#033 p->src = *pos;
#034 p->type = ty;
#035 p->defined = 1;
#036
上面幾行是儲存引數的屬性到
p符號裡。
#037 if (t == '=')
#038
#043
由於在標準
c裡是不允許引數變數初始化的,所以在第
37行就處理這樣的出錯,如果在
c++裡應是允許的。
#044 return p;
#045 } 在第
44行裡就是返回分析出來的乙個引數變數返回新增到引數列表裡。
到這裡就把所有的函式宣告分析完成了,把
hello.i
檔案裡的宣告已經分析大部份,自定義型別、指標型別、結構型別、函式宣告等部分,下面就開始進入到
main
函式的分析了,這次分析到這裡,下次再會。
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...