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

📄 cifa.cpp

📁 词法分析程序
💻 CPP
字号:
// cifa.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "ctype.h"
#include "iostream.h"
#include "stdlib.h"
#include "fstream.h"
#include "string.h"

#define MaxNum 200
#define KeyNum 13
#define LEN 10

bool bufnil=true;//缓冲区为空标志
bool Fileend=false;//文件结束标志

int frp=0;//缓冲区指针
char buf[MaxNum];//输入缓冲区
char token[LEN];//装配单词能用缓冲区
char keytable[KeyNum][10]={"program","var","procedure","begin","end","if", "then",
            "else","while","do","call","integer","real"};//保留字表

int IDfrp=1;//当前标识符表指针
struct ID_tab
{
	int Recode;
	char Idname[LEN];
	int Idaddr;
}ID[MaxNum];              //标识符表

char readch(ifstream infile);//1、读一个字符
void isIdenti(ifstream infile,ofstream outfile,char ch);//2、判断标识符
int lookup();//3、检查当前标识符是否为保留字,不是返回零
void isInt(ifstream infile,ofstream outfile,char ch);//4、判断正整数
void Anno(ifstream infile,ofstream outfile);//5、越过注释
void report_err(ofstream outfile);//6、错误处理
void scanner(ifstream infile,ofstream outfile);//7、判断

char readch(ifstream infile)
{
	char ch;
	//缓冲区不空
	if(!bufnil)
	{
		ch=buf[frp];
		frp++;
		if(ch=='\0') bufnil=true;//为下一次读字符设标志 
		return ch;
	}
	//缓冲区空
	infile.getline(buf,sizeof(buf));//从文件中读一行
    if(infile.eof())  Fileend=true;
	else{
		bufnil=false;
		frp=0;            //指针还原
		ch=buf[frp];
		frp++;
		if(ch=='\0') bufnil=true;
		return ch;
	}
	return '\0';//若文件中为空返回回车
}

int lookup()   
{
	int i;
	for(i=0;i<KeyNum;i++)
		if(strcmp(token,keytable[i])==0) return i+3;
	return 0;
}


void isIdenti(ifstream infile,ofstream outfile,char ch)
{
	int i=1;
	token[0]=ch;
	ch=readch(infile);
	while(isalnum(ch))
	{
		token[i]=ch;
		i++;
		ch=readch(infile);
	}
	token[i]='\0';//串结束
	frp--;
	if(i>=8)
	{
		report_err(outfile);
		return;
	}
	if(!lookup())//不是保留字
	{
		for(i=1;i<IDfrp;i++)
			if(strcmp(token,ID[i].Idname)==0)//已出现的标识符再记录
			{
				outfile<<"(1,"<<i<<")"<<token<<endl;//读出标识符表中的序列号
				return;
			}
        outfile<<"(1,"<<IDfrp<<")"<<token<<endl;
		ID[IDfrp].Recode=IDfrp;              //未出现的表示符记录到标识符表中
		strcpy(ID[IDfrp].Idname,token);
		ID[IDfrp].Idaddr=0;
		IDfrp++;
		
	}
	else outfile<<"("<<lookup()<<","<<"0)"<<keytable[lookup()-3]<<endl;//保留字二元式
}

void isInt(ifstream infile,ofstream outfile,char ch)    
{
	int i=1,value=-1;
	token[0]=ch;
	value=ch-'0';	
	ch=readch(infile);
	while(isdigit(ch))
	{
		value=value*10+ch-'0';
		token[i++]=ch;
		ch=readch(infile);
	}
	while(isalnum(ch))//是否字母或数字
	{
		value=-1;
		ch=readch(infile);
	}
	
	token[i]='\0';
	frp--;
	if(value==-1) report_err(outfile);
	else outfile<<"(2,"<<value<<")"<<value<<endl;
}



void Anno(ifstream infile,ofstream outfile)   
{
	char ch;
	while(!Fileend)
	{
		ch=readch(infile);//碰到下一个*
		if(ch=='*')
		{
			ch=readch(infile);//如果下一个是/
			if(ch=='/')
			{
				return;
			}
		}
	}
	outfile<<"wrong Annotations!"<<endl;
}

void report_err(ofstream outfile)
{
	outfile<<"**error(1)**"<<endl;
}


void scanner(ifstream infile,ofstream outfile)   
{
	char ch;
	ch=readch(infile);

    if(ch==' ')//跳过空格
	{
		ch=readch(infile);
		while(ch==' ')
			ch=readch(infile);
		frp--;
	}
	else if(isalpha(ch))//判断标识符
		isIdenti(infile,outfile,ch);

	else if(isdigit(ch))
		isInt(infile,outfile,ch);//判断正整数
		

	else 
		switch(ch)//判别其他有效字符
	{
	case '\0':break;
	case '+': outfile<<"(16,0)+"<<endl; break;
	case '-': outfile<<"(17,0)-"<<endl; break;
	case '*': outfile<<"(18,0)*"<<endl; break;
	case '~': outfile<<"(20,0)~"<<endl; break;
	case '^': outfile<<"(21,0)^"<<endl; break;
	case '=': outfile<<"(27,0)="<<endl; break;
	case '.': outfile<<"(31,0)."<<endl; break;
	case ',': outfile<<"(32,0),"<<endl; break;
	case ';': outfile<<"(30,0);"<<endl; break;
	case '(': outfile<<"(33,0)("<<endl; break;
	case ')': outfile<<"(34,0))"<<endl; break;	
	case ':': ch=readch(infile);
		      if(ch=='=') outfile<<"(29,0):="<<endl;
			  else { frp--; outfile<<"(35,0):"<<endl; }
			  break;
	case '<': ch=readch(infile);
		      if(ch=='=') outfile<<"(24,0)<="<<endl;
			  else if(ch=='>') outfile<<"(28,0)<>"<<endl;
			  else { frp--; outfile<<"(23,0)<"<<endl; }
			  break;
	case '>': ch=readch(infile);
		      if(ch=='=') outfile<<"(26,0)>="<<endl;
			  else { frp--; outfile<<"(25,0)>"<<endl; }
			  break;
	case '/': ch=readch(infile);
		      if(ch=='*') Anno(infile,outfile);
			  else if(ch=='\\') outfile<<"(28,0)/\\"<<endl;
			  else { frp--; outfile<<"(19,0)/"<<endl; }
			  break;
	case '\\':ch=readch(infile);
		      if(ch=='/') outfile<<"(22,0)\\/"<<endl;
			  else { frp--; outfile<<"**error(1)**"<<endl; }
			  break;
	default:  report_err(outfile);
		      break;
	}
}




int main(int argc, char* argv[])
{
	ifstream infile("D:\\fin.txt");
	ofstream outfile("D:\\fout.txt");
	if(!infile)
	{
		cout<<"file_in cannot open.\n";
		abort();
	}

while(!Fileend)
		scanner(infile,outfile);

	outfile<<endl;
	outfile<<"序列\t"<<"名字\t"<<"地址\t"<<endl;
	for(int i=1;i<IDfrp;i++)
		outfile<<ID[i].Recode<<"\t"<<ID[i].Idname<<"\t"<<ID[i].Idaddr<<endl;

	infile.close();
	outfile.close();
	return 0;
}


⌨️ 快捷键说明

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