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="<" 
						<