编译原理-实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
程序清单
1.分工:
2.词法分析:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define keywordSum 8
char *keyword[keywordSum]={"if","else","for","while","do","int","read","write"}; char singleword[50]="+ - * ( ) { } ; , :";
char doubleword[10]="><=!";
extern char Scanin[300],Scanout[300];
extern FILE *fin,*fout;
int TESTscan()
{ char ch,token[40];
int es=0,j,n;
printf("请输入源程序文件名(包括路径):");
scanf("%s",Scanin);
printf("请输入词法分析输出文件名(包括路径):");
scanf("%s",Scanout);
if((fin=fopen(Scanin,"r"))==NULL)
{ printf("\n打开词法分析输入文件出错!\n");
return(1); }
if((fout=fopen(Scanout,"w"))==NULL)
{ printf("\n创建词法分析输出文件出错!\n");
return(2);}
ch=getc(fin);
while(ch!=EOF)
{ while(ch==' '||ch=='\n'||ch=='\t') ch=getc(fin);
if(isalpha(ch))
{ token[0]=ch;j=1;
ch=getc(fin);
while(isalnum(ch))
{ token[j++]=ch;
ch=getc(fin); }
token[j]='\0';
n=0;
while ((n<keywordSum) && strcmp(token,keyword[n])) n++;
if(n>=keywordSum)
fprintf(fout,"%s\t%s\n","ID",token);
else
fprintf(fout,"%s\t%s\n",token,token);
{
token[0]=ch;j=1;
ch=getc(fin);
while(isdigit(ch))
{ token[j++]=ch;
ch=getc(fin); }
token[j]='\0';
fprintf(fout,"%s\t%s\n","NUM",token);
}else if(strchr(singleword,ch)>0)
{
token[0]=ch;token[1]='\0';
ch=getc(fin);
fprintf(fout,"%s\t%s\n",token,token);
}else if (strchr(doubleword,ch)>0)
{
token[0]=ch;
ch=getc(fin);
if(token[0]=='!')
{ if (ch == '=')
{
token[1]=ch; token[2]='\0';
ch = getc(fin);
fprintf(fout,"%s\t%s\n",token,token);
}
else
{
token[1]='\0';
es=1;
fprintf(fout,"%s\t%s\n","ERROR",token);
}
}
else{
if (ch == '=')
{
token[1]=ch; token[2]='\0';
ch = getc(fin);
}else
token[1]='\0';
fprintf(fout,"%s\t%s\n",token,token);
}
}else if (ch=='/')
{
ch = getc(fin);
{
char ch1;
ch1=getc(fin);
do
{
ch=ch1; ch1=getc(fin);
}while((ch!='*' || ch1!='/') && ch1!=EOF);
ch = getc(fin);
}else if(ch=='/'){
do{
ch=getc(fin);
}while(ch!='\n' && ch!=EOF);
ch=getc(fin);
}else
{
token[0]='/'; token[1]='\0';
fprintf(fout,"%s\t%s\n",token,token);
}
}else
{
token[0]=ch; token[1]='\0';
ch=getc(fin);
es = 3;
fprintf(fout,"%s\t%s\n","ERROR",token);
}
}
fclose(fin);
fclose(fout);
return (es);
}
3.语法分析:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<conio.h>
int TESTparse();
int program();
int compound_Stat();
int statement();
//int expression_Stat();
int expression_stat();
int expression();
int bool_expr();
int additive_expr();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
char token[20], token1[40]; ///token保存单词符号,token1保存单词值extern char Scanout[300]; ///保存词法分析输出文件名
FILE * fp; ///用于指向输入文件的指针
#define keywordSum 8
char *keyword[keywordSum]={"if","else","for","while","do","int","read","write"}; char singleword[50]="+ - * ( ) { } ; , :";
char doubleword[10]="><=!";
extern char Scanin[300],Scanout[300];
extern FILE *fin,*fout;
///语法分析程序
int TESTparse()
{
int es = 0;
if ((fp=fopen(Scanout,"r"))==NULL)
{
printf("\n打开%s错误!\n",Scanout);
es = 0;
}
if (es==0) es=program();
printf("=====语法分析结果!======\n");
switch(es)
{
case 0: printf("语法分析成功!\n"); break;
case 10: printf("打开文件%s失败!\n"); break;
case 1: printf("缺少{!\n"); break;
case 2: printf("缺少}!\n"); break;
case 3: printf("缺少标识符!\n"); break;
case 4: printf("少分号!\n"); break;
case 5: printf("缺少(!\n"); break;
case 6: printf("缺少)!\n"); break;
case 7: printf("缺少操作数!\n"); break;
}
fclose(fp);
return(es);
}
///<程序>::={<声明序列><语句序列>}
int program()
{
int es = 0;
fscanf(fp, "%s%s\n",token,token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"{")) ///判断是否为'{' {
es = 1;
return (es);
}
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es = declaration_list();
if(es>0) return (es);
es = statement_list();
if(strcmp(token, "}")) ///判断是否为'}' {
es = 2;
return (es);
}
return(es);
}
///<声明序列>::=<声明序列><声明语句>|空
int declaration_list()
{
int es=0;
while(strcmp(token,"int")==0)
{
es=declaration_stat();
if(es>0) return (es);
}
return (es);
}
///<声明语句>::=int <变量>;
int declaration_stat()
{
int es=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"ID")) return (es=3); ///不是标识符
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,";")) return (es=4);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return (es);
}
///<语句序列>::=<语句序列><语句>|空
int statement_list()
{
int es=0;
while(strcmp(token,"}"))
{
es=statement();
if(es>0) return (es);
}
return (es);
}
///<语句>::=<if语句>|<while语句>|<for语句>|<read语句>|<read语句>
/// <write语句>|<复合语句>|<表达式语句>
int statement()
{
int es=0;
if(es==0 && strcmp(token,"if")==0) es=if_stat(); ///<if语句>
if(es==0 && strcmp(token,"while")==0) es=while_stat(); ///<while语句>
if(es==0 && strcmp(token,"for")==0) es=for_stat(); ///<for语句>
///可在此处添加do语句调用
if(es==0 && strcmp(token,"read")==0) es=read_stat(); ///<read语句>
if(es==0 && strcmp(token,"write")==0) es=write_stat(); ///<write语句>
if(es==0 && strcmp(token,"{")==0) es=compound_stat(); ///<复合语句>
if(es==0 && strcmp(token,"ID")==0 || strcmp(token,"NUM")==0)
es=expression_stat(); ///表达式语句> return (es);
}
///<if语句>::=if(<表达式>)<语句>|[else<语句>]
int if_stat()
{
int es=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"(")) return (es=5);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement();
if(es>0) return(es);
if(strcmp(token,")")) return(es=6);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement();
if(es>0) return(es);
if(strcmp(token,"else")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement();
if(es>0) return(es);
}
return(es);
}
///<while语句>::=while(<表达式>)<语句>
int while_stat()
{
int es=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"(")) return (es=5);
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);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es = statement();
return(es);
}
///<for语句>::=for(<表达式>;<表达式>;<表达式>)<语句> int for_stat()
{
int es=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"(")) return (es=5);
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);
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);
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);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=expression();
return (es);
}
///<write_语句>::=write<表达式>;
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);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}
///<raed_语句>::=read<变量>;
int read_stat()
{
int es=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,"ID")) return (es=3);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
if(strcmp(token,";")) return (es=4);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return(es);
}
///<复合语句>::={<语句序列>}
int compound_stat() ///复合语句函数{
int es=0;
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=statement_list();
return (es);
}
///<表达式语句>::=<表达式>;|;
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(es==0 && strcmp(token,";")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return (es);
}else
{
es=4;
return (es); ///少分号
}
}
///<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
int expression()
{
int es=0, fileadd;
char token2[20], token3[40];
if(strcmp(token,"ID")==0)
{
fileadd=ftell(fp); ///记住问件当前位置
fscanf(fp,"%s%s\n",&token2,&token3);
printf("%s%s\n",token2,token3);
es=bool_expr();
if(es>0) return(es);
if(strcmp(token2,"=")==0) ///'='
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
}else
{
fseek(fp,fileadd,0); ///若非‘=’则文件指针回到'='前边的标识符
printf("%s%s\n",token,token1);
es=bool_expr();
if(es>0) return(es);
}
}else es=bool_expr();
return (es);
}
///<布尔表达式>::=<算数表达式>|<算术表达式>(>|<|>=|<=|==|!=)
///<算术表达式>
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)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=additive_expr();
if(es>0) return(es);
}
return (es);
}
///<算术表达式>::=<项>{(+|-)<项>}
int additive_expr()
{
int es=0;
es=term();
if(es>0) return(es);
while(strcmp(token,"+")==0 || strcmp(token,"-")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=term();
if(es>0) return(es);
}
return (es);
}
///<项>::=<因子>{(*|/)<因子>}
int term()
{
int es=0;
es=factor();
if(es>0) return(es);
while(strcmp(token,"*")==0 || strcmp(token,"/")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
es=factor();
if(es>0) return(es);
}
return (es);
}
///<因子>::=(<表达式>)|<标识符>|<无符号整数>
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);
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
}else
{
if(strcmp(token,"ID")==0 || strcmp(token,"NUM")==0)
{
fscanf(fp,"%s%s\n",&token,&token1);
printf("%s%s\n",token,token1);
return (es);
}else
{
es=7; ///缺少操作数
return (es);
}
}
return (es);
}
int TESTscan()
{
char ch,token[40];
int es=0,j,n;
printf("请输入源程序文件名(包括路径):");
scanf("%s",Scanin);
printf("请输入词法分析输出文件名(包括路径):");
scanf("%s",Scanout);
if((fin=fopen(Scanin,"r"))==NULL)
{
printf("\n打开词法分析输入文件出错!\n");
return(1);
}
if((fout=fopen(Scanout,"w"))==NULL)
{
printf("\n创建词法分析输出文件出错!\n");
return(2);
}
ch=getc(fin);
while(ch!=EOF)
{
while(ch==' '||ch=='\n'||ch=='\t')ch=getc(fin);
if(isalpha(ch))
{
token[0]=ch;j=1;
ch=getc(fin);
while(isalnum(ch))
{
token[j++]=ch;
ch=getc(fin);
}
token[j]='\0';
n=0;
while ((n<keywordSum) && strcmp(token,keyword[n])) n++;
if(n>=keywordSum)
fprintf(fout,"%s\t%s\n","ID",token);
else
fprintf(fout,"%s\t%s\n",token,token);
}else if (isdigit(ch))
{
token[0]=ch;j=1;
ch=getc(fin);
while(isdigit(ch))
{
token[j++]=ch;
ch=getc(fin);
}
token[j]='\0';
fprintf(fout,"%s\t%s\n","NUM",token);
}else if(strchr(singleword,ch)>0)
{
token[0]=ch;token[1]='\0';
ch=getc(fin);
fprintf(fout,"%s\t%s\n",token,token);
}else if (strchr(doubleword,ch)>0)
{
token[0]=ch;
ch=getc(fin);
if (ch == '=')
{
token[1]=ch; token[2]='\0';
ch = getc(fin);
}else
token[1]='\0';
fprintf(fout,"%s\t%s\n",token,token);
}else if (ch=='/')
{
ch = getc(fin);
if(ch =='*')
{
char ch1;
ch1=getc(fin);
do
{
ch=ch1; ch1=getc(fin);
}while((ch1='*' || ch1!='/') && ch1!=EOF);
ch = getc(fin);
}else
{
token[0]='/'; token[1]='\0';
fprintf(fout,"%s\t%s\n",token,token);
}
}else
{
token[0]=ch; token[1]='\0';
ch=getc(fin);
es = 3;
fprintf(fout,"%s\t%s\n",token,token);
}
}
fclose(fin);
fclose(fout);
return (es);
}
4.主程序:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
extern int TESTscan();
extern int TESTparse();
char Scanin[300], Scanout[300]; /* 用于接收输入输出文件名*/ FILE * fin, * fout; /* 用于指向输入输出文件的指针*/ void main()
{
int es=0;
es = TESTscan(); /* 调词法分析*/
if(es>0) printf("词法分析有错,编译停止!");
else printf("词法分析成功!\n");
if(es==0)
{
es=TESTparse(); /*调语法分析*/
if(es==0) printf("语法分析成功!\n");
else printf("语法分析错误!\n");
}
}。