清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.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 #define STRCMP(a,R,b) (strcmp(a,b) R 0) /*推断标识符类型*/ 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 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,==,"double")) return TYPE; if (STRCMP(s,==,"float")) return TYPE; if (STRCMP(s,==,"struct")) return TYPE; if (STRCMP(s,==,"union")) return TYPE; if (STRCMP(s,==,"enum")) return TYPE; return IDENTIFIER; } /*读取下一个标记到"this" *可能读入的字符包括:字母、数字、*[]() */ void gettoken(void) { char *p = this.string; /*略过空白字符*/ while((*p = (char)getchar()) == ' ') ; /*是字母或数字*/ if (isalnum(*p)) { while(isalnum(*++p = (char)getchar())) ; /*读到下一个不是字母或数字为止*/ ungetc(*p,stdin); /*将一个字符回退到输入流*/ *p = ''; this.type = (char)classify_string(); return; } if (*p == '*') { strcpy(this.string,"pointer to"); this.type = '*'; return; } this.string[1] = ''; this.type = *p; return; } /*理解所有分析过程的代码段*/ int read_to_first_identifier(void) { gettoken(); /*取第一个标记*/ while(this.type != (char)IDENTIFIER) /* 取到标识符终止,标识符未压入栈 */ { push(this); gettoken(); } printf("%s is ",this.string); gettoken();/*再取标识符右边一个符号*/ return 0; } int 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 0; } int deal_with_function_args(void) { while(this.type != ')') /* 把函数参数取出来丢弃 */ { gettoken(); } gettoken(); /* 读取')'后的下一个标记 */ printf("function returning "); return 0; } int deal_with_pointers(void) { while(stack[top].type == '*') { printf("%s ",pop.string); } return 0; } int deal_with_declarator(void) { /*处理标识符后可能存在的数组或函数*/ switch(this.type) { case '[' : deal_with_arrays();break; case '(' : deal_with_function_args();break; default : break; } deal_with_pointers(); /* 栈顶元素是'*' */ /*处理在读到标识符之前压入堆栈的符号*/ while(top >= 0) { if (stack[top].type == '(') { pop; gettoken(); /* 读取')'之后的符号,可能是'('或'[' */ deal_with_declarator(); /* 递归调用 */ } else { printf("%s ",pop.string); } } return 0; } int main(void) { /*将标记压入堆栈中,直到遇见标识符*/ read_to_first_identifier(); deal_with_declarator(); printf("n"); return 0; }