C专家编程之分析声明语句

最近读了一下C专家编程,这本书讲的比较深入,同时又有一些有趣的小故事,喜欢的朋友看看试试。今天给大家分享里面一个小程序。分析声明语句。直接上代码。

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#define MAXTOKENS 100
#define MAXTOKENLEN 64


enum type_tag {IDENTIFIER , QUALIFER, TYPE};

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

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

#define pop stack[top--]
#define push(s) stack[++top] = s


enum type_tag classify_string(void)
{/* 推断标识符的类型 */

    char *s = This.string;
    if(!strcmp(s, "const"))
    {
        strcpy(s, "read_only");

        return QUALIFER;
    }

    if(!strcmp(s, "volatile")) return QUALIFER;
    if(!strcmp(s, "void"))  return TYPE;
    if(!strcmp(s, "char")) return TYPE;
    if(!strcmp(s, "signed")) return TYPE;
    if(!strcmp(s, "unsigned")) return TYPE;
    if(!strcmp(s, "short"))     return TYPE;
    if(!strcmp(s, "int"))   return TYPE;
    if(!strcmp(s, "long"))  return TYPE;
    if(!strcmp(s, "float")) return TYPE;
    if(!strcmp(s, "double"))    return TYPE;
    if(!strcmp(s, "struct"))    return TYPE;
    if(!strcmp(s, "union")) return TYPE;
    if(!strcmp(s, "enum"))  return TYPE;

    return IDENTIFIER;  //返回标识符类型
}


void gettoken(void) //读取下一个标记到“This”
{
    char *p = This.string;  //指针p指向This的string部分

    while((*p = getchar()) == ' ');//略过空白字符

    if(isalnum(*p))
    {

        while(isalnum(*++p = getchar()));
        ungetc(*p, stdin);      //向标准输入中回退一个字符
        *p = '\0';
        This.type = classify_string();  //判断标记类型

        return;
    }

    if(*p == '*')   //指针类型
    {
        strcpy(This.string, "pointer to");
        This.type = '*';

        return;
    }

    This.string[1] = '\0';  //其他一个字符类型
    This.type = *p;
    return;
}


read_to_first_identifer()   //一直读取到第一个标识符
{
    gettoken();

    while(This.type != IDENTIFIER)  //判断是否为标识符
    {
        push(This);
        gettoken();
    }

    printf("%s is ", This.string);
    gettoken();
}

deal_with_arrays()  //处理数组
{
    while(This.type == '[')
    {
        printf("array ");
        gettoken();
        if(isdigit(This.string[0]))
        {
            printf("0..%d ", atoi(This.string)-1);
            gettoken();
        }

        gettoken();
        printf("of ");
    }
}


deal_with_function_args()   //处理函数
{
    while(This.type != ')')
    {
        gettoken();
    }
    gettoken();
    printf("function returning ");
}


deal_with_pointers()    //处理指针
{
    while(stack[top].type == '*')
    {
        printf("%s ", pop.string);
    }
}

deal_with_declarator()  //处理标识符之后可能存在在数组/函数
{

    switch(This.type)
    {
    case '[' : deal_with_arrays(); break;
    case '(' : deal_with_function_args();
    }

    deal_with_pointers();

    while(top >= 0)
    {
        if(stack[top].type == '(')
        {
            pop;
            gettoken();
            deal_with_declarator();
        }else
        {
            printf("%s ", pop.string);
        }
    }
}

int main(int argc, char *argv[])
{
//    freopen("G:\\in.txt", "r", stdin);

    read_to_first_identifer();
    deal_with_declarator();
    printf("\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/canhelove/article/details/83934350