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;
}