analyseword.cpp

来自「词法分析程序 能自动识别VC++程序编译原理课程上机作业C++程序编写」· C++ 代码 · 共 190 行

CPP
190
字号
/*
	Author : Deimos
	Date   : 2005/4/13
	Modify : 2005/4/14
	Title  : C语言简易词法分析器
	Version: Demo 
*/

/*
	保留字:if、int、for、while、do、return、break、continue	--  编号:1
	标识符:除保留字以外的字符串或字符(数字不行)				--  编号:2
	无符号整形数:												--  编号:3
	运算符包括:+、-、*、/、=、>、<、>=、<=、!=					--  编号:4
	分隔符包括:,、;、{、}、(、)								--  编号:5
*/

#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAXBUF 255 //缓冲数组的最大值,也就是一个词法允许的最大值

int LineNum=0;//记录当前读取的行数,只为报错提示用

void ReadSourceFile();//读取源文件函数
void Analysis(FILE *fp);//分析函数
bool IsNumber(char ch);//判断一个数是不是数字
bool IsChar(char ch);//判断一个数是不是字母
bool FindKey(char *arr);

void main()
{

	FILE *fp;
	if((fp = fopen("c:\\a.txt","rw"))==NULL) //判断将要读取的文件是否存在
	{
		cout<<"\n\t C:\\a.txt 并不存在,请检查,并在其中输入源程序,以 # 号结尾!\n";
	}
	else
	{ //如果存在,进行词法分析
		Analysis(fp);
		fclose(fp);
	}
	
}

void Analysis(FILE *fp)
{
	char ch=NULL;
	char arr[MAXBUF] = "";//建立一个缓冲数组
	int i=0;//为缓冲数组计数

	while(!feof(fp))
	{
		fscanf(fp, "%c", &ch);//从输入文件中读取一个字符

		if(ch==' ' || ch=='\t')//过滤 空格 和 TAB
			;
		else if(ch=='\n')//过滤 换行,并为以后报错做准备,用一个变量记录
			LineNum++;
		else if(IsNumber(ch))
		{
			while(IsNumber(ch))
			{
				arr[i] = ch;
				i++;
				fscanf(fp, "%c", &ch);
				
			}
			fseek(fp, -1L, SEEK_CUR);//指针想前移动一个,因为前面那个循环已经想后读了一个字符
			                         //如果不是,那么就有一个字符被读了,所以这里要回去
            arr[i] ='\0';

			cout<<"( "<<arr<<"\t,\t3 )\n";

			i=0;//计数器还原
		//	free(temp);//释放内存		
		}
		else if(IsChar(ch))
		{
			while(IsNumber(ch) || IsChar(ch))
			{
				arr[i] = ch;
				i++;
				fscanf(fp, "%c", &ch);
			}
			fseek(fp, -1L, SEEK_CUR);//指针想前移动一个,因为前面那个循环已经想后读了一个字符
			                         //如果不是,那么就有一个字符被读了,所以这里要回去
			if(FindKey(arr))
			{
				arr[i] ='\0';

				cout<<"( "<<arr<<"\t,\t1 )\n";

				i=0;//计数器还原
			}
			else
			{
				arr[i] ='\0';

				cout<<"( "<<arr<<"\t,\t2 )\n";

				i=0;//计数器还原
			}			
		}
		else if(ch == '>')
		{
			fscanf(fp, "%c", &ch);
			if(ch == '=')
				cout<<"( >=\t,\t4 )\n";
			else
			{
				fseek(fp, -2L, SEEK_CUR);
				fscanf(fp, "%c", &ch);
				goto Lable;
			}

		}
		else if(ch == '<')
		{
			fscanf(fp, "%c", &ch);
			if(ch == '=')
				cout<<"( <=\t,\t4 )\n";
			else
			{
				fseek(fp, -2L, SEEK_CUR);
				fscanf(fp, "%c", &ch);
				goto Lable;
			}
		}
		else if(ch == '!')
		{
			fscanf(fp, "%c", &ch);
			if(ch == '=')
				cout<<"( !=\t,\t4 )\n";
			else
			{
				fseek(fp, -2L, SEEK_CUR);
				fscanf(fp, "%c", &ch);
				goto Lable;
			}
		}
		else
		{
Lable:		
			if(ch == '+') {cout<<"( +\t,\t4 )\n";continue;}
			if(ch == '-') {cout<<"( -\t,\t4 )\n";continue;}
			if(ch == '*') {cout<<"( *\t,\t4 )\n";continue;}
			if(ch == '/') {cout<<"( /\t,\t4 )\n";continue;}
			if(ch == '>') {cout<<"( >\t,\t4 )\n";continue;}
			if(ch == '<') {cout<<"( <\t,\t4 )\n";continue;}
            if(ch == '=<') {cout<<"( <\t,\t4 )\n";continue;}
			if(ch == '>=') {cout<<"( <\t,\t4 )\n";continue;}
			if(ch == '=') {cout<<"( =\t,\t4 )\n";continue;}
			if(ch == ',') {cout<<"( ,\t,\t5 )\n";continue;}
			if(ch == ';') {cout<<"( ;\t,\t5 )\n";continue;}
			if(ch == '{') {cout<<"( {\t,\t5 )\n";continue;}
			if(ch == '}') {cout<<"( }\t,\t5 )\n";continue;}
			if(ch == '(') {cout<<"( (\t,\t5 )\n";continue;}
			if(ch == ')') {cout<<"( )\t,\t5 )\n";continue;}
			else
			{
				cout<<"出现不可识别字符在第 "<<LineNum+1<<" 行,值为 "<<ch<<endl;
			}
		}

	}
		
}

bool IsNumber(char ch)
{
	if(ch>='0' && ch<='9')
		return true;
	else
		return false;
}

bool IsChar(char ch)
{
	if((ch>='A' && ch<='Z') || (ch>='a' && ch<='z'))
		return true;
	else
		return false;
} 

bool FindKey(char *arr)
{
	char *key[8] = {"if","int","for","while","do","return","br

⌨️ 快捷键说明

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