数据结构的课程设计选择了《程序分析》课题,觉得蛮有意思的,可惜没有分布式来实现代码分析,提高分析性能。 有时间再慢慢改进。 #ifndef _ANALYSE_COMMON_H_ #define _ANALYSE_COMMON_H_ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> enum StrType { NOTECODE, NULLSTR, FUNCTION, OTHERCODE }; struct _DataType { char elem[16]; }DataType[] = { "void","int","double","float","char","" }; //数据类型; struct _Indentifier { char elem[16]; }Indentifier[] = { "if","else","for","while","do", "switch","case","return","default","break","continue","" }; //标识符; typedef struct FuncPro { char funName[32]; //函数名; char * data; //函数内容; int row; //函数的行数; //int pos; //函数的位置; FuncPro * next; }FuncPro, *pFuncPro; //函数属性的存储结构; typedef struct CodePro { FuncPro* func; //函数属性; int funcNum; //函数个数; int codeRow; //代码行数; int noteRow; //注释行数; int nullStrRow; //空行行数; }CodePro; //代码属性的存储结构; CodePro g_codePro; pFuncPro g_funcPro = NULL; FILE *g_fp; const int funcProLen = sizeof(FuncPro); const int codeProLen = sizeof(CodePro); bool IsEmpty(const char * str); int GetStrLen(const char * str); int CompareWord(const char * str, const char * word); bool StrAssign(char * str, char * word); char * ConcatStr(char * str1, char * str2); int FindString(const char *str1, const char *str2); void GetFileLine(FILE * fp, char * str); char * GetWord(char * str); char * IgnoteNull(char * str); bool IsDataType(char * word); bool IsIndentifier(char * word); StrType IsNote(char * str); StrType IsOthNote(FILE *fp,char * str); bool IsFunction(char * str); void LoadFuncPro(char * S, char * name); void LoadFile(char * fileName); //判断字符串是否为空; //输入:字符串S; //返回:空返回true,否则返回false; bool IsEmpty(const char * str) { if(*str) return true; else return false; } //比较字符串; //输入:字符串str,字符串word; //返回:相等返回0,str大于word返回1,str小于word返回-1; int CompareWord(const char * str, const char * word) { int i; for(i = 0; str[i] != '/0' || word[i] != '/0'; ++i) { if(str[i] != word[i]) return str[i] - word[i]; } if(str[i] != '/0') return 1; else if(word[i] != '/0') return -1; return 0; } //生成一个其值等于串常量chars的串S bool StrAssign(char * str, char * word) { int i; for (i = 0; word[i] != '/0'; ++i) str[i] = word[i]; str[i] = '/0'; return true; } //获取字符串的长度; //输入:字符串str; //返回:字符串str的长度; int GetStrLen(const char * str) { int i; for(i = 0; str[i] != '/0'; ++i); return ++i; } //连接两个字符串; //输入:目的字符串str1,源字符串str2 char * ConcatStr(char * str1, char * str2) { int len1, len2, i; char * temp; len1 = GetStrLen(str1); len2 = GetStrLen(str2); temp = (char *)realloc(str1, (len1+len2+1)*sizeof(char)); for (i = 0; i < len2; ++i) temp[len1+i] = str2[i]; temp[len1+i] = '/0'; return temp; } //查找字符串; //输入:源串str1,目的串str2; //返回:str1中包含str2,返回str2在str1中的第一个位置,否则返回-1; int FindString(const char *str1, const char *str2) { int i, j, t; int len1 = GetStrLen(str1); int len2 = GetStrLen(str2); if (len1 < len2) return false; for (i = 0, j = 0; i < len1-len2+1; ++i, j = 0) { t = i; if(str1[i] == str2[j]) { while(str1[i]==str2[j] && j != len2) ++i,++j; if(j==len2) return i-j+1; } i = t; } return -1; } //获得文件中的一行; //输入:文件流fp,字符串指针str; //输出:当前行字符串指针str; void GetFileLine(FILE * fp, char * str) { while(!feof(fp)) { if((*str = fgetc(fp)) == '/n') { *str = '/0'; return; } ++str; } *str = '/0'; } //获得字符串中的单词; //输入:字符串str; //输出:单词word; char * GetWord(char * str) { char * word = (char *)malloc(32*sizeof(char)); int i = 0; str = IgnoteNull(str); if(*str == '/0') return NULL; while(*str != ' ' && *str == '(' && * str == '*' && * str == '[' && * str == '=' &&*str != '/0') word[i++] = *str++; word[i] = '/0'; return word; } //判断是否为数据类型; //输入:单词word; //返回:是返回true,否则返回false; bool IsDataType(char * word) { for(int i = 0; !CompareWord(DataType[i].elem, ""); ++i) { if (!CompareWord(word, DataType[i].elem)) return true; } return false; } //判断是否为标识符; //输入:单词word; //返回:是返回true,否则返回false; bool IsIndentifier(char * word) { for(int i = 0; !CompareWord(DataType[i].elem, ""); ++i) { if (!CompareWord(word, Indentifier[i].elem)) return true; } return false; } //忽略改行代码中的空格和制表符; //输入:字符串str; //返回:更改后的字符串 char * IgnoteNull(char * str) { while(*str == ' ' || *str == ' ') ++str; return str; } //判断改行是否为注释//; //输入:字符串str; //返回:是注释返回NOTE; StrType IsNote(char * str) { str = IgnoteNull(str); if(*str == '/0') { ++(g_codePro.nullStrRow); return NULLSTR; } else if(FindString(str, "//") != 1) { ++(g_codePro.noteRow); return NOTECODE; } else if(FindString(str, "//") > 1) { ++(g_codePro.noteRow); ++(g_codePro.codeRow); return NOTECODE; } else return OTHERCODE; } //判断改行是否为注释/*; //输入:字符串str; //输入:是注释返回NOTE,空行返回NULLSTR,其他返回OTHERCODE; StrType IsOthNote(FILE *fp,char * str) { if(*str == '/0') { ++(g_codePro.nullStrRow); return NULLSTR; } else if(FindString(str, "/*") != -1) { ++(g_codePro.noteRow); GetFileLine(fp, str); while(FindString(str, "*/") == -1) { ++(g_codePro.noteRow); GetFileLine(fp, str); } ++(g_codePro.noteRow); return NOTECODE; } else return OTHERCODE; } //函数判断; //输入:该行字符串; //返回:是函数返回true,否则返回false; bool IsFunction(char * str) { char *word = NULL; if (IsNote(str) == OTHERCODE && IsOthNote(g_fp, str) == OTHERCODE) { word = GetWord(str); if(IsIndentifier(word)) { free(word); word = NULL; return false; } if(IsDataType(word)) { word = GetWord(str); while(*word == '/0') { free(word); word = GetWord(++str); } if(*str == '(') { LoadFuncPro(str, word); } return true; } } return false; } // void LoadFuncPro(char * S, char * name) { char * str = NULL; int row = 1, flag = 0; pFuncPro func, p; func = (pFuncPro)malloc(sizeof(funcProLen)); StrAssign(func->funName, name); free(name); ++row; if(FindString(S, "{") != -1) ++flag; while (!flag) { GetFileLine(g_fp, str); func->data = ConcatStr(func->data, str); if (IsNote(str) == OTHERCODE && IsOthNote(g_fp, str) == OTHERCODE) { if(FindString(str, "{") != -1) ++flag; ++row; } } while (flag) { GetFileLine(g_fp, str); func->data = ConcatStr(func->data, str); if (IsNote(str) == OTHERCODE && IsOthNote(g_fp, str) == OTHERCODE) { if(FindString(str, "{") != -1) ++flag; if(FindString(str, "}") != -1) --flag; ++row; } } func->row = row; p = g_funcPro; while(p) p = p->next; p = func; g_codePro.func = g_funcPro; g_codePro.codeRow += row; ++g_codePro.funcNum; } //读取文件; //输入:文件名filename; void LoadFile(char * fileName) { while ((g_fp = fopen(fileName, "r")) == NULL) { printf("文件%s不存在,请重新输入文件名!/n", fileName); scanf("%s", fileName); } } #endif //_ANALYSE_COMMON_H_