ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

编译原理-PL0词法分析实验(包含源码)

2021-01-05 17:04:39  阅读:233  来源: 互联网

标签:ch PL0 else 词法 源码 fprintf fout printf fin


实验要求:

1、对源程序进行理解,从PL0文档中抽取出词法部分的代码,单独作为一个程序,变成一个词法程序,用visual6.0或者Dev c++进行编译,编译成为可执行文件;
2、对输出的文件进行检验,用PL0验证源程序作为词法验证输入源程序,对其进行读入
3、单词序列二元组结果的显示并保存成结构文件;
4、指出抽取的PL0词法分析程序中的标识符、关键字、界符、运算符,常数有哪些;
5、画出状态转移图。

PL0验证源程序文件.txt

点击此处下载

词法分析器源程序.cpp

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void init();
void getsym();
/* 符号 */
enum symbol
{
	nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,
	lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,
	beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,
	constsym,varsym,procsym,programsym,
};
#define norw 14           /*关键字个数*/
#define al 10            //符号的最大的长度 
#define nmax 10         //number的最大位数
char word [norw][al];  //保留字13个
char ch;               /* 获取字符的缓冲区 */
enum symbol sym;         /* 当前的符号 */
enum symbol wsym[norw];    /* 保留字对应的符号值 */
enum symbol ssym[256];    //单字符的符号值
FILE *fin,*fout;
int main()
{
	printf("请输入结果要保存的文件:\n");    //词法分析之后的结果要输出到的文件
	char outname[30],inname[30];
	scanf("%s",outname);
	if((fout=fopen(outname,"w"))==NULL)
	{
		printf("不能打开文件!");
		exit(0);
	}
	printf("请输入需要词法分析的源程序:\n");     //需要词法分析的源程序
	scanf("%s",inname);
	if((fin=fopen(inname,"r"))==NULL)
	{
		printf("不能打开文件!\n");
		exit(0);
	}
	ch=fgetc(fin);
	while(ch!=EOF) //EOF实际是-1,用来表示文本文件的结束 
	{
		getsym();
	}
}
//读取源文件
void getsym()
{
	long  m;
    char id[al+1],a[al+1];
	int  i,k;
	init();
	if(ch==' '||ch==10||ch==9)         /*忽略空格、换行和TAP*/
	{
		ch=fgetc(fin);
	}
	else
	{
		if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')   /*名字或保留字以a..z开头*/
		{
			k=0;
		    do                                    /*搜索当前符号是否为保留字*/
			{
				if(k<al)
				{
					a[k]=ch;
			       	k++;
				}
				ch=fgetc(fin);
			}while ((ch>='a'&&ch<='z'||ch>='0'&&ch<='9')||(ch>='A'&&ch<='Z'||ch>='0'&&ch<='9'));
			a[k]=0;
		    strcpy(id,a);
		    //将识别出来的字符和已定义的标示符作比较, 判断是否是关键字
		    for(i=0;i<norw;i++)
			{
				if(strcmp(id,word[i])==0)
				{
					sym=wsym[i];
                    printf("%s       %ssym\n",id,id);
                    fprintf(fout,"%s       %ssym\n",id,id);
					break;
				}
				else
				{
					if(i==(norw-1))
					{
						sym=ident;
					    printf("%s          ident\n",id);
					    fprintf(fout,"%s          ident\n",id);
					}
				}
			}
		}
		else
		{
			if(ch>='0'&&ch<='9')   /*检测是否为数字:以0..9开头*/
			{
				k=0;
			    m=0;
			    sym=number;
			    do
				{
					m=10*m+ch-'0';
				    k++;
				    ch=getc(fin);
				}while(ch>='0'&&ch<='9');     /*获取数字的值*/
				if(k>=nmax)
				{
					printf("     error!数值太大!     \n");
					//exit(0);
				}
				printf("%d        number\n",m);
				fprintf(fout,"%d        number\n",m);
			}
	       	else
			{
				if(ch==':')              /*检测赋值符号*/
				{
		           	ch=getc(fin);
					if(ch=='=')
					{
						sym=becomes;
					    printf(":=         becomes\n");
						fprintf(fout,":=         becomes\n");
					    ch=fgetc(fin);
					}
					else
					{
						sym=nul;
					    printf(":            nul\n");                     /*不能识别的符号*/
						fprintf(fout,":            nul\n");
					}
				}
				else
				{
					if(ch=='<')                                          /*检测小于或小于等于符号*/
					{
						ch=fgetc(fin);
					    if(ch=='=')
						{
							sym=leq;
					       	printf("<=            lep\n");
							fprintf(fout,"<=            lep\n");
					        ch=fgetc(fin);
						}
				        else
						{
							sym=lss;
					      	printf("<            lss\n");
							fprintf(fout,"<            lss\n");
						}
					}
				    else
					{
						if(ch=='>')                         /*检测大于或大于等于符号*/
						{
							ch=fgetc(fin);
							if(ch=='=')
							{
								sym=geq;
						       	printf(">=            geq\n");
								fprintf(fout,">=            geq\n");
					           	ch=fgetc(fin);
							}
							else
							{
								sym=gtr;
							    printf(">            gtr\n");
						        fprintf(fout,">            gtr\n");
							}
						}
						else     /*当符号不满足上述条件时,全部按照单字符符号处理*/
						{
							sym=ssym[ch];
							if(ch=='+'){printf("+           plus\n");fprintf(fout,"+           plus\n");ch=fgetc(fin);}
							else
							if(ch=='-'){printf("-          minus\n");fprintf(fout,"-          minus\n");ch=fgetc(fin);}
							else
							if(ch=='*'){printf("*          times\n");fprintf(fout,"*          times\n");ch=fgetc(fin);}
							else
							if(ch=='/'){printf("/          slash\n");fprintf(fout,"/          slash\n");ch=fgetc(fin);}
							else
							if(ch=='('){printf("(         lparen\n");fprintf(fout,"(         lparen\n");ch=fgetc(fin);}
							else
							if(ch==')'){printf(")         rparen\n");fprintf(fout,")         rparen\n");ch=fgetc(fin);}
							else
							if(ch=='='){printf("=            eql\n");fprintf(fout,"=            eql\n");ch=fgetc(fin);}
							else
							if(ch==','){printf(",          comma\n");fprintf(fout,",          comma\n");ch=fgetc(fin);}
							else
							if(ch=='#'){printf("#            neq\n");fprintf(fout,"#            neq\n");ch=fgetc(fin);}
							else
							if(ch=='.'){printf(".         period\n");fprintf(fout,".         period\n");ch=fgetc(fin);}
							else
							if(ch==';'){printf(";       semicoln\n");fprintf(fout,";       semicoln\n");ch=fgetc(fin);}
							else{printf("%c            nul\n",ch);fprintf(fout,"%c            nul\n",ch);ch=fgetc(fin);}
						}
					}
				}
			}
		}
	}
}
//对关键字等实现初始化
void init()
{
	/*设置单字符符号*/
	int i;
	for(i=0;i<=255;i++)
	{
		ssym[i]=nul;
	}
	ssym['+']=plus;
	ssym['-']=minus;
	ssym['*']=times;
	ssym['/']=slash;
	ssym['(']=lparen;
	ssym[')']=rparen;
	ssym['=']=eql;
	ssym[',']=comma;
	ssym['.']=period;
	ssym['#']=neq;
	ssym[';']=semicolon;
 /*设置保留字名字,按照字母表顺序,便于折半查找*/
	strcpy(&(word[0][0]),"begin");
	strcpy(&(word[1][0]),"call");
	strcpy(&(word[2][0]),"const");
	strcpy(&(word[3][0]),"do");
	strcpy(&(word[4][0]),"end");
	strcpy(&(word[5][0]),"if");
	strcpy(&(word[6][0]),"odd");
	strcpy(&(word[7][0]),"procedure");
	strcpy(&(word[8][0]),"read");
	strcpy(&(word[9][0]),"program");
	strcpy(&(word[10][0]),"var");
	strcpy(&(word[11][0]),"whlie");
	strcpy(&(word[12][0]),"write");
	strcpy(&(word[13][0]),"then");
/*设置保留字符号*/
	wsym[0]=beginsym;
	wsym[1]=callsym;
	wsym[2]=constsym;
	wsym[3]=dosym;
	wsym[4]=endsym;
	wsym[5]=ifsym;
	wsym[6]=oddsym;
	wsym[7]=procsym;
	wsym[8]=readsym;
	wsym[9]=programsym;
	wsym[10]=varsym;
	wsym[11]=whilesym;
	wsym[12]=writesym;
	wsym[13]=thensym;
}

输入要保存的二元组文件名字和要词法分析的源程序文件
在这里插入图片描述

然后运行该程序
在这里插入图片描述
该目录下已经生成了test.txt 二元组文件
在这里插入图片描述

生成的test.txt 二元组文件

在这里插入图片描述
指出抽取的PL0词法分析程序中的标识符、关键字、界符、运算符,常数有哪些;
标识符:字母数字串
关键字:begin end if then else while write read do call Constantine
var procedure repeat until
界符: , . ; ( )
运算符: + - * / := = <>(#) < <= > >=
常数:整数
5、画出状态转移图。
在这里插入图片描述
实验完成

标签:ch,PL0,else,词法,源码,fprintf,fout,printf,fin
来源: https://blog.csdn.net/qq_46350148/article/details/112243428

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有