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

📄 lex.cpp

📁 编译
💻 CPP
字号:
#include <iostream.h>
#include<ctype.h> 
#include<string>
using namespace std;
#define ID 11
#define INT 12
#define COMMA 13
#define ENDF 14
#define COLON 15
#define SEMIC 16
#define ADD 17
#define MINUS 18
#define MULTI 19
#define EVALU 20
#define LE 21
#define NE 22
#define LT 23
#define EQ 24
#define GE 25
#define GT 26

char TOKEN[20];                      //字符数组用来依次存放单词词文的各个字符

extern int lookup(char *);           //以TOKEN字符串查保留字表
extern void out(int,char *);         //以(CLASS VALUE)的二元组形式分类输出个各个单词 
extern void report_error(char);      //报告程序中的词法错误
bool isalpha(char);                  //判断接收字符是否为字母
bool isalnum(char);                  //判断接收字符是否为字母或者数字
bool isdigit(char);                  //判断接收字符是否为数字

void scanner(FILE *fp)
{//词法分析的主体程序,对输入的文本文件进行词法分析
	char ch;
	int i,c;
	int error=0;                         //记录文件中词法错误的个数
	ch=fgetc(fp);                        //从输入文件中读取一个字符
	while(ch!=EOF)                       
	{//当从输入文件接收的字符不是文件结束符时,执行循环
		if(isalpha(ch))
		{//如果从输入文件接收的第一个字符是字母
			TOKEN[0]=ch;
			ch=fgetc(fp);i=1;
			while(isalnum(ch))
			{
				TOKEN[i]=ch;i++;
				ch=fgetc(fp);                  
			}
			TOKEN[i]='\0';                     //在字符数组末尾添加字符串结束符
			c=lookup(TOKEN);                   //查保留字表
			if(c==0)out(ID,TOKEN);             //输出接受单词为标识符
			else out(c,TOKEN);              //输出接收单词为保留字
		}
		if(isdigit(ch))                     //如果从输入文件接收的第一个字符是数字
		{
			TOKEN[0]=ch;
			ch=fgetc(fp);i=1;
			while(isdigit(ch)||ch=='.')
			{//从第二个接收字符开始,当是数字时,执行循环
				TOKEN[i]=ch;i++;
				ch=fgetc(fp);                   //重复接收字符,直到接收到非数字
			}
			if(isalpha(ch))
			{
				while(isalpha(ch))
				{	
					TOKEN[i]=ch;i++;
					ch=fgetc(fp);
				}
				TOKEN[i]='\0';
				cout<<"\'"<<TOKEN<<"\'"<<" IS ERROR!"<<endl;
			}
			else 
			{
				fseek(fp,-1,1);
			    TOKEN[i]='\0';                     //在字符数组末尾添加字符串结束符
			    out(INT,TOKEN);                    //输出接收单词为整数
			}
		}
		else            //如果从输入文件接收的第一个字符既不是字母又不是数字
		switch(ch)
		{//将所接收到的符号字符进行分类,采取一符一类
			case':':ch=fgetc(fp);                                   
		        if(ch=='=')out(EVALU,"':='");          //输出接收符号为赋值号  
	 			else
				{
					fseek(fp,-1,1);                        //文件接收字符回推一个字符
					out(COLON,"':'");                      //输出冒号
				}
				break;
			case',':out(COMMA,"','");break;                   //输出逗号
			case'.':out(ENDF,"'.'");break;                    //输出句号
			case';':out(SEMIC,"';'");break;                   //输出分号 
			case'+':out(ADD,"'+'");break;                     //输出加号  
			case'-':out(MINUS,"'-'");break;                   //输出减号 
			case'*':out(MULTI,"'*'");break;                   //输出乘号
			case'<':ch=fgetc(fp);
				if(ch=='=')out(LE,"'<='");             //输出小于或等于号 
				else if(ch=='>')out(NE,"'<>'");        //输出不等于号
						else
						{
						fseek(fp,-1,1);
						out(LT,"'<'");                 //输出小于号
						} 
			break;
			case'=':out(EQ,"'='");break;                      //输出等于号
			case'>':ch=fgetc(fp);
				if(ch=='=')out(GE,"'>='");             //输出大于或等于号
					else
					{
					fseek(fp,-1,1);
					out(GT,"'>'");                     //输出大于号
					}
				break;
			case' ':break;                                    //空格不作处理
			case'\n':break;                                   //换行不作处理
			case'\t':break;
			default:report_error(ch);                         //接收非上述字符程序报告词法错误
			error++;break;
		}
		ch=fgetc(fp);                                          //继续从文件中读取下一个单词,直到文件结束
	}//while循环结束
	cout<<endl<<"共发现"<<error<<"个词法错误!"<<endl;
	return;
}
int lookup(char *token)
{
	string keyword[10]={"","begin","end","var","integer","while","do","if","then","procedure"};
	/* 建立保留字表如下:
	1	begin
	2	end
	3	var
	4	integer
	5	while
	6	do
	7	if
	8	then
	9	procedure
	*/
	for(int j=1;j<=9;j++)if(token==keyword[j])return j;   //以TOKEN字符串查保留字表,若查到返回保留字类别码
	return 0;                                              //TOKEN不是保留字,返回0
}
void out(int c,char *token)
{//以(CLASS VALUE)的二元组形式分类输出个各个单词
cout<<'('<<c<<','<<token<<')'<<endl;
}
void report_error(char c)
{//报告程序中的词法错误
cerr<<'\''<<c<<'\''<<" IS ERROR!"<<endl;
}
bool isalpha(char c)
{ //判断接收字符是否为字母
if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))return 1;
   else return 0;
}
bool isalnum(char c)
{//判断接收字符是否为字母或者数字
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9'))return 1;
   else return 0;
}
bool isdigit(char c)
{//判断接收字符是否为数字
if(c>='0'&&c<='9')return 1;
   else return 0;
}

int main()
{
FILE *fp;                             //定义文件指针
char filename[20];
printf("请输入文件名:");
scanf("%s",filename); 
if((fp=fopen(filename,"r"))==NULL) //打开要读取的文本文件,用fp指向
{
	printf("不能打开文件.\n"); 
	exit(0);
	}

scanner(fp);                          //调用词法分析程序
getchar();getchar();
return 0;
}

⌨️ 快捷键说明

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