将C语言的声明描述成为语言

/*
	本程序是将C语言的声明描述成为语言
	
*/

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

#define MAXTOKENS 100
#define MAXTOKENLEN 64

//声明枚举变量,当一个变量确定有几个变化的值,用枚举作为变量合适
enum type_tag {IDENTIFIER,QUALIFIER,TYPE};

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

struct token stack[MAXTOKENS];//声明堆栈
struct token temp;//声明temp结构体变量

int top = -1;

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

//对读取到的标记字符串的类型做出判断,利用枚举类型作为返回值
enum type_tag classify_string(void){
	
	char *s = temp.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;

}

//读取每个标记存到temp变量中
void gettoken(void){
	
	char *p = temp.string;

	//如果有空白字符,则忽略
	while((*p = getchar()) == ' ');//注意没有循环体

	if(isalnum(*p)){//如果读入的是字母或数字
		while(isalnum(*++p = getchar()));//判断下一个是否还是,如果是,继续读取
		ungetc(*p,stdin);//该句是将读到的字符会退到输入流中,即上一步中while读到的不满足的字符回退。
		*p = '\0';
		temp.type = classify_string();//对该字符串判断其标记类型
		return;
	}

	if(*p == '*'){
		strcpy(temp.string," pointer to");
		temp.type = '*';
		return;
	}

	//如果是其他的字符,则读取该字符
	temp.string[1] = '\0';
	temp.type = *p;
	return;
}

//读第一个标示符
void read_to_first_identifier(){
	gettoken();
	while(temp.type != IDENTIFIER ){
		push(temp);
		gettoken();
	}
	printf("%s is",temp.string);
	gettoken();//读取标示符后面的字符
}

void deal_with_arrays(){
	while(temp.type == '['){
		printf(" array ");
		gettoken();//数字或者]
		if(isdigit(temp.string[0])){
			printf("0..%d ",atoi(temp.string)-1);//atoi:计算字符串的长度
			gettoken();//读取']'
		}
		gettoken();//读取']'后的下一个字符
		printf("of ");
	}
}

void deal_with_function_args(){
	while(temp.type != ')'){
		gettoken();
	}
	gettoken();
	printf("function returning ");
}

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

void deal_with_declarator(){
	//处理标示符后面可能的数组或者函数
	switch(temp.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();
	printf("\n");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值