1.類型的表示
C語言的類型是相當靈活的,除了標准的類型(int char float double long 等等)外,自己根據需求,能定義出無窮的類型。一個具體的例子:
int * a[10];
它表示的意思是:
a is ARRAY 0..9 of POINTER to INT
仔細觀察它的意思,就會發現,這個類型是其他基本類型按照一定順序的組合:ARRAY|POINTER|INT。要表示這種形式,鏈表是最合適不過的了。如下圖:
(圖2.1類型的表示)
還有一些情況,比如結構體類型,那么上述的表示就不大合適了。例如下面的結構體:
struct _a{
int n;
char * p[10];
};
結構中的每個域分別是由一個個的類型組成的。那么,我們可以用一個類型鏈表組成。具體就是:
_a is STRUCT of
n: INT
p: ARRAY 0..9 of POINTER to INT
如下圖所示:
(圖2.2結構體的表示)
程序中的類型定義如下:
typedef struct type_t ttype_t;
typedef struct type_t * ptype_t;
typedef struct type_list_t ttype_list_t;
typedef struct type_list_t * ptype_list_t;
struct type_t{
int bty;
int size;
ptype_t ty;
ptype_list_t sty;
char * name;
char * tag;
char * pos;
};
struct type_list_t{
ptype_t ty;
ptype_list_t next;
};
2.類型解析
定義一個類型,我們可以把它分成三個部分:
specifier + id + dclor
對應到一個具體的定義:int * p[10]; 這三部分分別是:
specifier int *
id p
dclor [10]
類型的解析過程是這樣的,首先找到id,然后根據一個規則(向右再向左),依次解析出這個類型:
(圖2.3類型的解析過程)
在第2步,有幾種情況:
a. [ 表示數組,如果遇到[ 則進入解析數組函數
b. ( 表示函數,如果遇到( 則進入解析參數列表函數
所以我們的解析函數是這樣的:
void dclor( ptype_t ty ){
switch( *token ){
case ALY: dcl_arrays(ty); break;
case '(': ty->pos = prog; dcl_args(ty); break;
}
dcl_pointers(ty);
while(tok_top >= 0){
if( *tok_stack[tok_top].token == '(' ){ //左邊是( 繼續向右解析
token_pop();
get_token();
dclor(ty);
}
else{
struct token_node node;
node = token_pop();
if( strcmp( node.token, "splitor" ) == 0 ){
//結束
break;
}
if( node.ty != NULL ){
sbt.ty = node.ty;
}
dcl_specifier( node.tok, NULL );
}
}
}
對於類型的解析,我這里推薦下《C專家編程》中的類型解釋部分,里面講解得更加透徹。