编译原理课程设计说明书--词法分析,语法分析,语义分析

合集下载

[工学]编译原理--词法分析_语法分析_语义分析C语言

[工学]编译原理--词法分析_语法分析_语义分析C语言

[工学]编译原理--词法分析_语法分析_语义分析C语言词法分析#include#include#includeusing namespace std;#define MAXN 20000int syn,p,sum,kk,m,n,row;double dsum,pos;char index[800],len;//记录指数形式的浮点数char r[6][10]={"function","if","then","while","do","endfunc"}; char token[MAXN],s[MAXN];char ch;bool is_letter(char c){return c>='a' && c<='z' || c>='A' && c<='Z';}bool is_digtial(char c){return c>='0' && c<='9';}bool is_dot(char c){return c==',' || c==';';}void identifier()//标示符的判断{m=0;while(ch>='a' && ch<='z' || ch>='0' && ch<='9') {token[m++]=ch;ch=s[++p];}token[m]='\\0';ch=s[--p];syn=10;for(n=0;n<6;n++)if(strcmp(token,r[n])==0){syn=n+1;break;}}void digit(bool positive)//数字的判断{len=sum=0;ch=s[p];while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=s[++p];}if(ch=='.'){dsum=sum;ch=s[++p];pos=0.1;while(ch>='0' && ch<='9'){dsum=dsum+(ch-'0')*pos;pos=pos*0.1;ch=s[++p];}if(ch=='e'){index[len++]=ch;ch=s[++p];if(ch=='-' || ch=='+'){index[len++]=ch;ch=s[++p];}if(!(ch>='0' && ch<='9')){syn=-1;}else{while(ch>='0' && ch<='9'){index[len++]=ch;ch=s[++p];}}}if(syn==-1 || (ch>='a' && ch<='z') || ch=='.') {syn=-1;//对数字开头的标识符进行判错。

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)

编译原理课程设计(词法分析,语法分析,语义分析,代码生成)#include<cstdio>#include<iostream>#include<cstdlib>#include<fstream>#include<string>#include<cmath>using namespace std;/************************************************/struct token// token {int code;//int num;//token *next;};token *token_head,*token_tail;//tokenstruct str// string {int num;//string word;//str *next;};str *string_head,*string_tail;//stringstruct ivan// {char left;//string right;//int len;// };ivan css[20];// 20 struct pank// action {char sr;//int state;// };pank action[46][18];//action int go_to[46][11];// go_to struct ike// {ike *pre;int num;//int word;//ike *next;};ike *stack_head,*stack_tail;// struct L//{int k;string op;//string op1;//string op2;//string result;//L *next;//L *Ltrue;//trueL *Lfalse;//false};L *L_four_head,*L_four_tail,*L_true_head,*L_false_head;//truefalse struct symb//{string word;//int addr;//symb *next;};symb *symb_head,*symb_tail;///************************************************/void scan();//void cifa_main();//int judge(char ch);// void out1(char ch);//token.txtvoid out3(char ch,string word);//string.txt void input1(token*temp);//token void input3(str *temp);//string void output();// void outfile();///************************************************/void yufa_main();//void yufa_initialize();// int yufa_SLR1(int a);// int ID1(inta);//action string ID10(int i);//int ID2(char ch);//go_toint ID20(char ch);//char ID21(int j);//void add(ike *temp);//ike void del();//ike/************************************************/void yuyi_main(int m);//void add_L_four(L *temp);// void add_L_true(L *temp);//true void add_L_false(L *temp);//false void add_symb(symb *temp);// void output_yuyi();// string newop(int m);//string id_numtoname(int num);// int lookup(string m);///************************************************/FILE *fp;//int wordcount;//int err;//int nl;//int yuyi_linshi;//stringE_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;// int id_num,id1_num,id2_num,id_left,id_while,id_then,id_do;// /******************************************************/int main(){cout<<"************************"<<endl;cout<<"* *"<<endl;cout<<"* *"<<endl;cout<<"* *"<<endl;cout<<"* *"<<endl;cout<<"************************"<<endl;cifa_main();//yufa_main();//output_yuyi();//cout<<endl;system("pause");return(0);}/******************************************************/ void cifa_main(){token_head=new token;token_head->next=NULL;token_tail=new token;token_tail->next=NULL;string_head=new str;string_head->next=NULL;string_tail=new str;string_tail->next=NULL;//L_four_head=new L;L_four_head->next=NULL;L_four_tail=new L;L_four_tail->k=0;L_four_tail->next=NULL;L_true_head=new L;L_true_head->Ltrue=NULL;L_false_head=new L;L_false_head->Lfalse=NULL;symb_head=new symb;symb_head->next=NULL;symb_tail=new symb;symb_tail->next=NULL;yuyi_linshi=-1;id_num=0;wordcount=0;//err=0;//nl=1;//scan();if(err==0){char m;output();cout<<"!"<<endl<<endl<<" y";cin>>m;cout<<endl;if(m=='y'){outfile();cout<<"token.txtsting.txt"<<endl;cout<<endl;}}}void scan(){cout<<endl;system("pause");cout<<endl;char ch;string word;char document[50];int flag=0;cout<<":";cin>>document;cout<<endl;cout<<"************************"<<endl; cout<<"* *"<<endl;cout<<"************************"<<endl; if((fp=fopen(document,"rt"))==NULL) {err=1;cout<<"!"<<endl;return;}while(!feof(fp)){word="";ch=fgetc(fp);flag=judge(ch);if(flag==1)out1(ch);else if(flag==3)out3(ch,word);else if(flag==4 || flag==5 ||flag==6) continue;else{cout<<nl<<" "<<":! "<<ch<<endl;err=1;}}fclose(fp);}int judge(char ch){int flag=0;if(ch=='=' || ch=='+' || ch=='*' || ch=='>' || ch==':' || ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')')flag=1;//else if(('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))flag=3;//else if(ch==' ')flag=4;//else if(feof(fp))flag=5;//else if(ch=='\n'){flag=6;//nl++;}elseflag=0;//return(flag);}void out1(char ch){int id;switch(ch){case '=' : id=1;break;case '+' : id=2;break;case '*' : id=3;break;case '>' : id=4;break;case ':' : id=5;break;case ';' : id=6;break;case '{' : id=7;break;case '}' : id=8;break;case '(' : id=9;break;case ')' : id=10;break;// default : id=0;}token *temp;temp=new token;temp->code=id;temp->num=-1;temp->next=NULL;input1(temp);return;}void out3(char ch,string word) {token *temp;temp=new token;temp->code=-1;temp->num=-1;temp->next=NULL;str *temp1;temp1=new str;temp1->num=-1;temp1->word="";temp1->next=NULL;int flag=0;word=word+ch;ch=fgetc(fp);flag=judge(ch);if(flag==1 || flag==4 || flag==5 || flag==6){if(word=="and" || word=="if" || word=="then" || word=="while" || word=="do" || word=="int"){if(word=="and")temp->code=31;else if(word=="if")temp->code=32;else if(word=="then")temp->code=33;else if(word=="while")temp->code=35;else if(word=="do")temp->code=36;else if(word=="int")temp->code=37;//input1(temp);if(flag==1)out1(ch);else if(flag==4 || flag==5 || flag==6) return;}else if(flag==1){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);out1(ch);}else if(flag==4 || flag==5 || flag==6) {wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);}return;}else if(flag==2 || flag==3)out3(ch,word);//else{err=1;cout<<nl<<" "<<":! "<<ch<<endl; return;}}void input1(token *temp) {if(token_head->next == NULL) {token_head->next=temp;token_tail->next=temp;}else{token_tail->next->next=temp; token_tail->next=temp;}}void input3(str *temp) {if(string_head->next == NULL) {string_head->next=temp;string_tail->next=temp;}else{string_tail->next->next=temp; string_tail->next=temp;}}void output(){cout<<"token"<<endl;token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){cout<<temp1->code;if(temp1->num == -1){cout<<endl;}else{cout<<" "<<temp1->num<<endl;}temp1=temp1->next;}cout<<""<<endl;str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){cout<<temp3->num<<" "<<temp3->word<<endl; temp3=temp3->next;}}void outfile(){ofstream fout1("token.txt");//ofstream fout3("string.txt");token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){fout1<<temp1->code;if(temp1->num == -1)fout1<<endl;elsefout1<<" "<<temp1->num<<endl;temp1=temp1->next;}str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){fout3<<temp3->num<<" "<<temp3->word<<endl; temp3=temp3->next;}}/******************************************************/ void yufa_main(){if(err==0){system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* *"<<endl;cout<<"************************"<<endl;yufa_initialize();//token *temp;temp=new token;temp=token_head->next;int p,q;p=0;q=0;cout<<""<<endl;while(temp!=NULL){int w;w=ID1(temp->code);p=yufa_SLR1(w);if(p==1) break;if(p==0)temp=temp->next;if(temp==NULL) q=1;}//if(q==1)while(1){p=yufa_SLR1(17);if(p==3) break;}//$}}void yufa_initialize() { stack_head=new ike;stack_tail=new ike;stack_head->pre=NULL;stack_head->next=stack_tail; stack_head->num=0;stack_head->word='!';stack_tail->pre=stack_head; stack_tail->next=NULL;//css[0].left='Q';css[0].right="P";css[1].left='P';css[1].right="id()L;R"; css[2].left='L';css[2].right="L;D";css[3].left='L';css[3].right="D";css[4].left='D';css[4].right="id:int"; css[5].left='E';css[5].right="E+T";css[6].left='E';css[6].right="T";css[7].left='T';css[7].right="T*F";css[8].left='T';css[8].right="F";css[9].left='F';css[9].right="(E)";css[10].left='F';css[10].right="id";css[11].left='B';css[11].right="B and B"; css[12].left='B';css[12].right="id>id"; css[13].left='M';css[13].right="id=E";css[14].left='S';css[14].right="if B then M"; css[15].left='S';css[15].right="while B do M"; css[16].left='S';css[16].right="M";css[17].left='N';css[17].right="N;S";css[18].left='N';css[18].right="S";css[19].left='R';css[19].right="{N}";int i,j;for(i=0;i<20;i++){char *css_len;css_len=&css[i].right[0];css[i].len=strlen(css_len); }css[1].len=6;css[4].len=3;css[10].len=1;css[11].len=3;css[12].len=3;css[13].len=3;css[14].len=4;css[15].len=4;//for(i=0;i<46;i++){for(j=0;j<18;j++)action[i][j].sr='#';}//actionfor(i=0;i<46;i++){for(j=0;j<11;j++)go_to[i][j]=-1;}//go_to/****************************actiongo_to************************/ action[0][0].sr='s';action[0][0].state=2;action[1][17].sr='@';//action[2][1].sr='s';action[2][1].state=3;action[3][2].sr='s';action[3][2].state=4;action[4][0].sr='s';action[4][0].state=5;action[5][4].sr='s';action[5][4].state=6;action[6][11].sr='s';action[6][11].state=7;action[7][3].sr='r';action[7][3].state=4;action[8][3].sr='r';action[8][3].state=3;action[9][3].sr='s';action[9][3].state=10; action[10][0].sr='s';action[10][0].state=5; action[10][9].sr='s';action[10][9].state=13; action[11][17].sr='r';action[11][17].state=1; action[12][3].sr='r';action[12][3].state=2; action[13][0].sr='s';action[13][0].state=14; action[13][13].sr='s';action[13][13].state=23; action[13][15].sr='s';action[13][15].state=27; action[14][8].sr='s';action[14][8].state=15; action[15][0].sr='s';action[15][0].state=36; action[15][1].sr='s';action[15][1].state=41; action[16][6].sr='s';action[16][6].state=43; action[16][3].sr='r';action[16][3].state=13; action[16][10].sr='r';action[16][10].state=13; action[17][3].sr='s';action[17][3].state=19; action[17][10].sr='s';action[17][10].state=18; action[18][17].sr='r';action[18][17].state=19; action[19][0].sr='s';action[19][0].state=14; action[19][13].sr='s';action[19][13].state=23; action[19][15].sr='s';action[19][15].state=27; action[20][3].sr='r';action[20][3].state=17; action[20][10].sr='r';action[20][10].state=17; action[21][3].sr='r';action[21][3].state=18; action[21][10].sr='r';action[21][10].state=18;action[22][3].sr='r';action[22][3].state=16; action[22][10].sr='r';action[22][10].state=16; action[23][0].sr='s';action[23][0].state=31; action[24][12].sr='s';action[24][12].state=34; action[24][14].sr='s';action[24][14].state=25; action[25][0].sr='s';action[25][0].state=14; action[26][3].sr='r';action[26][3].state=14; action[26][10].sr='r';action[26][10].state=14; action[27][0].sr='s';action[27][0].state=31; action[28][12].sr='s';action[28][12].state=34; action[28][16].sr='s';action[28][16].state=29; action[29][0].sr='s';action[29][0].state=14; action[30][3].sr='r';action[30][3].state=15; action[30][10].sr='r';action[30][10].state=15; action[31][7].sr='s';action[31][7].state=32; action[32][0].sr='s';action[32][0].state=33; action[33][12].sr='r';action[33][12].state=12; action[33][14].sr='r';action[33][14].state=12; action[33][16].sr='r';action[33][16].state=12; action[34][0].sr='s';action[34][0].state=31; action[35][12].sr='r';action[35][12].state=11; action[35][14].sr='r';action[35][14].state=11; action[35][16].sr='r';action[35][16].state=11; action[36][2].sr='r';action[36][2].state=10;action[36][3].sr='r';action[36][3].state=10; action[36][5].sr='r';action[36][5].state=10; action[36][6].sr='r';action[36][6].state=10; action[36][10].sr='r';action[36][10].state=10; action[37][2].sr='r';action[37][2].state=8; action[37][3].sr='r';action[37][3].state=8; action[37][5].sr='r';action[37][5].state=8; action[37][6].sr='r';action[37][6].state=8; action[37][10].sr='r';action[37][10].state=8; action[38][2].sr='r';action[38][2].state=6; action[38][3].sr='r';action[38][3].state=6; action[38][5].sr='s';action[38][5].state=39; action[38][6].sr='r';action[38][6].state=6; action[38][10].sr='r';action[38][10].state=6; action[39][0].sr='s';action[39][0].state=36; action[39][1].sr='s';action[39][1].state=41; action[40][2].sr='r';action[40][2].state=7; action[40][3].sr='r';action[40][3].state=7; action[40][5].sr='r';action[40][5].state=7; action[40][6].sr='r';action[40][6].state=7; action[40][10].sr='r';action[40][10].state=7; action[41][0].sr='s';action[41][0].state=36; action[41][1].sr='s';action[41][1].state=41; action[42][2].sr='s';action[42][2].state=45;action[42][6].sr='s';action[42][6].state=43;action[43][0].sr='s';action[43][0].state=36;action[43][1].sr='s';action[43][1].state=41;action[44][2].sr='r';action[44][2].state=5;action[44][3].sr='r';action[44][3].state=5;action[44][5].sr='s';action[44][5].state=39;action[44][6].sr='r';action[44][6].state=5;action[44][10].sr='r';action[44][10].state=5;action[45][2].sr='r';action[45][2].state=9;action[45][3].sr='r';action[45][3].state=9;action[45][5].sr='r';action[45][5].state=9;action[45][6].sr='r';action[45][6].state=9;action[45][10].sr='r';action[45][10].state=9;go_to[0][0]=1;go_to[4][1]=8;go_to[4][9]=9;go_to[10][1]=12;go_to[10][ 2]=11;go_to[13][7]=22;go_to[13][8]=21;go_to[13][10]=17;go_to[15][3]=16;go_to[15][4]=38;go_to[15][5]=37;go_to[19][7]=20;go_t o[19][8]=20;go_to[23][6]=24;go_to[25][7]=26;go_to[27][6]=28;go_to[29][7]=30;go_to[34][6]=35;go_to[39][5]=40;go_to[41][3]=42;go_t o[41][4]=38;go_to[41][5]=37;go_to[43][4]=44;go_to[43][5]=37;/****************************actiongo_to************************/ }int ID1(int i)//action {int j;j=-1;if(i==25) {j=0;id_num++;}//if(i==1) {j=8,id_left=id_num;}//if(i==2) j=6;if(i==3) j=5;if(i==4) j=7;if(i==5) j=4;if(i==6) j=3;if(i==7) j=9;if(i==8) j=10;if(i==9) j=1;if(i==10) j=2;if(i==31) j=12;if(i==32) j=13;if(i==33) {j=14;id_then=L_four_tail->k+1;}//ifthenif(i==35) {j=15;id_while=L_four_tail->k+1;}//whilewhile if(i==36) {j=16;id_do=L_four_tail->k+1;}//whiledoif(i==37) j=11;return(j);}string ID10(int i)//{string ch;if(i==0) ch="id";if(i==1) ch="(";if(i==2) ch=")";if(i==3) ch=";";if(i==4) ch=":";if(i==5) ch="*";if(i==6) ch="+";if(i==7) ch=">";if(i==8) ch="=";if(i==9) ch="{";if(i==10) ch="}";if(i==11) ch="int";if(i==12) ch="and";if(i==13) ch="if";if(i==14) ch="then";if(i==15) ch="while"; if(i==16) ch="do";if(i==17) ch="$";return(ch);}int ID2(char ch)//go_to {int j;j=-1;if(ch=='P') j=0;if(ch=='D') j=1;if(ch=='R') j=2;if(ch=='E') j=3;if(ch=='T') j=4;if(ch=='F') j=5;if(ch=='B') j=6;if(ch=='M') j=7;if(ch=='S') j=8;if(ch=='L') j=9;if(ch=='N') j=10; return(j);}int ID20(char ch)// {int j;j=-1;if(ch=='P') j=100; if(ch=='D') j=101; if(ch=='R') j=102; if(ch=='E') j=103; if(ch=='T') j=104; if(ch=='F') j=105;if(ch=='B') j=106;if(ch=='M') j=107;if(ch=='S') j=108;if(ch=='L') j=109;if(ch=='N') j=1010;return(j);}char ID21(int j)//{char ch;if(j==100 || j==0) ch='P'; if(j==101 || j==1) ch='D'; if(j==102 || j==2) ch='R'; if(j==103 || j==3) ch='E'; if(j==104 || j==4) ch='T'; if(j==105 || j==5) ch='F'; if(j==106 || j==6) ch='B'; if(j==107 || j==7) ch='M'; if(j==108 || j==8) ch='S'; if(j==109 || j==9) ch='L'; if(j==1010 || j==10) ch='N'; return(ch);}void add(ike *temp)//{if(stack_head->next==stack_tail){temp->pre=stack_head;temp->next=stack_tail;stack_head->next=temp;stack_tail->pre=temp;}else{temp->pre=stack_tail->pre;temp->next=stack_tail;stack_tail->pre->next=temp;stack_tail->pre=temp;}}void del()//{stack_tail->pre->pre->next=stack_tail; stack_tail->pre=stack_tail->pre->pre; }int yufa_SLR1(int w){/*cout<<""<<ID10(w)<<" ";*/int i,flag=0,state_temp;//flag01,23char sr_temp;sr_temp=action[stack_tail->pre->num][w].sr;//state_temp=action[stack_tail->pre->num][w].state;// if(sr_temp=='#')//{flag=1;err=3;cout<<"!"<<endl;}else if(sr_temp=='s')//{ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=w;temp->num=state_temp;add(temp);cout/*<<""*/<<sr_temp<<state_temp<<" "/*<<""<<stack_tail->pre->num<<" "<<""<<ID10(stack_tail->pre->word)*/<<endl;flag=0;}else if(sr_temp=='r')//{int p=ID2(css[state_temp].left);int q=css[state_temp].len;for(i=0;i<q;i++)del();ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=ID20(css[state_temp].left);temp->num=go_to[stack_tail->pre->num][p];//go_toadd(temp);cout/*<<""*/<<sr_temp<<state_temp<<" "<<css[state_temp].left<<""<<css[state_temp].right<<" "/*<<""<<stack_tail->pre->num<<" "<<""<<ID21(stack_tail->pre->word)*/<<endl;flag=2;yuyi_main(state_temp);//}else if(sr_temp=='@')//{cout<<"END"/*<<""<<sr_temp<<state_temp*/<<""<<css[state_temp].left<<""<<css[state_temp].right<<" "/*<<""<<stack_tail->pre->num<<" "<<""<<ID21(stack_tail->pre->word)*/<<endl;flag=3;cout<<"!"<<endl;}else//{flag=1;err=3;cout<<"!"<<endl;}return(flag);}/******************************************************/ void yuyi_main(int m){L *temp;int k;k=1;temp=new L;temp->op=" ";temp->op1=" ";temp->op2=" ";temp->result="";temp->next=NULL;temp->Ltrue=NULL;temp->Lfalse=NULL;if(m==4)//{symb *Stemp;Stemp=new symb;id_name=id_numtoname(id_num); Stemp->word=id_name;Stemp->next=NULL;add_symb(Stemp);}if(m==5)//EE+T{temp->op="+";temp->op1=E_name;temp->op2=T_name;yuyi_linshi++;//E_name="t"+newop(yuyi_linshi); temp->result=E_name;add_L_four(temp);//}if(m==6)//ET{E_name=T_name;}if(m==7)//TT*F{temp->op="*";temp->op1=T_name;temp->op2=F_name;yuyi_linshi++;//T_name="t"+newop(yuyi_linshi); temp->result=T_name;add_L_four(temp);//}if(m==8)//TF{T_name=F_name;}if(m==9)//F(E){F_name=E_name;}if(m==10)//Fid{id_name=id_numtoname(id_num); F_name=id_name;k=lookup(id_name);//if(k==0){err=2;errword=id_name;return;}}if(m==12)//Bid>id{temp->op="J>";id1_num=id_num-1;id1_name=id_numtoname(id1_num); k=lookup(id1_name);//if(k==0){err=2;errword=id1_name;return;}id2_num=id_num;id2_name=id_numtoname(id2_num); k=lookup(id2_name);//if(k==0){err=2;errword=id2_name;return;}temp->result="-1";temp->op1=id1_name;temp->op2=id2_name;add_L_four(temp);//add_L_true(temp);//trueL *temp2;temp2=new L;temp2->op="J";temp2->op1=" ";temp2->op2=" ";temp2->result="-1";add_L_four(temp2);//add_L_false(temp2);//false}if(m==13)//Mid=E{temp->op="=";temp->op1=E_name;temp->op2=" ";id_name=id_numtoname(id_left);temp->result=id_name;add_L_four(temp);//yuyi_linshi=-1;//}if(m==14)//Sif B then M{int a;a=id_then;temp=L_true_head->Ltrue;while(temp!=NULL){temp->result="L"+newop(a);a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+1;temp=L_false_head->Lfalse;while(temp!=NULL){temp->result="L"+newop(a);temp=temp->Lfalse;}L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//truefalse}if(m==15)//Swhile B do M {int a;a=id_do;temp=L_true_head->Ltrue; while(temp!=NULL){temp->result="L"+newop(a); a=temp->k;temp=temp->Ltrue;}a=L_four_tail->k+2;temp=L_false_head->Lfalse; while(temp!=NULL){temp->result="L"+newop(a); temp=temp->Lfalse;}L *temp1;temp1=new L;temp1->op="J";temp1->op1=" ";temp1->op2=" ";temp1->next=NULL;temp1->result="L"+newop(id_while); add_L_four(temp1);//L_true_head->Ltrue=NULL;L_false_head->Lfalse=NULL;//truefalse }}string newop(int m)//{int shang,yushu;string chuan,chuan1;shang=m;chuan="";while(1){yushu=shang%10;chuan=chuan+char(48+yushu);shang=shang/10;if(shang==0)break;}int i;char *ch;ch=&chuan[0];chuan1="";for(i=strlen(ch)-1;i>=0;i--)chuan1=chuan1+chuan[i];return(chuan1);}void add_L_four(L *temp)//{temp->k=L_four_tail->k+1;if(L_four_head->next == NULL){L_four_head->next=temp;L_four_tail->next=temp;}else{L_four_tail->next->next=temp;L_four_tail->next=temp;}L_four_tail->k=L_four_tail->next->k; } void add_L_true(L *temp)//true{temp->Ltrue=L_true_head->Ltrue;L_true_head->Ltrue=temp;}void add_L_false(L *temp)//false {temp->Lfalse=L_false_head->Lfalse; L_false_head->Lfalse=temp;}void add_symb(symb *temp)//{if(symb_head->next == NULL){temp->addr=0;symb_head->next=temp;symb_tail->next=temp;}else{temp->addr=symb_tail->next->addr+4; symb_tail->next->next=temp;symb_tail->next=temp;}}void output_yuyi(){if(err==0)//{cout<<endl;system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* *"<<endl;cout<<"************************"<<endl;cout<<""<<endl;L *temp;temp=L_four_head->next;while(temp!=NULL){cout<<"L"<<temp->k<<": "<<temp->op<<", "<<temp->op1<<", "<<temp->op2<<","<<temp->result<<""<<endl;temp=temp->next;}cout<<""<<endl;symb *Stemp;Stemp=symb_head->next;cout<<"name"<<" type "<<" id "<<" identifer "<<"addr"<<endl;while(Stemp!=NULL){cout<<Stemp->word<<" int "<<" 25 "<<" sv "<<Stemp->addr<<endl;Stemp=Stemp->next;}}if(err==2)//{cout<<endl;system("pause");cout<<endl;cout<<"************************"<<endl; cout<<"* *"<<endl;cout<<"************************"<<endl; cout<<""<<errword<<"!"<<endl;}}string id_numtoname(int num)//{str *temp;string name;temp=string_head->next;while(temp!=NULL){if(num==temp->num){name=temp->word;break;。

编译原理课程设计之第六章 语义分析

编译原理课程设计之第六章 语义分析

mcy
2
语义分析的任务:
计算各类语法成分的语义信息(属性信息),一般将收集
的语义信息存放到相应的信息表中,在编译程序中符号 表是用来存放源程序中标示符相关属性(语义)信息的一 种信息表。 静态语义检查
类型检查:指类型相容问题的检查,如果操作符作用于不相容的操作数, 则编译器应该报错。 上下文有关问题的检查:当某个对象出现时,要求它必须在前面的某个 适当位置已经出现过。 唯一性检查:有时,要求某个对象只能被定义一次。 控制流检查:引起控制流从某个结构中跳转出来的语句,必须能够决定 控制流转向的目标地址。
(1)所采用的语法分析方法
(2)属性的计算次序。 语法分析方法都要求从左向右处理输入程 序,等价于要求属性能通过从左向右遍历 分析树进行赋值。
mcy
44
定义属性a1,...,ak 的一个属性文法是L-属性(Lattributed)文法,如果满足
mcy
37
num→digit
num.val=digit.val digit.base=num.base digit.val=0 digit.val=1 digit.val=7
digit→0 digit→1 ...... digit→7
mcy
38
digit→8
digit→9
if digit.base=8 then digit.val=error else digit.val= 8 if digit.base=8 then digit.val= error else digit.val 9
mcy
29
文法规则
语义规则 var-list.dtype = type.dtype type.dtype = integer type.dtype = real

编译原理中的词法分析与语法分析原理解析

编译原理中的词法分析与语法分析原理解析

编译原理中的词法分析与语法分析原理解析编译原理是计算机科学中的重要课程,它研究的是如何将源程序翻译成目标程序的过程。

而词法分析和语法分析则是编译过程中的两个重要阶段,它们负责将源程序转换成抽象语法树,为接下来的语义分析和代码生成阶段做准备。

本文将从词法分析和语法分析的原理、方法和实现技术角度进行详细解析,以期对读者有所帮助。

一、词法分析的原理1.词法分析的定义词法分析(Lexical Analysis)是编译过程中的第一个阶段,它负责将源程序中的字符流转换成标记流的过程。

源程序中的字符流是没有结构的,而编程语言是有一定结构的,因此需要通过词法分析将源程序中的字符流转换成有意义的标记流,以便之后的语法分析和语义分析的进行。

在词法分析的过程中,会将源程序中的字符划分成一系列的标记(Token),每个标记都包含了一定的语义信息,比如关键字、标识符、常量等等。

2.词法分析的原理词法分析的原理主要是通过有限状态自动机(Finite State Automaton,FSA)来实现的。

有限状态自动机是一个数学模型,它描述了一个自动机可以处于的所有可能的状态以及状态之间的转移关系。

在词法分析过程中,会将源程序中的字符逐个读取,并根据当前的状态和字符的输入来确定下一个状态。

最终,当字符读取完毕时,自动机会处于某一状态,这个状态就代表了当前的标记。

3.词法分析的实现技术词法分析的实现技术主要有两种,一种是手工实现,另一种是使用词法分析器生成工具。

手工实现词法分析器的过程通常需要编写一系列的正则表达式来描述不同类型的标记,并通过有限状态自动机来实现这些正则表达式的匹配过程。

这个过程需要大量的人力和时间,而且容易出错。

而使用词法分析器生成工具则可以自动生成词法分析器的代码,开发者只需要定义好源程序中的各种标记,然后通过这些工具自动生成对应的词法分析器。

常见的词法分析器生成工具有Lex和Flex等。

二、语法分析的原理1.语法分析的定义语法分析(Syntax Analysis)是编译过程中的第二个阶段,它负责将词法分析得到的标记流转换成抽象语法树的过程。

编译原理课程设计语义

编译原理课程设计语义

编译原理课程设计语义一、教学目标本课程旨在让学生掌握编译原理的基本概念、理论及其在实际编译器设计与实现中的应用。

通过本课程的学习,学生将能够:1.知识目标:–理解编译原理的基本概念,如文法、语法分析、语义分析、中间代码生成、目标代码生成等;–掌握编译器的主要组成部分及其作用;–了解编译器优化技术及其应用。

2.技能目标:–能够使用编译原理相关工具,如词法分析器、语法分析器、编译器生成器等;–能够独立完成简单编译器的设计与实现;–能够对编译器进行性能分析和优化。

3.情感态度价值观目标:–培养学生的抽象思维能力和问题解决能力;–培养学生对计算机科学领域的探索精神和创新意识;–培养学生对编译原理的兴趣,提高其对计算机科学的热情。

二、教学内容本课程的教学内容主要包括以下几个部分:1.编译原理基本概念:介绍编译器的基本概念、编译过程及编译器的主要组成部分;2.词法分析:讲解词法分析的基本方法、词法分析器的实现及其优化;3.语法分析:介绍语法分析的基本方法、语法分析器的实现及其优化;4.语义分析:讲解语义分析的基本方法、语义分析器的实现及其优化;5.中间代码生成:介绍中间代码生成的基本方法及其优化;6.目标代码生成:讲解目标代码生成的基本方法及其优化;7.编译器优化:介绍编译器优化技术及其应用。

三、教学方法为了提高教学效果,本课程将采用多种教学方法,如:1.讲授法:通过讲解编译原理的基本概念、理论及其应用,使学生掌握相关知识;2.讨论法:学生进行小组讨论,培养学生的思考能力和问题解决能力;3.案例分析法:分析实际编译器的设计与实现案例,使学生更好地理解编译原理;4.实验法:让学生动手实现简单编译器,提高学生的实践能力。

四、教学资源为了支持本课程的教学,我们将准备以下教学资源:1.教材:《编译原理》(推荐使用国内外经典教材);2.参考书:提供相关领域的参考书籍,以便学生深入学习;3.多媒体资料:制作PPT、教学视频等,丰富教学手段;4.实验设备:提供计算机及相关软件,供学生进行实验和实践。

编译原理词法分析和语法分析

编译原理词法分析和语法分析
if(ch=='=')
{ syn=21;
token[m++]=ch;
}
else
{ syn=31;
p--;
}
break;
case '=':token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{ syn=25;
token[m++]=ch;
}
else
{ syn=18;
p--;
}
break;
break;
case -1:printf("you have input a wrong string\n");
getch();
exit(0);
default: printf("( %-10s%5d )\n",token,syn);
break;
}
}while(syn!=0);
getch();
}
scaner()
printf("success!\n");
}
else { if(kk!=1) printf("the string haven't got a 'end'!\n");
kk=1;
}
}
else { printf("haven't got a 'begin'!\n");
kk=1;
}
return;
}
yucu()
if(syn==18)
{ scaner();/*读下一个单词符号*/

C语言编译原理词法分析和语法分析

C语言编译原理词法分析和语法分析

C语言编译原理词法分析和语法分析编程语言的编写和使用离不开编译器的支持,而编译器的核心功能之一就是对代码进行词法分析和语法分析。

C语言作为一种常用的高级编程语言,也有着自己的词法分析和语法分析规则。

一、词法分析词法分析是编译器的第一阶段,也是将源代码拆分为一个个独立单词(token)的过程。

在C语言中,常见的单词包括关键字(如if、while等)、标识符(如变量名)、常量(如数字、字符常量)等。

词法分析器会根据预定义的规则对源代码进行扫描,并将扫描到的单词转化为对应的符号表示。

词法分析的过程可以通过有限自动机来实现,其中包括各种状态和状态转换规则。

词法分析器通常会使用正则表达式和有限自动机的方法来进行实现。

通过词法分析,源代码可以被分解为一个个符号,为后续的语法分析提供基础。

二、语法分析语法分析是编译器的第二阶段,也是将词法分析得到的单词序列转换为一棵具有语法结构的抽象语法树(AST)的过程。

在C语言中,语法分析器会根据C语言的文法规则,逐句解析源代码,并生成相应的语法树。

C语言的语法规则相对复杂,其中包括了各种语句、表达式、声明等。

语法分析的过程主要通过递归下降分析法、LR分析法等来实现。

语法分析器会根据文法规则建立语法树的分析过程,对每个语法结构进行逐步推导和分析,最终生成一棵完整的语法树。

三、编译器中的词法分析和语法分析在编译器中实现词法分析和语法分析是一项重要的技术任务。

编译器通常会将词法分析和语法分析整合在一起,形成一个完整的前端。

在C语言编译器中,词法分析和语法分析器会根据C语言的词法规则和文法规则,对源代码进行解析,并生成相应的中间表示形式,如语法树或者中间代码。

词法分析和语法分析的结果会成为后续编译器中各个阶段的输入,如语义分析、中间代码生成、目标代码生成等。

编译器的优化和错误处理也与词法分析和语法分析有密切关系。

因此,对词法分析和语法分析的理解和实现对于编译器开发者而言是非常重要的。

编译原理课程设计-词法分析器和语法分析器

编译原理课程设计-词法分析器和语法分析器

编译原理课程设计报告院系专业年级学号姓名2013年12月 8日课程设计一:手工设计C语言的词法分析器一、设计内容手工设计c语言的词法分析器,结合状态转换图的原理完成对c语言源程序的基本单词的分析及提取,并设计相应的数据结构保存提取出来的单词。

以及对c语言中的保留字的处理策略,实现一个完整的C语言的词法分析器的编写。

二、设计目的通过本实验的设计更具体的理解词法分析器的工作机制。

同时更理解C语言的结构体系。

从而更深刻的透析编译原理过程。

三、设计平台1、硬件环境(1)Intel(R) Core(TM) i3-2310M CPU @2.10GHz 2.10GHz(2)内存4G2、软件环境(1)Window8 Professor(2)Visual C++6.0开发软件3、开发语言:C语言。

四、需求分析:词法分析程序又称词法分析器或词法扫描器。

可以单独为一个程序;也可以作为整个编译程序的一个子程序,当需要一个单词时,就调用此法分析子程序返回一个单词,这里,作为子程序词法分析器的结构:状态转换图的程序实现为便于程序实现,假设每个单词间都有界符或运算符或空格隔开,并引入下面的全局变量及子程序:1) ch 存放最新读进的源程序字符2) strToken存放构成单词符号的字符串3)Buffer 字符缓冲区4)struct keyType存放保留字的符号和种别五、概要设计保留字表的设计结构:基本功能状态转换:六、详细设计1.GETCHAR 读一个字符到 ch中2.GETBC 读一个非空白字符到ch中3.CONCAT 把CHAR 中字符连接到strToken 之后4.LETTER 判断CHAR 中字符是否为字母5.DIGIT 判断ch中字符是否为数字6.RESERVE 用strToken中的字符串查找保留字表,并返回保留字种别码,若返回零,则非保留字7.RETRACT 把CHAR 中字符回送到缓冲区源程序:#include "stdio.h"#include "stdlib.h"#include "conio.h"#include "string.h"#define N 47 //保留字个数char ch='\0'; //存放最新读进的源程序字符char strToken[20]="\0"; //存放构成单词符号的字符串char buffer[257]="\0"; //字符缓冲区/*------------保留字结构-------------*/struct keyType{char keyname[256];int value;}Key[N]={{"$ID",0},{"$INT",1},{"auto",2},{"break",3},{"case",4},{"char",5},{"const",6},{"continue",7},{"default",8},{"do",9},{"double",10},{"else",11},{"enum",12},{"extern",13},{"float",14},{"for",15},{"goto",16},{"if",17},{"int",18},{"long",19},{"register",20},{"return",21},{"short",22},{"signed",23},{"sizeof",24},{"static",25},{"struct",26},{"switch",27},{"typedef",28},{"union",29},{"unsigned",30},{"void",31},{"volatile",32},{"while",33},{"=",34},{"+",35},{"-",36},{"*",37},{"/",38},{"%",39},{",",40},{";",41},{"(",42},{")",43},{"?",44},{"clear",45},{"#",46}};/*-------------子过程-------------*/void GetChar() //读一个字符到ch中{ int i;if(strlen(buffer)>0){ch=buffer[0];for(i=0;i<256;i++)buffer[i]=buffer[i+1];}elsech='\0';}void GetBC() //读一个非空白字符到ch中{ int i;while(strlen(buffer)){i=0;ch=buffer[i];for(;i<256;i++)buffer[i]=buffer[i+1];if(ch!=' '&&ch!='\n'&&ch!='\0') break;}}void ConCat() //把ch连接到strToken之后{ char temp[2];temp[0]=ch;temp[1]='\0';strcat(strToken,temp);}bool Letter() //判断ch是否为字母{ if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')return true;elsereturn false;}bool Digit() //判断ch是否为数字{ if(ch>='0'&&ch<='9')return true;elsereturn false;}int Reserve() //用strToken中的字符查找保留字表,并返回保留字种别码,若返回0,则非保留字{ int i;for(i=0;i<N;i++)if(strcmp(strToken,Key[i].keyname)==0)return Key[i].value;return 0;}void Retract() //把ch中的字符回送到缓冲区{ int i;if(ch!='\0') {buffer[256]='\0';for(i=255;i>0;i--)buffer[i]=buffer[i-1];buffer[0]=ch;}ch='\0';}/*----------词法分析器------------*/keyType ReturnWord(){ strcpy(strToken,"\0");int c;keyType tempkey;GetBC();if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z') {。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理课程设计说明书题目:编译器原型设计与开发院(系):计算机科学与工程学院专业:计算机科学与技术目录1 引言 (1)1.1 设计概述 (1)1.2 设计目标 (2)1.3 小组分工 (3)2 开发过程 (3)2.1 词法分析 (3)2.1.1 消除白空格以及注释 (3)2.1.2 词法分析 (6)2.2 .语法分析 (8)2.2.1 递归下降手工编码 (8)2.2.2 first集合的计算 (8)2.2.3 左递归消除 (9)2.2.4 selection表自动生成 (10)2.2.5 LL(1)手工编码 (11)2.3 语义分析 (11)2.3.1 表达式求值LR(1) (11)2.3.2 四元式 (13)3 测试过程 (14)4 总结 (19)5 参考文献 (20)6 代码附录 (20)1引言编译程序是现代计算机系统的基本组成部分之一,而且多数计算机系统都配有不止一个高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序。

从功能上看,一个编译程序就是一个语言翻译程序。

语言翻译程序把一种语言(称作源语言)书写的程序翻译成另一种语言(称作目标语言)的等价程序。

一个编译程序的重要性体现在它使得多数计算机用户不必考虑与机器有关的繁琐细节,使程序员和程序设计专家独立于机器,这对于当今机器的数量和种类持续不断地增长的年代尤为重要。

编译程序完成从源程序到目标程序的翻译工作,是一个复杂的整体的过程。

将编译过程划分成词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成六个阶段。

1.1设计概述编译原理程序结构框图词法分析词法分析是编译过程的第一个阶段。

这个阶段的任务是从左到右有一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。

这里所谓的单词是指逻辑上紧密相连的一组字符,这些字符基友具体含义。

比如标识符是由字母字符开头,后跟字母、数字字符的字符序列组成的一种单词。

保留字(关键字或基本字)是一种单词,此外还有算符、界符等。

语法分析语法分析是编译过程的第二个阶段。

语法分析的任务是在词法分析的基础上将单词序列分解成各类语法短语,如“程序”、“语句”、“表达式”等。

一般这种语法短语,也称语法单位,可表示成语法树。

语法分析所依据的是语言的语法规则,即描述程序结构的规则。

通过语法分析确定整个输入串是否构成一个语法上正确的程序。

语义分析语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。

比如语义分析的一个工作是进行类型审查,审查每个算符是否具有语言规范允许的运算对象,当不符合语言规范时,编译程序应报告错误。

中间代码生成在进行了上述的语法分析和语义分析阶段的工作之后,有的编译程序将源代码变成一种内部表示形式,这种内部表示形式叫做中间语言或中间代码。

所谓“中间代码”是一种结构简单、含义明确的记号系统,这种记号系统可以设计为多种多样的形式,重要的设计原则为两点:一是容易生成;二是容易将它翻译成目标代码。

很多编译程序采用了一种近似“三地址指令”的“四元式”的中间代码,这种四元式的形式为:(运算符,运算对象1,运算对象2,结果)。

1.2设计目标鉴于我们需要完成编译器的词法分析、语法分析、语义分析、中间代码生成的设计开发,本次课程设计主要完成以下任务:词法分析:1.消除白空格2.消除注释3.词法分析语法分析:4.递归下降手工编码5.first集合的计算6.follow集合的自动计算7.selection表自动生成8.递归下降自动生成9.LL(1)分析手工编码10.LL(1)自动生成11.LR(1)分析手工编码12.左递归消除语义分析以及中间代码生成:13.中缀式转后缀式递归下降编码14.中缀式转后缀式LL(1)编码15.中缀式转后缀式LR1)编码16.表达式求值LL(1)17.表达式求值LR(1)18.四元式1.3小组分工2开发过程2.1词法分析2.1.1消除白空格以及注释这个模块实现的功能主要是对代码中多余的白空格以及注释进行消除。

在文本中输入一段代码,其中可以有多余的空格和注释,经过这个程序运行后,将实现多余空格,注释去除。

设计思路:这个模块一共有6个状态,设为0,1,2,3,4,5,其中状态转换图:字符转换表Ch_Type_Table:为了消除注释需要。

其中在程序中f_留表示为f_save;f_改表示为f_change;f_补表示为f_add;f_删表示为f_delete;Action_Table表示为void(*Action_Table[6][6])(void)。

2.1.2词法分析设计思路:1、把消除白空格、消除注释、识别标识符id,识别整数di,识别运算符、识别界符、识别双引号内的注释分层次画状态机,使状态机清晰易懂,方便其他同学学习;2、以0状态为中转,每一层次的状态机遇到不是该层次的内容(识别了一个词元,当前输入不是该词元的内容了),回到0状态去判断该字符应转向的状态。

3、使用了ungetc()函数,输入回退一个字符,回到0状态中转之前,如果该字符并没有做处理,要ungetc,回退到输入流,那么从0状态会再读出之前没有处理的字符,再判断转换;4、词元存储,用结构体存储数组存储;不同类型的词元对应不同的表,词元结构体中存储的是,该词元的类型(也即表的类型)、在该表中的下标(可以通过该下标找到对应词元的相关信息,便于后期扩展)、该词元在测试代码中的坐标(x,y)。

不同类型的词元表有程序动态维护。

表的动态维护对与整个编译程序很重要。

struct Data{int type; //表类型:id=0,num=1,运算符2 界符3int value; //在表中的下标int pos_x,pos_y;//源代码位置};本模块一共有13个状态,0—12,其中词法分析状态转换图为:说明:1、字符转换表:字母,下划线(_)化为一类,为识别标识符用。

0单独处理是用于识别单个0和以0开头的错误整数;这里的运算符是指可以和“=”连在一起作为一个词元的,如>=,<=,+=,-+,*=,/=;界符是指一个字符做为一个词元的,如{}();,等。

2、函数说明:f_留,表示将当前字符存到缓冲数组里面;f_读,提取词元,从缓冲数组里面读出当前词元,并将缓冲数组清空;f_回,转到中转0状态之前,将当前字符回退到输入流中。

f_留2:为后面添加,单个字符组成的词元,不用存到缓冲数组里面,直接提取成一个词元,存到词元结构体数组里面。

2.2.语法分析2.2.1递归下降手工编码这个模块是给定状态转换表,action表,之后对输入的表达式进行词法分析,判断表达式正误。

其中文法如下:E:=TE’E’:=+TE’|@T:=FT’T’:=*FT’|@F:=id|di|(E)所定义的函数为:void f_exp();void f_term();void f_factor();void f_term_remains();void f_exp_remains();2.2.2first集合的计算这个模块进行的是first集合的计算。

定义的文法存储数据结构为:struct define {char left;string right;};设计思路:整体上采用不动点算法依次扫描每条文法右部,若遇到终止符,则将该终止符加入文法左部非终止符的first集中。

如果遇到非终止符,则先判断该终止符的first集合中是否包含@(“@”代表“可空”),如果不包含@,则将该非终止符的first集加到文法左部的非终止符的first集中;如果包含@,并且该非终止符不是最后一个非终止符,则将该非终止符的first集合去掉@后,加到文法左部的first集合中;否则直接将此非终止符的first集合加到文法左部的first集合中。

具体描述如下:对于任意给定的LL(1) 文法G,为了构造它的预测分析表M,我们就必须构造与文法G有关的集合First和fellow.首先我们对每一个X∈VT U Vn ,构造FIRST(X),办法是,连续使用下面的规则,直至每个集合FIRST不再增大为止. (1)若X∈VT,,则FIRST(X)={X}.(2)若X∈Vn ,且有产生式X->a……,则把a加入到FIRST(X)中,若X->ε,也是一条产生式,则把ε也加到FIRST(X)中.(3)若X->Y……是一个产生式且Y∈Vn,则把FIRST(Y)中所有非ε-元素都加到FIRST(X)中,若X->Y1Y2……YK ,是一个连续的产生式, Y1Y2……Yi-1 都是非终结符,而且,对于任何j,1≤j≤i-1,FIRST(Yj) 都含有ε(即Y1Y2……Yi-1=>ε),则把FIRST(Yi) 中的所有非ε-元素都加到FIRST(X)中,特别是,若所有的FIRST(Yj)均含有ε,j=1,2,……,k,则把ε加到FIRST(X)中.辅助函数:/*统计文法条数,非终止符个数,终止符个数,并把非终止符,终止符弄成一个字符串,用于查找下标*/void get_gene() //获得产生式,并统计int get_index(char b); //得到终止符或非终止符的统一下标void add(string &tLeft , string s);将s添加到tLeft中,即将右边的字符串添加到左边的字符串中,去掉重复,如果右边存在新的字符,要将flag置为 1 ,用于不动点算法。

2.2.3左递归消除设计思路:将间接左递归变成左递归,然后消除直接左递归。

(1)把文法的所有非终止符按某一顺序排序,如:A1,A2,…….An;(2)从A1开始消除都为A1的产生式的直接左递归,然后把左部为A1的所有规则的右部逐个替换为A2开始的产生式中的A1,并消除左部位A2的产生式中的直接左递归,继而以同样的方式吧A2的右部代入左部为A3右部以A1或A2开始的产生式中,消除左部为A3的产生式之直接左递归,直到把左部为A1,A2,…….An-1的右部代入左部为An的产生式中,从An中消除直接左递归。

把上述算法归结为:如非终止符的排序为:A1,A2,…….AnFOR i:=1 TO N DOBEGINFOR j:=1 TO i-1 DOBEGIN如Aj的所有产生式为:Aj->a1|a2|….|ak替换形成Ai->Ajr的产生式变为:Ai->a1r|a2r|….|akrEND消除Ai中的一切直接左递归.END.(3)去掉无用产生式。

2.2.4selection表自动生成设计思路:扫描文法,计算文法右部的first集合(“@”不计算在内),直接将文法去右部填入文法右部计算得到的相应first集合和文法左部对应的selection表项中。

相关文档
最新文档