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; }