其中動(dòng)作符號(hào)的含義如下
@BRF↑label1 :輸出 BRF label1,
@BR↑label2:輸出 BR label2,
@SETlabel↓label1:設(shè)置標(biāo)號(hào)label1
@SETlabel↓label2:設(shè)置標(biāo)號(hào)label2
*/
int if_stat(){
int es=0,label1,label2; //if
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
if (strcmp(token,“(”)) return(es=5); //少左括號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=expression();
if (es》0) return(es);
if (strcmp(token,“)”)) return(es=6); //少右括號(hào)
label1=labelp++;//用label1記住條件為假時(shí)要轉(zhuǎn)向的標(biāo)號(hào)
fprintf(fout,“ BRF LABEL%d/n”,label1);//輸出假轉(zhuǎn)移指令
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=statement();
if (es》0) return(es);
label2=labelp++;//用label2記住要轉(zhuǎn)向的標(biāo)號(hào)
fprintf(fout,“ BR LABEL%d/n”,label2);//輸出無(wú)條件轉(zhuǎn)移指令
fprintf(fout,“LABEL%d:/n”,label1);//設(shè)置label1記住的標(biāo)號(hào)
if (strcmp(token,“else”)==0)//else部分處理
{
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=statement();
if (es》0) return(es);
}
fprintf(fout,“LABEL%d:/n”,label2);//設(shè)置label2記住的標(biāo)號(hào)
return(es);
}
//《while_stat》::= while (《expr 》) 《 statement 》
//《while_stat》::=while @SET↑labellabel1(《expression》) @BRF↑label2
// 《statement 》@BR↑label1 @SETlabel↓label2
//動(dòng)作解釋如下:
//@SETlabel↑label1:設(shè)置標(biāo)號(hào)label1
//@BRF↑label2 :輸出 BRF label2,
//@BR↑label1:輸出 BR label1,
//@SETlabel↓label2:設(shè)置標(biāo)號(hào)label2
int while_stat()
{
int es=0,label1,label2;
label1=labelp++;
fprintf(fout,“LABEL%d:/n”,label1);//設(shè)置label1標(biāo)號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
if (strcmp(token,“(”)) return(es=5); //少左括號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=expression();
if (es》0) return(es);
if (strcmp(token,“)”)) return(es=6); //少右括號(hào)
label2=labelp++;
fprintf(fout,“ BRF LABEL%d/n”,label2);//輸出假轉(zhuǎn)移指令
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=statement();
if (es》0) return(es);
fprintf(fout,“ BR LABEL%d/n”,label1);//輸出無(wú)條件轉(zhuǎn)移指令
fprintf(fout,“LABEL%d:/n”,label2);//設(shè)置label2標(biāo)號(hào)
return(es);
}
//《for_stat》::= for(《expr》,《expr》,《expr》)《statement》
/*
《for_stat》::=for (《expression》;
@SETlabel↓label1《 expression 》@BRF↑label2@BR↑label3;
@SETlabel↓label4 《 expression 》@BR↑label1)
@SETlabel↓label3 《語(yǔ)句 》@BR↑label4@SETlabel↓label2
動(dòng)作解釋?zhuān)?/p>
1. @SETlabel↓label1:設(shè)置標(biāo)號(hào)label1
2. @BRF↑label2 :輸出 BRF label2,
3. @BR↑label3:輸出 BR label3,
4. @SETlabel↓label4:設(shè)置標(biāo)號(hào)label4
5. @BR↑label1:輸出 BR label1,
6. @SETlabel↓label3:設(shè)置標(biāo)號(hào)label3
7. @BR↑label4:輸出 BR label4,
8. @SETlabel↓label2:設(shè)置標(biāo)號(hào)label2
*/
int for_stat()
{
int es=0,label1,label2,label3,label4;
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
if (strcmp(token,“(”)) return(es=5); //少左括號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=expression();
if (es》0) return(es);
if (strcmp(token,“;”)) return(es=4); //少分號(hào)
label1=labelp++;
fprintf(fout,“LABEL%d:/n”,label1);//設(shè)置label1標(biāo)號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=expression();
if (es》0) return(es);
label2=labelp++;
fprintf(fout,“ BRF LABEL%d/n”,label2);//輸出假條件轉(zhuǎn)移指令
label3=labelp++;
fprintf(fout,“ BR LABEL%d/n”,label3);//輸出無(wú)條件轉(zhuǎn)移指令
if (strcmp(token,“;”)) return(es=4); //少分號(hào)
label4=labelp++;
fprintf(fout,“LABEL%d:/n”,label4);//設(shè)置label4標(biāo)號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=expression();
if (es》0) return(es);
fprintf(fout,“ BR LABEL%d/n”,label1);//輸出無(wú)條件轉(zhuǎn)移指令
if (strcmp(token,“)”)) return(es=6); //少右括號(hào)
fprintf(fout,“LABEL%d:/n”,label3);//設(shè)置label3標(biāo)號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=statement();
if (es》0) return(es);
fprintf(fout,“ BR LABEL%d/n”,label4);//輸出無(wú)條件轉(zhuǎn)移指令
fprintf(fout,“LABEL%d:/n”,label2);//設(shè)置label2標(biāo)號(hào)
return(es);
}
//《write_stat》::=write 《expression》;
//《write_stat》::=write 《expression》@OUT;
//動(dòng)作解釋?zhuān)?/p>
//@ OUT:輸出 OUT
int write_stat()
{
int es=0;
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=expression();
if (es》0)return(es);
if (strcmp(token,“;”)) return(es=4); //少分號(hào)
fprintf(fout,“ OUT/n”);//輸出指令
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
return(es);
}
//《read_stat》::=read ID;
//《read_stat》::=read ID↑n LOOK↓n↑d @IN@STI↓d;
//動(dòng)作解釋?zhuān)?/p>
//@LOOK↓n↑d:查符號(hào)表n,給出變量地址d; 沒(méi)有,變量沒(méi)定義
//@IN:輸出IN
//@STI↓d:輸出指令代碼STI d
int read_stat()
{
int es=0,address;
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
if (strcmp(token,“ID”)) return(es=3); //少標(biāo)識(shí)符
es=lookup(token1,&address);
if (es》0) return(es);
fprintf(fout,“ IN /n”);//輸入指令
fprintf(fout,“ STI %d/n”,address);//指令
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
if (strcmp(token,“;”)) return(es=4); //少分號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
return(es);
}
//《compound_stat》::={《statement_list》}
int compound_stat(){ //復(fù)合語(yǔ)句函數(shù)
int es=0;
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=statement_list();
return(es);
}
//《expression_stat》::=《expression》;|;
int expression_stat()
{
int es=0;
if (strcmp(token,“;”)==0)
{
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
return(es);
}
es=expression();
if (es》0) return(es);
if (strcmp(token,“;”)==0)
{
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
return(es);
} else
{
es=4;
return(es);//少分號(hào)
}
}
//《expression》::=ID↑n@LOOK↓n↑d@ASSIGN=《bool_expr》@STO↓d |《bool_expr》
int expression()
{
int es=0,fileadd;
char token2[20],token3[40];
if (strcmp(token,“ID”)==0)
{
fileadd=ftell(fp); //@ASSIGN記住當(dāng)前文件位置
fscanf(fp,“%s %s/n”, &token2,&token3);
printf(“%s %s/n”,token2,token3);
if (strcmp(token2,“=”)==0) //‘=’
{
int address;
es=lookup(token1,&address);
if (es》0) return(es);
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=bool_expr();
if (es》0) return(es);
fprintf(fout,“ STO %d/n”,address);
} else
{
fseek(fp,fileadd,0); //若非‘=’則文件指針回到‘=’前的標(biāo)識(shí)符
printf(“%s %s/n”,token,token1);
es=bool_expr();
if (es》0) return(es);
}
} else es=bool_expr();
return(es);
}
//《bool_expr》::=《additive_expr》
// |《 additive_expr 》(》|《|》=|《=|==|!=)《 additive_expr 》
/*
《bool_expr》::=《additive_expr》
|《 additive_expr 》》《additive_expr》@GT
|《 additive_expr 》《《additive_expr》@LES
|《 additive_expr 》》=《additive_expr 》@GE
|《 additive_expr 》《=《 additive_expr 》@LE
|《 additive_expr 》==《 additive_expr 》@EQ
|《 additive_expr 》!=《 additive_expr 》@NOTEQ
*/
int bool_expr()
{
int es=0;
es=additive_expr();
if(es》0) return(es);
if ( strcmp(token,“》”)==0 || strcmp(token,“》=”)==0
||strcmp(token,“《”)==0 || strcmp(token,“《=”)==0
||strcmp(token,“==”)==0|| strcmp(token,“!=”)==0)
{
char token2[20];
strcpy(token2,token);//保存運(yùn)算符
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=additive_expr();
if(es》0) return(es);
if ( strcmp(token2,“》”)==0 ) fprintf(fout,“ GT/n”);
if ( strcmp(token2,“》=”)==0 ) fprintf(fout,“ GE/n”);
if ( strcmp(token2,“《”)==0 ) fprintf(fout,“ LES/n”);
if ( strcmp(token2,“《=”)==0 ) fprintf(fout,“ LE/n”);
if ( strcmp(token2,“==”)==0 ) fprintf(fout,“ EQ/n”);
if ( strcmp(token2,“!=”)==0 ) fprintf(fout,“ NOTEQ/n”);
}
return(es);
}
//《additive_expr》::=《term》{(+|-)《 term 》}
//《 additive_expr》::=《term》{(+《 term 》@ADD |-《項(xiàng)》@SUB)}
int additive_expr()
{
int es=0;
es=term();
if(es》0) return(es);
while (strcmp(token,“+”)==0 || strcmp(token,“-”)==0)
{
char token2[20];
strcpy(token2,token);
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=term();
if(es》0) return(es);
if ( strcmp(token2,“+”)==0 ) fprintf(fout,“ ADD/n”);
if ( strcmp(token2,“-”)==0 ) fprintf(fout,“ SUB/n”);
}
return(es);
}
//《 term 》::=《factor》{(*| /)《 factor 》}
//《 term 》::=《factor》{(*《 factor 》@MULT | /《 factor 》@DIV)}
int term()
{
int es=0;
es=factor();
if(es》0) return(es);
while (strcmp(token,“*”)==0 || strcmp(token,“/”)==0)
{
char token2[20];
strcpy(token2,token);
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=factor();
if(es》0) return(es);
if ( strcmp(token2,“*”)==0 ) fprintf(fout,“ MULT/n”);
if ( strcmp(token2,“/”)==0 ) fprintf(fout,“ DIV/n”);
}
return(es);
}
//《 factor 》::=(《additive_expr》)| ID|NUM
//《 factor 》::=(《 expression 》)| ID↑n@LOOK↓n↑d@LOAD↓d |NUM↑i@LOADI↓i
int factor()
{
int es=0;
if (strcmp(token,“(”)==0)
{
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
es=expression();
if (es》0) return(es);
if (strcmp(token,“)”)) return(es=6); //少右括號(hào)
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
} else
{
if (strcmp(token,“ID”)==0)
{
int address;
es=lookup(token1,&address);//查符號(hào)表,獲取變量地址
if (es》0) return(es);//變量沒(méi)聲明
fprintf(fout,“ LOAD %d/n”,address);
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
return(es);
}
if (strcmp(token,“NUM”)==0)
{
fprintf(fout,“ LOADI %s/n”,token1);
fscanf(fp,“%s %s/n”,&token,&token1);
printf(“%s %s/n”,token,token1);
return(es);
}else
{
es=7;//缺少操作數(shù)
return(es);
}
}
return(es);
}
//主程序
void main(){
int es=0;
es=TESTscan();//調(diào)詞法分析
if (es》0) printf(“詞法分析有錯(cuò),編譯停止!”);
else printf(“詞法分析成功!/n”);
if (es==0)
{
es=TESTparse(); //調(diào)語(yǔ)法、語(yǔ)義分析并生成代碼
if (es==0) printf(“語(yǔ)法、語(yǔ)義分析并生成代碼成功!/n”);
else printf(“語(yǔ)法、語(yǔ)義分析并生成代碼錯(cuò)誤!/n”);
}
}
下面我們可以進(jìn)行測(cè)試:如下我挑了幾個(gè)典型的。大家可以看看。
評(píng)論
查看更多