把c语言中的声明用程序翻译成通俗的语言

理解c语言的优先级规则:

A

 声明从它的名字开始读取,然后按照优先级次序一次读取

B

优先级从高到底依次是:

b1  声明中被括号括起来的那部分

b2 后缀操作符

      括号()表示这是一个函数,而方括号【】表示这是一个数组

b3 前缀操作符,星号*表示“指向。。。的指针”

C

如果const(或volatile)关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符,在其他情况下作用于它左边

紧邻的指针*号。

如  char * const*(*next)();

     上式表示“next是一个指针,它指向一个函数,这个函数返回另外一个指针,该指针指向一个类型为char的常量指针”

这里有一个设计方案,主要的数据结构是一个堆栈,我们从左向右读取,把各个标记依次压入堆栈,知道读到标识符为止,然后我们继续向右读入一个标记,也就是标识符右边的那一个标记,接着观察标识符左边的那个标记(需要从堆栈中弹出)

#include 
#include 
#include 
#include 
#define MAX_LEN 100
enum type_token {IDENTIFIER,QUALIFIER,TYPE};
typedef struct token{
	char string[100];
	char type;
}token;
token tmp_token;
typedef struct stack{
	token array[MAX_LEN];
	int top;
}stack;
struct stack token_stack;
void init(stack *sta)
{
	sta->top=-1;
}
int push(stack *sta,token s)
{
	if(sta->top>=254)
	{
		printf("the stack is full.\n");
		return 1;
	}
	else
	{
		sta->array[++(sta->top)]=s;
	}
	return 0;
}
token pop(stack *sta)
{
	if(sta->top==-1)
	{
		printf("ERROR,the stack is empty!\n");
	}
	else
	{
		return sta->array[(sta->top)--];
	}
	
}
int stack_empty(const stack s)
{
	if(s.top==-1)
		return 0;
	else
		return 1;
}
token top_stack(const stack s)
{
	if(stack_empty(s)==0)
	{
		printf("ERROR the stack is empty!\n");
	}
	else
		return s.array[s.top];
}
enum type_token classify_string();
void gettoken()
{//读取token函数,如果是字母,数字,下划线就一直读取,否则就停止存入tmp_token中处理
	memset(tmp_token.string,'\0',sizeof(tmp_token.string));//先把tmp_token清空
	char *p=tmp_token.string;
	while((*p=getchar())==' ');//略过空白字符
	if(isalnum(*p) || *p=='_'){
		//读入的标志符要是字母,数字或者下划线,表示是标志符
		while(1)
		{
			*(++p)=getchar();
			if(isalnum(*p) || *p=='_')
				continue;
			else
				break;
		}
		ungetc(*p,stdin);//把非满足的字符放回缓冲区,下次再用
		*p='\0';
		tmp_token.type=classify_string();
		return;
	}
	if(*p=='*'){
		strcpy(tmp_token.string,"pointer to ");
		tmp_token.type='*';
		return;
	}
	tmp_token.string[1]='\0';
	tmp_token.type=*p;
	return;
}
enum type_token classify_string()
{//推断标志符的类型
	char *s=tmp_token.string;
	if(!strcmp(s,"const")){
		strcpy(s,"read-only ");
		return QUALIFIER;
	}
	if(!strcmp(s,"volatile")) return QUALIFIER;
	if(!strcmp(s,"extern")) 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 read_first_identifier(){
	gettoken();
	while(tmp_token.type!=IDENTIFIER){
		push(&token_stack,tmp_token);
		gettoken();
	}
	printf("%s is ",tmp_token.string);
	gettoken();
}
void deal_with_array()
{
	while(tmp_token.type=='[')
	{
		printf("array");
		gettoken();
		if(isdigit(tmp_token.string[0]))
		{
			printf(" 0..%d ",atoi(tmp_token.string)-1);
			gettoken();
		}
		gettoken();//读取‘】’之后的token
		printf("of ");
	}
}
void deal_with_function()
{
	while(tmp_token.type != ')')
		gettoken();
	gettoken();
	printf(" function returning ");
}
void deal_with_pointer()
{
	token t;
	t=top_stack(token_stack);
	while(t.type=='*')
	{
		printf("%s",t.string);
		pop(&token_stack);
		t=top_stack(token_stack);
	}
}
void deal_with_declarator(){//递归处理的过程
	switch(tmp_token.type){
	case '[': deal_with_array();break;
	case '(': deal_with_function();
	}
	deal_with_pointer();
	while(stack_empty(token_stack)==1)
	{
		token t=top_stack(token_stack);
		if(t.type=='('){
			pop(&token_stack);
			gettoken();//读取‘)’之后的符号
			deal_with_declarator();
		}
		else
		{
			printf("%s",pop(&token_stack).string);
		}
	}
}



int main()
{
	init(&token_stack);
    read_first_identifier();
	deal_with_declarator();
	printf("\n");
	return 0;
}

你可能感兴趣的:(把c语言中的声明用程序翻译成通俗的语言)