⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdecl.c

📁 一个复杂的C语言声明该如何读呢?cdecl能够读出所有负责的C语言声明
💻 C
字号:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#define MAXTOKENS   100
#define MAXTOKENLEN 64

enum tokenType{IDENTIFIER, QUALIFILE, TYPE};

struct token 
{
    char type;
    char string[MAXTOKENLEN];
};

int top = -1;
struct token stack[MAXTOKENS];
struct token gToken;

#define pop     stack[top--]
#define push(s) stack[++top] = s
#define STRCMP(a, R, b) (strcmp(a, b) R 0)

/**
 * @brief    判断标识符类型
 * @author   Youlei Yuan
 * @author   youleiy@mobilesoft.com.cn
 * @date     2005/11/17
 * @param    
 * @return   
 */
enum tokenType ClassifyString(void)
{
    char*          s    = gToken.string;
    enum tokenType type = IDENTIFIER;

    if (STRCMP(s, == , "const")) 
    { 
        strcpy(s, "只读");
        type = QUALIFILE; 
    }
    if (STRCMP(s, ==, "volatile")) 
    { 
        type = QUALIFILE;
    }
    if (STRCMP(s, ==, "void")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "char")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "int")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "float")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "double")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "signed")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "unsigned")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "short")) 
    { 
        type = TYPE;
    }    
    if (STRCMP(s, ==, "long")) 
    { 
        type = TYPE;
    }
    if (STRCMP(s, ==, "struct")) 
    { 
        type = TYPE;
    }
    if (STRCMP(s, ==, "union")) 
    { 
        type = TYPE;
    }
    if (STRCMP(s, ==, "enum")) 
    { 
        type = TYPE;
    }

    return type;
};

/**
 * @brief    读取下一个标记到gToken  
 * @author   Youlei Yuan
 * @author   youleiy@mobilesoft.com.cn
 * @date     2005/11/17
 * @param    
 * @return   
 */
void gettoken(void)
{
    char* p = gToken.string;

    // 略过空白
    *p = getchar();
    while (0x20==*p || 0x0d==*p || 0x0a==*p || '\t'==*p) 
    {  
        *p = getchar();
    }

    // 读入的是数字或字母
    if (isalnum(*p)) 
    { 
        while (isalnum(*++p=getchar())) 
        {
            ;
        }
        ungetc(*p, stdin);
        *p = '\0';
        gToken.type = ClassifyString();
        return;
    }

    if ('*' == *p) 
    { 
        strcpy(gToken.string, "指向");
        gToken.type = '*';
        return;
    }

    gToken.string[1] = '\0';
    gToken.type      = *p;
}

/**
 * @brief      
 * @author   Youlei Yuan
 * @author   youleiy@mobilesoft.com.cn
 * @date     2005/11/17
 * @param    
 * @return   
 */
void ReadToFirstIdentifier()
{
    gettoken();
    while (gToken.type != IDENTIFIER) 
    {  
        push(gToken);
        gettoken();
    }
    printf("%s 是一个", gToken.string);
    
    gettoken();
}

/**
 * @brief      
 * @author   Youlei Yuan
 * @author   youleiy@mobilesoft.com.cn
 * @date     2005/11/17
 * @param    
 * @return   
 */
void DealWithArrays(void)
{
    while (gToken.type == '[') 
    {  
        printf("数组");
        gettoken(); // 数组或']'
        if (isdigit(gToken.string[0])) 
        { 
            printf("[0..%d]", atoi(gToken.string)-1);
            gettoken(); // ']'
        }
        gettoken();
        printf("的");
    }
}

void DealWithFunctionArgs() 
{
    while (gToken.type!=')') 
    {
        gettoken();
    }
    gettoken();
    printf("函数返回 ");
}

void DealWithPointers() 
{
    while ( stack[top].type== '*' ) 
    {
        printf("%s ", pop.string );
    }
}

/* deal with possible array/function following identifier */
void DealWithDeclarator() 
{
    switch (gToken.type) 
    {
    case '[' : DealWithArrays(); 
        break;
    case '(' : DealWithFunctionArgs();
        break;
    }
    
    DealWithPointers();
    
    /* process tokens that we stacked while reading
    identifier */
    while (top>=0) 
    {
        if (stack[top].type == '(' ) 
        {
            pop;
            gettoken(); /* read past ')' */
            DealWithDeclarator();
        } 
        else 
        {
            printf("%s ",pop.string);
        }
    }
}

int main()
{
    /* put tokens on stack until we reach identifier*/
    ReadToFirstIdentifier();
    DealWithDeclarator();
    printf("\n");
    
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -