/*
本程序是将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;
}
将C语言的声明描述成为语言
最新推荐文章于 2024-05-02 17:51:30 发布