www.pudn.com > zdf.rar > cafa.cpp
#include#include #include #include using namespace std; #define NUM 10 /*保留字最大长度为9*/ #define LINEMAX 255 /*读取一行最大为255*/ typedef struct entry /*定义结构*/ { char word[10]; /*关键字,长度最大为10*/ int token; /*token值*/ } entry; typedef struct SymbolNode /*符号表*/ { int token; char name[NUM]; int len; struct SymbolNode *next; } symbol; typedef struct TokenNode /*token字表*/ { char string[NUM]; int token; struct TokenNode *next; } TokenTable; entry words[]= { "and",1, "array",2, "begin",3, "bool",4, "call",5, "case",6, "char",7, "constant",8, "do",9, "else",10, "end",11, "false",12, "for",13, "if",14, "input",15, "integer",16, "not",17, "of",18, "or",19, "output",20, "procedure",21, "program",22, "read",23, "real",24, "repeat",25, "set",26, "then",27, "to",28, "true",29, "until",30, "var",31, "while",32, "write",33, "标识符",34,"整常数",35,"实常数",36, "字符常数",37, "'",38, "(",39, ")",40, "*",41, "*/",42, "+",43, ",",44, "-",45, ".",46, "..",47, "/",48, "/*",49, ":",50, ":=",51, ";",52, "<",53, "<=",54, "<>",55, "=",56, ">",57,">=",58, "[",59, "]",60 }; class csort { protected: char *bf; /*用于存储标识符,数字, 字符常量*/ int row; int col; char *str; /*只是个指针,不为其分配存储空间*/ char strline[LINEMAX]; /*文件中读入的一行字符串,其允许的最大字符个数为255*/ public: csort(); ~csort(); int sort(); int is_sign(char ch); int IsKeyword(char *str); int IsDelimeter(); int recogid(); int recogdig(); int recogstr(); int handlecom(); char *NewMem(int len); int error_pro(int errorno); }; csort::csort() { bf=NULL; row=0; col=0; str=NULL; } csort::~csort() { delete [] bf; } class cifa:public csort { protected: int len; int token; char *p; /*所要查找的符号表时的符号*/ symbol *symbollink,*sym_head; /*指向符号表的指针*/ TokenTable *tokenlink,*token_head; /*指向token表的指针*/ FILE *fp; public: cifa();//symbol *symbollink, TokenTable *tokenlink); ~cifa(); int cifa_main(); int string_process(); /*处理读取的行字符串,消除行首空格及TAB,及行中TAB*/ int lookup_sym(char *sym); void ins_sym(char *sym); void print_sym(); void ins_token(char *p); /*插入符号表*/ void print_token(); }; cifa :: cifa()//symbol *symbollink, TokenTable *tokenlink) { len=0; token=-1; p=NULL; fp=NULL; symbollink=new symbol; sym_head=symbollink; tokenlink=new TokenTable; token_head=tokenlink; symbollink->token=0; strcpy(symbollink->name, "Token"); symbollink->len=0; /*头指针记录符号个数*/ symbollink->next=NULL; strcpy(tokenlink->string, "Symbol"); tokenlink->token=0; //头指针记录token 个数 tokenlink->next=NULL; } cifa::~cifa() { TokenTable *temp=token_head->next; while(temp!=NULL) { delete token_head; token_head=temp; temp=token_head->next; } symbol *temps=sym_head->next; while(temps!=NULL) { delete sym_head; sym_head=temps; if(sym_head==NULL) printf("#"); temps=sym_head->next; } }; int cifa::cifa_main() { int findflag; //是否查找到相同的符号, 0存在相同的符号,1不存在相同的符号 char filename[20]; cout<<"请输入源文件名:"< >filename; ifstream in(filename); if(!in) { cout<<"can't open file.\n"; return 1; } while(in) { in.getline(strline,255);//读出源文件中一行字符串,默认行结束符为'\n' row++; if(in) //开始行处理 { len=string_process(); //消除行中的TAB键以及行首的空格,返回剩余字符串长度 col = 0; //指向行首 while(col < len) //对一行字符串进行处理 { bf=NULL; token=sort();//根据单词的第一个字符进行分类,判断该单词是属于哪一类,返回单词的token值 if(token!=-1) { if(bf!=NULL) p=bf; else p=words[token-1].word; cout< =NUM) colno=-3; state = '2'; } break; } } return colno; } //识别并去掉注释 int csort::handlecom() { char ch; int colno=0; ch=str[++colno]; if(ch=='*') { do { //注释只有一行中有效,行结束也认为注释结束 ch=str[++colno]; }while(!(ch=='*'&&str[colno+1]=='/')&&ch!='\0'); colno+=3; } else colno=-1; //返回-1则表明是除号 return colno; } //识别字符常数 int csort::recogstr() { char state='0'; //初始状态为0 char ch ; int colno=-1; while(state!='2') { ch = str[++colno]; switch( state ) { case '0': state = '1'; break; case '1': if( ch == '\'' ) state = '2'; //读到最后一个单引号,结束 else state = '1'; //否则一直是字符串部分 } } return colno+1; } //查找关键字 int csort::IsKeyword(char *str) { int i=0; /* 查找次数 */ int flag = -1; while(i<33) /*字符串表没有结束*/ { if(!strcmp(str,words[i].word)) { flag = i; break; } else i++; } return flag; } //查找界符 int csort::IsDelimeter() { int i=37; int flag = -1; char temp[3]; while(i<60) //字符串表没有结束 { if(str[0]==words[i].word[0]) { strncpy(temp, str, 2); temp[2]='\0'; if(!strcmp(temp,words[i+1].word)) i++; flag = i; break;/*返回与str相同的keyword的数组位置*/ } else i++; } return flag; } //为单词申请存储空间返回指向该空间首地址的指针 char *csort::NewMem(int len) { bf=new char[len]; strncpy(bf, str, len-1); bf[len-1]='\0'; return bf; } //查找符号表,查找指定的字符串是否在符号表中,flag为标识符 int cifa::lookup_sym(char *sym) { int flag=0; if( IsDelimeter()==-1 && IsKeyword(sym)==-1) { flag=1; while( symbollink!=NULL ) { if( !strcmp(symbollink->name, sym) ) /*符号相同时*/ { flag=0; break; } symbollink=symbollink->next; } } return flag; } //填入符号表 void cifa::ins_sym(char *sym) { symbollink->len++; /*符号个数加1*/ while(symbollink->next!=NULL) symbollink=symbollink->next; symbollink->next=new symbol; symbollink=symbollink->next; symbollink->token=token; symbollink->len=strlen(sym); strcpy(symbollink->name, sym); symbollink->name[NUM-1]='\0'; symbollink->next=NULL; } void cifa::print_sym() /*打印符号表*/ { FILE *fp; symbol *temp=sym_head->next; fp=fopen("symbol.txt","w+"); while(temp!=NULL) { fprintf(fp, "(%d\t%s\t%d)\n", temp->token, temp->name, temp->len); temp=temp->next; } fclose(fp); } void cifa::ins_token(char *p) /*插入符号表*/ { token_head->token++; /*token个数加1*/ tokenlink->next=new TokenTable; tokenlink=tokenlink->next; strcpy(tokenlink->string, p); /*赋值*/ tokenlink->string[NUM-1]='\0'; tokenlink->token=token; tokenlink->next=NULL; } void cifa::print_token() /*打印token表*/ { FILE *fp; TokenTable *temp=token_head->next; fp=fopen("token.txt","w+"); while(temp!=NULL) { fprintf(fp, "%s\n",temp->string); temp=temp->next; } fclose(fp); } int csort::error_pro(int errorno) { switch(errorno) { case -2: cout<<"Row="<
" <