您的位置:首页 > 编程语言 > C语言/C++

cdecl程序,用于分析C语言的声明

2010-04-04 10:59 387 查看
#include <stdio.h>

#include <ctype.h>

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

#define STRCMP(a, R, b) (strcmp(a, b) R 0)
#define MAXTOKENS 100
#define MAXTOKENLEN 64

enum type_tag{ Identifer, Qualifier, Type };

struct token
{
char type;
char string[MAXTOKENLEN];
};
struct token stack[MAXTOKENS];
struct token this;
int top = -1;

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

void Read_to_first_identifer(void);
enum type_tag Classify_str(void); /*推断标识符的类型*/
void Gettoken(void);/*读取下一个标记到this*/
void Deal_with_declarator(void);
void Deal_with_arrays(void);
void Deal_with_function_args(void);
void Deal_with_pointers(void);
void Deal_wirh_declarator(void);

int main(void)
{
char next = 0;
printf("输入一个C语言声明,cdecl程序会把声明转化成通俗文字:/n");
do{
/*将标记压入堆栈,直至遇到标识符*/
Read_to_first_identifer();
Deal_with_declarator();
printf("/n是否进行下一个声明的推断(y//n)?");
}while('Y' == toupper( next = getchar() ));
return 0;
}

void Read_to_first_identifer(void)
{
Gettoken();
while(Identifer != this.type)
{
push(this);
Gettoken();
}
printf("%s is ", this.string);
Gettoken();
return;
}

void Gettoken(void)
{
char *p = this.string;

while( ' ' == (*p = getchar()) );/*忽略空格*/

if(isalnum(*p))/*A~z,0~9*/
{
while(isalnum( *++p = getchar() ));
ungetc(*p, stdin);
*p = '/0';
this.type = Classify_str();
return;
}

if('*' == *p)
{
strcpy(this.string, "pointer to");
this.type = '*';
return;
}
this.string[1] = '/0';
this.type = *p;
return;
}

enum type_tag Classify_str(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, ==, "int")) return Type;
if(STRCMP(s, ==, "long")) return Type;
if(STRCMP(s, ==, "float")) return Type;
if(STRCMP(s, ==, "double")) return Type;
if(STRCMP(s, ==, "signed")) return Type;
if(STRCMP(s, ==, "unsigned")) return Type;
if(STRCMP(s, ==, "struct")) return Type;
if(STRCMP(s, ==, "union")) return Type;
if(STRCMP(s, ==, "enum")) return Type;
return Identifer;
}

void Deal_with_declarator(void)
{
/*处理标识符之后可能存在的函数或数组*/
switch(this.type)
{
case '[': Deal_with_arrays(); break;
case '(': Deal_with_function_args(); break;
default: break;
}

Deal_with_pointers();

/*处理在读入标识符之前压入堆栈的符号*/
while(-1 < top)
{
if('(' == stack[top].type)
{
pop;
Gettoken();
Deal_with_declarator();
}
else
printf("%s ", pop.string);
}
return;
}

void Deal_with_arrays(void)
{
while('[' == this.type)
{
printf("array ");
Gettoken();/*数字或']'*/
if(isdigit(this.string[0]))
{
printf("0..%d ", atoi(this.string)-1);
Gettoken();/*读取']'*/
}
Gettoken();/*读取']'之后的再一个标记*/
printf("of ");
}
return;
}

void Deal_with_function_args(void)
{
while(')' != this.type)
Gettoken();
Gettoken();
printf("function returning ");
return;
}

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

farsight@farsight-ubuntu:~/chendan/link$ ./cdecl
输入一个C语言声明,cdecl程序会把声明转化成通俗文字:
int *p
p is pointer to int
是否进行下一个声明的推断(y/n)?y
char *const *(*next)()
next is pointer to function returning pointer to read-only pointer to char
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: