typedef int a;        //a是TypedefNames,作用域為all the scope
//overload:表示在嵌套作用域中,類型定義名是否作為變量,而不是類型名
int f(char a)    //由于之前a已經(jīng)是typedef了,所以這里標記為overload, 
//那么在函數(shù)f的作用域中只能作為變量,而不是類型名,那么下面用a作為類型來定義變量都是語法錯誤
{
    
//語法分析時typedef是聲明,a已經(jīng)被聲明為char了,所以這里報告a重聲明了
    
//typedef char a;        
    printf("%c", a);
    
return 0;
}

int main()
{
    typedef 
char* a;    //在mian的作用域里面,a就是char *類型了
    a x = (void*)0;
    printf(
"Hello, World %c\n");
    
return 0;
}

引用ucc的文檔:
在大多數(shù)情況下,C語言是一個LL(0)文法,解析器可以根據(jù)當前的記號而決定與什么產(chǎn)生式和非終結(jié)符匹配。但是由于C語言引入了類型定義而破壞了這個特性。比如說在復合語句中遇到一個標識符,如果是類型定義名,則應該為聲明,否則為語句。為了簡潔性,ucc將語法分析和語義檢查分成兩個獨立的階段,但是類型定義又要求在語法分析中做一定的語義檢查,為此,ucc在語法分析中對于類型定義做最小的檢查。對于語法分析器來說,只要知道一個標識符是類型定義名就足夠了,而不需要知道具體的類型。
語法分析中用以進行語義檢查的數(shù)據(jù)結(jié)構(gòu)和算法如下:
typedef struct tdname
{
    char *id;
    int level;
    int overload;
} *TDName;
tdname表示一個類型定義名。
 id: 名字
 level: 類型定義名被定義點的嵌套層次,文件作用域的嵌套層次為0,復合語句的起始處嵌套層次加1,復合語句的結(jié)束處嵌套層次減1。有可能在多個作用域中定義同一個類型定義名,level表示這些作用域中嵌套層次最小的。比如說對于如下代碼片段:
typedef int a;
int f(void)
{
     typedef int a;
}
其中l(wèi)evel值應為0。這樣在其它函數(shù)中a的定義也是可見的。
overload:表示在嵌套作用域中,類型定義名是否作為變量,而不是類型名。比如如下代碼片段:
typedef int a;
int f(int a)
{
}
在f的函數(shù)定義中,a是參數(shù),而不是類型定義名。
ucc使用兩個向量:TypedefNames記錄了所有定義的類型名。OverloadNames記錄當前作用域中被重載了的類型名。
對于每一個聲明,調(diào)用CheckTypedefName函數(shù),如果該聲明屬于類型定義,則查看相應的類型名是否存在,如果不存在,則加入新的類型定義,如果存在,修改level為最小的嵌套層次。如果該聲明不屬于類型定義并且該聲明所定義的變量已定義為外部作用域的類型名,則標記該類型名被重載,并且將其加入OverloadNames中。
每當一個復合語句結(jié)束時,重置OverloadNames中的所有類型名的重載狀態(tài)。