cdecl

/* 理解所有分析过程的代码段*/
/*
 *这是一个小型程序,在过去的几年中已经被编写过无数次,The C Programming Language 有一个cdecl不完整的版本,本书的cdecl程序则更为详尽。它支持类型限定符const和volatile。同时它还涉及结构、枚举和联合,尽管在这方面作了简化。你可以很轻松地用这个版本的程序来处理函数中的参数声明。这个程序可以用大哟150行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]; }; 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 QUALIFIER; } if(!strcmp(s,"volatile")) return QUALIFIER; if(!strcmp(s,"void")) return QUALIFIER; 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; /*略过空白字符*/ while((*p = getchar()) == ' '); if(isalnum(*p)) { /*读入的标示符以A-Z,0-9开头*/ 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",atof(this.string)-1); gettoken();/*读取']'*/ } gettoken();/*读取']'之后的再一个标记*/ printf("of "); } } deal_with_function_args() { while(this.type!=')') { gettoken(); } gettoken(); printf("function returning "); } deal_with_poirters() { 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_poirters(); /*处理在读入到标识符之前压入到堆栈中的符号*/ while(top>=0) { if(stack[top].type == '(') { pop; gettoken();/*读取 ')'之后的符号*/ deal_with_declarator(); } else { printf("%s ",pop.string); } } } main() { /*将标记压入堆栈中,直到遇见标示符*/ read_to_first_identifer(); deal_with_declarator(); printf("/n"); return 0; }  

你可能感兴趣的:(function,struct,String,Arrays,token,returning)