⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 la.cpp

📁 用 C++ 作为宿主语言完成: Java语言词法分析器的设计和实现 使用DFA实现词法分析器的设计; 实现对Java源程序中注释的过滤; 利用两对半缓冲区从文件中逐一读取单词; 词法分析结果
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 50

static char zerobuffer[50]={""};
char firstbuffer[50];		//前半个缓冲区
char secondbuffer[50];		//后半个缓冲区
char buffer[50];			//存放取出的单词的缓冲区
char filename[30],fileout[30];//依次为输入文件和输出文件的文件名
char keyword[50][13]={	  //关键字列表
			"abstract","boolean","break","byte","case","catch","char","class","const","continue",
			"default","do","double","else","extends","false","final","finally","float","for",
			"goto","if","implements","import","instanceof","int","interface","long","native","new",
			"null","package","private","protected","public","return","short","static","super","switch",
			"synchronized","this","throw","throws","transient","ture","try","void","volatile","while"};
int line_id=0,line_num=0,word_num=0,errornum=0;//依次为行号,所在行单词数,总单词数,总错误数
int lpos=0,B=0,F=0;		//依次为在缓冲区中的当前位置,单词初始位置,单词结束位置
FILE *fin;				//输入文件
FILE *fout;				//输出文件
char ch=' ';
int type;				//单词类型
int state;				//当前状态
int k;
int keyflag,errorflag,backflag;	//依次为关键字标识,错误标识
int ep,fp,lp,dp,xp,sp,en,fn,ln,dn,xn,sn;   //判断数字常量用的标识号

void read_buffer();
void get_char();
void get_word();
void output();
void error();

void read_buffer()		//把字符串读入缓冲区
{
	int i=0;
	if(lpos==0)
	{
		strcpy(firstbuffer,zerobuffer);
		while(i<N)
		{
			firstbuffer[i]=getc(fin);
			i++;
		}
	}
	else if(lpos==N)
	{
		strcpy(secondbuffer,zerobuffer);
		while(i<N)
		{
			secondbuffer[i]=getc(fin);
			i++;
		}
	}
}

void get_char()		//从缓冲区逐个字符扫描
{
	if(lpos<N)
	{
		ch=firstbuffer[lpos];
		lpos++;
	}
	else 
		if(lpos==N)
		{
			read_buffer();
			ch=secondbuffer[0];
			lpos++;
		} 
		else 
			if(lpos>N && lpos<2*N)
			{
				ch=secondbuffer[lpos-N];
				lpos++;
			}
			else 
				if(lpos==2*N)
				{
					lpos=0;
					read_buffer();
					ch=firstbuffer[0];
					lpos++;
				}
}

void get_word()			//取出单词
{
	strcpy(buffer,zerobuffer);
	if(B<N && F<N)
	{
		for(k=B;k<=F;k++)
			buffer[k-B]=firstbuffer[k];
	}
	if(B<N && F>=N)
	{
		for(k=B;k<N;k++)
			buffer[k-B]=firstbuffer[k];
		for(k=N;k<=F;k++)
			buffer[k-B]=secondbuffer[k-N];
	}
	if(B>=N && F>=N)
	{
		for(k=B;k<=F;k++)
			buffer[k-B]=secondbuffer[k-N];
	}
	if(B>=N && F<N)
	{
		for(k=B;k<2*N;k++)
			buffer[k-B]=secondbuffer[k-N];
		for(k=0;k<=F;k++)
			buffer[k+2*N-B]=firstbuffer[k];
	}
	if(B<=F) buffer[F-B+1]='\0';
	else	 buffer[2*N-B+F]='\0';
}

void output()			//把单词及其属性写入指定文件,并显示出来
{
	fprintf(fout,"0x%0x   %s\n",type,buffer);
	printf("0x%0x   %s\n",type,buffer);
}

void IsAnotation()
{
}

void error()			//处理错误
{
	errornum++;
	printf("There is a error at Line %d : %s \n",line_id+1,buffer);
}

void IsKey()			//判断是关键字还是标识符
{
	keyflag=0;
	if(strlen(buffer)>13)
	{
		type=0x104;
	}
	for(k=0;k<50;k++)
	{
		if(strcmp(buffer,keyword[k])==0)
		{
			type=0x103;
			keyflag=1;
			break;
		}
	}
	if(keyflag==0)	type=0x104;
}

void IsNumber()			//判断数字常量的类型,并作相应处理
{
	for(k=0;k<(int)strlen(buffer);k++)
	{
		if(en==0 && (buffer[k]=='e'||buffer[k]=='E')) { ep=k;en++; }
		else if(buffer[k]=='f'||buffer[k]=='F') { fp=k;fn++; }
		else if(buffer[k]=='l'||buffer[k]=='L') { lp=k;ln++; }
		else if(buffer[k]=='x'||buffer[k]=='X') { xp=k;xn++; }
		else if(buffer[k]=='.') { dp=k;dn++; }
		else if(buffer[k]=='-') { sp=k;if(k!=0)sn++; }
		else if((buffer[k]>=71 && buffer[k]<=90)||(buffer[k]>=103 && buffer[k]<=122)||
			buffer[k]=='$'||buffer[k]=='_'||en>1||ln>1||dn>1||xn>1||sn>1||
			(buffer[0]!=48 && buffer[1]!='x' && buffer[1]!='X' &&((buffer[k]>=65 && buffer[k]<=70)||(buffer[k]>=97 && buffer[k]<=102)))||
			(buffer[0]!='-' && buffer[1]!=48 && buffer[2]!='x' && buffer[1]!='X' &&((buffer[k]>=65 && buffer[k]<=70)||(buffer[k]>=97 && buffer[k]<=102))))  
		{
			errorflag=1;
//			if(buffer[0]==48 && xp==1 && ((buffer[k]>=65 && buffer[k]<=70)||(buffer[k]>=97 && buffer[k]<=102)))
			break;
		}
	}
	if(errorflag==1) error();
	else if((en==0 && fn==0 && dn==0 && xn==0 && ln==0 && sn==0)  //1234
		||(en==0 && fn==0 && dn==0 && xn==0 && sn==0 && lp==strlen(buffer)-1)	 //123l
		||(dn==0 && ln==0 && sn==0 && xp==1 && buffer[0]==48 && xp!=strlen(buffer)-1) //0x123
		||(dn==0 && ln==0 && sn==0 && buffer[0]=='-' && xp==2 && buffer[1]==48 && xp!=strlen(buffer)-1))
	{
		type=0x107;
	}
	else if((en==0 && fn==0 && dn==1 && xn==0 && ln==0 && sn==0 )   //123.456
		||(en==0 && ln==0 && dn==1 && xn==0 && sn==0 && fp==strlen(buffer)-1) //123.456f
		||(en==1 && fn==0 && ln==0 && xn==0 &&  (dn==0|| (dn==1 && dp<ep) ||(sn==1 &&(sp-ep)==1) ) )  ) //12.3e56
	{
		type=0x108;
	}
	else 
	{
		errorflag=1;
		error();
	}
}

void IsOperator()
{
}

void Number()		//处理数字常量
{
//	B=F=lpos-1;
	ep=fp=lp=dp=xp=sp=101;
	en=fn=ln=dn=xn=sn=0;
	while((ch>=65 && ch<=90)||(ch>=97 && ch<=122)||(ch>=48 && ch<=57)||ch=='$'||ch=='_'||ch=='e'||ch=='E'||ch=='l'||ch=='L'||ch=='.'||ch=='f'||ch=='F'||ch=='-')
	{
		get_char();
		if(ch=='-' && ((lpos<N && firstbuffer[(lpos-2)%50]!='e' && firstbuffer[(lpos-2)%50]!='E')||
			(lpos>=N && secondbuffer[(lpos-2)%50]!='e' && secondbuffer[(lpos-2)%50]!='E'))){F=lpos-1;break;}
	}
	backflag=1;
	if(sn!=1)F=lpos-2;
	get_word();
	IsNumber();
	if(errorflag==0)
	{
		output();
		line_num++;
	}
	state=0;
}

void scanner()			//词法分析主函数
{int p=0,flag=0,n=0;
	read_buffer();
	get_char();
	while(ch!=EOF)
	{
		backflag=0;
	switch(state)
	{
	case 0:
		errorflag=0;
		if((ch>=65 && ch<=90)||(ch>=97 && ch<=122)||ch=='$'||ch=='_')
		{
			B=F=lpos-1;
			get_char();
			while((ch>=65 && ch<=90)||(ch>=97 && ch<=122)||(ch>=48 && ch<=57)||ch=='$'||ch=='_')
			{
				get_char();				
			}
			backflag=1;
			F=lpos-2;
			get_word();
			IsKey();
			output();
			line_num++;
			state=0;
			break;
		}
		else
		{
			if(ch>=48 && ch<=57)
			{
				B=F=lpos-1;
				Number();
				break;
			}
			else 
				if(ch==' ')
				{
					state=0;
					break;
				}
				flag=0;
				switch(ch)
				{
				case '"':
					n=0;
					B=F=lpos-1;
					get_char();
					while(ch!='"' && ch!='\n')
					{
						get_char();n++;												
					}
					if(ch=='\n') 
					{
						F=lpos-1;
						get_word();
						error();					//error!
					}
					else 
					{
						F=lpos-1;
						get_word();
						type=0x109;
						output();
						line_num++;
					}
					state=0;
					break;
				case '\'':					
					B=F=lpos-1;
					get_char();
					if(ch=='\'')
					{
						state=0;
						F=lpos-1;
						get_word();
						error();				//error!
						break;
					}
					else 
					{					
						get_char();
						if(ch=='\'')
						{
							F=lpos-1;
							get_word();
							type=0x106;
							output();
							line_num++;
							state=0;
							break;
						}
						F=lpos-1;
						get_word();
						error();					//error!
						state=0;
						break;
					}
				case '/':
					get_char();
					if(ch=='/')
					{
						n=0;
						while(ch!='\n' && n<100)
						{
							get_char();
							n++;												
						}
						if(n==100) 	error();				//error!
						line_id++;
						word_num+=line_num;
						printf("Line %2d : %d\n",line_id,line_num);
						line_num=0;
						state=0;
						break;
					}
					if(ch=='*')
					{
						get_char();
						while(ch!=EOF)
						{
							while(ch!='*' && ch!=EOF)
							{
								if(ch=='\n')
								{
									line_id++;
									word_num+=line_num;
									printf("Line %2d : %d\n",line_id,line_num);
									line_num=0;
								}
								get_char();											
							}
							get_char();
							if(ch=='/')
							{
								state=0;
								break;
							}
						}
						break;
					}
					if(ch=='=')
					{
						state=0;
						line_num++;
						break;
					}
					else 
					{
						F=B;
						get_word();
						type=0x11b;
						output();
						backflag=1;
						line_num++;
						state=0;
						break;
					}

				case '{':
				case '}':
					B=F=lpos-1;
					get_word();
					type=0x121;
					output();
					line_num++;
					state=0;
					break;
				case '[':
				case ']':
				case '(':
				case ')':			
				case '.':										//!!???				
					B=F=lpos-1;
					get_word();
					type=0x11d;
					output();
					line_num++;
					state=0;
					break;
				case ';':					
					B=F=lpos-1;
					get_word();
					type=0x122;
					output();
					line_num++;
					state=0;
					break;
				case ',':				
					B=F=lpos-1;
					get_word();
					type=0x120;
					output();
					line_num++;
					state=0;
					break;

				case '+':					
					B=F=lpos-1;
					get_char();
					if(ch=='+')
					{
						state=0;
						F=lpos-1;
						get_word();
						type=0x11c;
						output();
						line_num++;
						break;
					}
					if(ch=='=')
					{
						state=0;
						F=lpos-1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -