编写一个程序,把C语言的声明翻译成通俗语言--C专家编程

最近在看C专家编程,有一个编程挑战:编写一个程序,把C语言的声明翻译成通俗语言。很像编译原理中的词法分析部分与语法制导的部分。上个学期虽然自己也敲了编译器的各个环节但是自己写的C语言和书上的相比真的略显稚嫩。书上提供的代码真的很完美的感觉,记录在这里以后也方便品读。。。

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

#define MAXTOKENS 100
#define MAXTOKENLEN 64

//IDENTIFIER标识符,QUALIFIER限定符,TYPE类型
enum type_tag {IDENTIFIER, QUALIFIER, 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 QUALIFIER;
    }
    if(!strcmp(s, "volatile")) return QUALIFIER;
    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)
{
    char *p = this.string;

    //跳过空格
    while((*p = getchar()) == ' ');

    if(isalnum(*p))
    {
        while(isalnum(*++p = getchar()));//判断字符是否时字母或者数字,读入到string数组中
        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;
}
//读取声明直到读到第一个标识符
void read_to_first_identifier()
{
    gettoken();
    while(this.type != IDENTIFIER)
    {
        push(this);
        gettoken();
    }
    printf("%s is ",this.string);
    gettoken();
}

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

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

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

//处理声明器
void 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()
{
    read_to_first_identifier();
    deal_with_declarator();
    putchar('\n');
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值