程序实现分析C语言的声明语句含义
2012-11-30 16:41
260 查看
本程序参考了《C专家编程》一书中第3章“分析C语言的声明”中图3-1(65页)以及71页、72页的伪代码实现。程序能完成基本分析功能。如有问题,欢迎给我留言讨论。
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXTOKENLEN 20 #define STACKLEN 20 #define STRINGSIZE 20 #define QUALIFIER 'q' #define IDENTIFIER 'i' #define TYPE 't' /** **函数实现:通过程序分析C语言中的声明,尤其是函数、数组、指针等混在一起的复杂形式 **比如:int ( * fun ( ) ) ( ) ; 或者 char * const * ( * next ) ( ) ; 等 */ /** **其中,读入的符号分为三种类型:类型符,如int等;限定符,如*,const,volatile等;标识符,就是名字字符串。 **第一步:我们自左向右读取,将所有标记压入堆栈,直到标识符为止。 **第二步:读入标识符右边的符号。如果是方括号,将[可能的大小]读完,输出“……的数组”; **第三步:如果是左括号,将(可能的参数)读完,即直到右括号为止,输出“返回……的函数”。 **第四步:如果左边的符号(堆栈中的那个符号)是一个左括号,一直读,直到遇见对应的右括号,然后跳到第二步; **第五步:如果左边的符号是const,volatile,*之一:如果是const,输出”只读“;如果是volatile,输出”volatile“; **如果是*,输出”指向……的指针“。继续向左边读(即出栈),直到所读符号不再是三者之一,然后重复第四步。 **第六步:将堆栈中剩下的符号形成声明的基本类型。 */ struct token { char type; //符号的类型 char string[STRINGSIZE]; //符号名字 }; struct token stack[STACKLEN]; //符号堆栈 struct token present; //用来保存刚刚读入那个符号 int top = -1; //指向栈顶元素 /**对读入的token进行分类,包括标识符identifier、类型type和限定符qualifier*/ char token_classify(char *string) { if(strcmp(string,"const") == 0 || strcmp(string,"volatile") == 0 || strcmp(string,"*") == 0) //如果是限定符 return QUALIFIER; else if(strcmp(string,"int") == 0 || strcmp(string,"long") == 0 || strcmp(string,"short") == 0 || strcmp(string,"double") == 0 || strcmp(string,"unsigned") == 0 || strcmp(string,"float") == 0 || strcmp(string,"char") == 0 || strcmp(string,"enum") == 0 || strcmp(string,"union") == 0 || strcmp(string,"struct") == 0 || strcmp(string,"void") == 0) //如果是类型符 return TYPE; else if(strcmp(string,"(") == 0 || strcmp(string,")") == 0) //对于'('和')'单独处理 return ' '; else //排除其他情况后,剩余标识符 return IDENTIFIER; } /**读入下一个字符或字符串,并调用分类函数进行分类处理*/ void get_token() { char *p = present.string; ////读入后暂存在present当前符号变量中,指针指向present.string while((*p = getchar()) == ' '); //跳过空格 if(isalnum(*p)) //如果是字母或数字 { while(isalnum(*p)) { *++p = getchar(); } ungetc(*p,stdin); //退回非字母或数字的那个符号,用于下次读入 } else { p++; //如果是其他符号,比如'('')''*'直接读入 } *p = '\0'; //加上字符串结束标志 present.type = token_classify(present.string); //分类 } /**读至标识符,从左至用入栈,并显示标识符内容,第一步*/ void read_to_first_identifier() { get_token(); while(present.type != IDENTIFIER) //如果没读到标识符,将之前左边的符号全部入栈 { top++; stack[top] = present; get_token(); } printf("标识符是%s,",present.string); //输出标识符名字 get_token(); } /**处理数组,第二步*/ void deal_with_arrays() { while(present.string[0] != ']') //如果还没读到匹配的']',继续读,这样就将数组大小读入并忽略了 get_token(); printf("数组,该数组类型是"); //读到后输出它是一个数组 get_token(); } /**处理函数,第三步*/ void deal_with_functions() { while(strcmp(present.string,")") != 0) //如果还没读到匹配的')',继续读,这样就将函数的参数都读入并忽略了 get_token(); printf("函数,该函数返回"); //读到后输出它是一个函数 get_token(); } /**处理限定符,第五步*/ void deal_with_qualifiers(char *string) //限定符有三类,根据名字分别处理 { if(strcmp(string,"const") == 0) //输出只读 printf("只读"); else if(strcmp(string,"*") == 0) //输出它是一个指针 printf("指针,这个指针指向"); else printf("volatile"); //输出volatile } /**处理声明器,第二步,第三步,第四步,第五步,第六步*/ void deal_with_all() { struct token temp; //第2步 step2: if(strcmp(present.string,"[") == 0) //标识符右边,如果是'[',作为数组处理 deal_with_arrays(); //第3步 else if(strcmp(present.string,"(") == 0) //标识符右边,如果是'(',作为函数处理 deal_with_functions(); //第4步 step4: temp = stack[top--]; //取栈顶元素,即标识符左边符号 if(strcmp(temp.string,"(") == 0) //如果是'(',读到标识符右边')'为止 { while(strcmp(present.string,")") != 0) get_token(); get_token(); goto step2; //跳到第2步 } //第5步 else if(temp.type == QUALIFIER) //如果标识符左边符号是三个限定符之一 { deal_with_qualifiers(temp.string); //输出限定符代表的输出 while(stack[top].type == QUALIFIER) //获得堆栈中下一元素,如果仍为限定符继续输出知道不是限定符为止 { deal_with_qualifiers(stack[top].string); top--; } goto step4; //跳到第4步 } //第6步 else if(temp.type == TYPE) //将剩下的符号作为声明的基本类型输出 { printf("%s",temp.string); } } int main() { read_to_first_identifier(); deal_with_all(); return 0; }
相关文章推荐
- 《C语言及程序设计》程序阅读——用switch语句实现多分支结构
- 一个生成COBOL测试数据的小程序——分析COBOL中数据声明的语句
- C专家编程:用python写cdecl程序,以分析C语言程序的声明语句
- 模拟器与程序分析-4-一个简单的周期精确模拟器(CAS)的C语言实现
- 实验一 词法分析程序的设计与实现(C语言)
- cdecl程序,用于分析C语言的声明
- 程序比程序员更理解c语言! cdecl程序(分析c语言的声明
- jni实现C语言调用Java程序
- 一条语句实现程序运行时隐藏窗口
- 用C语言实现Ping程序功能
- C语言接口与实现【第四章】 setjmp/longjmp非局部跳转函数分析
- 用C语言实现的闹钟程序
- 【学习ios之路:C语言】小程序:实现类似ATM取款机功能.
- [VC/MFC]一条语句实现程序运行时隐藏窗口
- 编译原理:递归向下分析程序建立语法分析树的Java实现(一)
- C语言中const分析(未知大小的全局变量数组声明出错)
- [置顶] FastCGI 协议分析与C语言实现实例
- Anbox 实现分析之程序入口
- 基于C语言实现的Ping程序
- 把c语言中的声明用程序翻译成通俗的语言