当前位置: 首页 > 工具软件 > UCC > 使用案例 >

UCC编译器学习笔记11

邬良才
2023-12-01

语义检查就是建立成最完善的类型系统,这些类型是我们能读懂的信息了。

而被声明的标识符的类型信息正好是分布在 DeclarationSpecifiers 和 Declarator 中,通过调用第 29 或 46 行的 DeriveType函数,会把这两部分的类型信息组合到一起,构造完整的类型信息。例如,对于 int arr[4]来说,int 是其声明说明符,而 arr[4]是声明符,只有把 int 和[4]组合到一起,我们才能得到arr 的类型信息为 int [4]。

/***********************************************

    categ:  category    CHAR,UCHAR,SHORT, ...

    qual:   type qualifier, CONST, VOLATILE

    align:  type alignment

    size:   type size

    bty:        for primary type        bty  is NULL

            for derived type        not NULL,  fg, POINTERFUNCTIONARRAY等类型,...,确实是这样的

                                (1)const int is treated as derived type ?

                                (qual != 0 && bty == T(INT)) ?

                                (2) ENUM,  see function Enum(char *id)

            bty stands for base type ?                              

 ***********************************************/

#define TYPE_COMMON \   //表示公有的类型,就是各种类型,都需要有这个成员的

    int categ : 8;  \

    int qual  : 8;  \   //constant还是volatile

    int align : 16; \

    int size;       \

    struct type *bty;   //如果有第二类型属性,该指针指向那个类型。如果是函数类型,则这个是返回值的类型

                        //最重要的,如果是指针变量,指针本身是int型,但是bty这个域就是指向的那个类型

typedef struct type

{

    TYPE_COMMON

} *Type;

typedef struct typeDerivList //这个就是上面的类型bty要指向的东西

{

    int ctor;       // type constructor     pointer/function/array

    union

    {

        int len;    // array size

        int qual;   // pointer qualifier

        Signature sig;  // function signature

    };

    struct typeDerivList *next;

} *TypeDerivList;

有些错误在语法阶段是不好检查的,因为语法检查是严格按照文法来的(所以语法分析阶段就暂时先建立出语法树而已),而文法中有时候表示一些约束,是很难表示的。因此,在语义分析阶段就能检测出来,比如定义变量,static属于存储类型说明符,这个只能出现一次,可是文法阶段是很难表述这个的(因为上下文无关文法表示能力有限,可能得用2型文法:上下文有关文法才能表达这个约束性质),因为就推迟到语义分析阶段,检测出来:
 

    tok = (AstToken)specs->stgClasses;

    if (tok)

    {

        if (tok->next)

        {

            Error(&specs->coord, "At most one storage class");

        }

        specs->sclass = tok->token;

    }

 类似资料: