www.pudn.com > pl0_compiler_c.rar > cifa.cpp


// cifa.cpp: implementation of the cifa class. 
////////////////////////////////////////////////////////////////////// 
#include  
#include "cifa.h" 
#include "pl0.h" 
#include "errors.h" 
 
CCifa::CCifa(CPlCompiler *ppl) 
{ 
	wt=new word_table[16]; 
	strcpy(wt[0].word,"begin");		wt[0].sym=beginsym; 
	strcpy(wt[1].word,"call");		wt[1].sym=callsym; 
	strcpy(wt[2].word,"const");		wt[2].sym=constsym; 
	strcpy(wt[3].word,"do");		wt[3].sym=dosym; 
	strcpy(wt[4].word,"end");		wt[4].sym=endsym; 
	strcpy(wt[5].word,"if");		wt[5].sym=ifsym; 
	strcpy(wt[6].word,"odd");		wt[6].sym=oddsym; 
	strcpy(wt[7].word,"procedure");	wt[7].sym=procsym; 
	strcpy(wt[8].word,"read");		wt[8].sym=readsym; 
	strcpy(wt[9].word,"then");		wt[9].sym=thensym; 
	strcpy(wt[10].word,"var");		wt[10].sym=varsym; 
	strcpy(wt[11].word,"while");	wt[11].sym=whilesym; 
	strcpy(wt[12].word,"write");	wt[12].sym=writesym; 
	strcpy(wt[13].word,"else");		wt[13].sym=elsesym; 
	strcpy(wt[14].word,"repeat");	wt[14].sym=repeatsym; 
	strcpy(wt[15].word,"until");	wt[15].sym=untilsym; 
 
	create_ht(); 
	ch=' '; 
	line=1; 
	pl=ppl; 
} 
CCifa::~CCifa() 
{ 
	delete[] wt; 
} 
 
symbol CCifa::GetSymbol() 
{ 
	FILE *fs=pl->fp; 
	CErrors *err=pl->errors; 
	int k,p; 
	symbol sym; 
 
	while (ch==' '|| ch=='\t' || ch=='\n') 
	{ 
		if (ch=='\n') line++; 
		ch=getc(fs); 
	} 
	//字符是一个字母,说明是保留字或标识符 
	if ('a'<=ch && ch<='z' || 'A'<=ch && ch<='Z') {	 
		k=0;	                      //标识符缓冲区指针置0 
		do{ 
			if (k=0) ? wt[p].sym : ident; 
	} 
	//如果读出字符是数字 
	else if ('0'<=ch && ch<='9') 
	{ 
		k=0;                          //数字位数 
		num=0;                        //数字置为0 
		sym=number;                   //置sym为number,表示这一次读到的是数字 
		do{ 
			num=num*10+ch-'0';          //去除0开头的数字 
			k++;	                  //数字位数加1 
			ch=getc(fs); 
		}while ('0'<=ch && ch<='9'); 
		if (k>NUMBER_LENGTH)          //如果组成的数字位数大于最大允许的数字位数 
			err->Add(30); 
		if (num>MAX_NUMBER) 
		{ 
			err->Add(31); 
			num=0; 
		} 
	} 
	//读出的不是字母也不是数字 
	else if (ch==':')                 //冒号 
	{ 
		ch=getc(fs); 
		if (ch=='=')	              //赋值号 
		{ 
			sym=becomes; 
			ch=getc(fs); 
		} 
		else 
			sym=nul; 
	} 
	else if (ch=='<')                 //如果读到小于号 
	{ 
		ch=getc(fs); 
		if (ch=='=') 
		{ 
			sym=leq;                  //<=号 
			ch=getc(fs); 
		} 
		else 
			sym=lss;                  //<号 
	} 
	else if (ch=='>')                 //如果读到大于号 
	{ 
		ch=getc(fs); 
		if (ch=='=') 
		{ 
			sym=geq;                  //>=号 
			ch=getc(fs); 
		} 
		else 
			sym=gtr;                  //>号 
	} 
	else 
	{ 
		switch (ch) 
		{ 
		case '+':sym=plus;break; 
		case '-':sym=minus;break; 
		case '*':sym=times;break; 
		case '/':sym=slash;break; 
		case '(':sym=lparen;break; 
		case ')':sym=rparen;break; 
		case '=':sym=eql;break; 
		case '#':sym=neq;break; 
		case ',':sym=comma;break; 
		case '.':sym=period;break; 
		case ';':sym=semicolon;break; 
		case EOF:sym=endfile;break; 
		default: sym=nul; 
		} 
		ch=getc(fs); 
	} 
	return sym; 
} 
/////////////////////////////////////////////////////// 
 
void CCifa::create_ht()              //保留字的查找表处理 
{ 
	for (int i=0;i<20;i++) ht[i]=-1; 
	for (i=0;i<16;i++) 
		ht[hush(wt[i].word)]=i; 
} 
int CCifa::hush(char *s) 
{ 
	int a=s[1],b=s[2]; 
	if (a>='a') a-='a'-'A'; 
	if (b>='a') b-='a'-'A'; 
	int h=a*2+b-100; 
	if (h==40) h=0; 
	else if(h==103) h=2; 
	h%=21; 
	if (h==20) h=3; 
	return h; 
} 
int CCifa::hushsrch(char *word) 
{ 
	int p=ht[hush(word)]; 
	if (p==-1) return -1; 
	if (stricmp(word,wt[p].word)!=0) 
		return -1; 
	return p; 
}