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

📄 scan.cpp

📁 自己做的一个简单的C词法分析器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// scan.cpp: implementation of the scan class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "scanner1.h"
#include "scan.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////



#define INDEX	 110  //表示标识符
#define CARCTER  111  //表示字符型常数
#define INTEN    112  //表示整型常数
#define REAL     113  //表示实型常数

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

scan::scan()
{
	//初始化参数
	row=0;
	col=0;
	p_wt=0;
	m_st.point=0;
	strtoken=_T("");
	errnum=0;
	memset(this->m_st.strtabe,0,1000);
	wordtablenum=0;
	//初始化符号表
	for(int i=0;i<100;i++)
		m_wt[i].start=0;
}

scan::~scan()
{

}

/*********************************************************************/
//函数说明:scan总控。得到传来的一行信息开始扫描
//参数说明:s-传来的一行信息,row-当前是第几行,count-这一行的字符个数
//返回值:分析后得到的token、错误信息、符号表
/*********************************************************************/
CString scan::Analyze(CString s,int row,int count)//scan总控
{
	col=0;	//列计数器初始化
	memset(this->buf,0,100);
	strcat(buf,s);
	err=_T("");
	char ch;
	this->row=row;//行计数器初始化
	this->count=count;
	//扫描每一个字符
	for (int i=0;i < count;i++)
	{
		ch=buf[i];
		//开始判断
		Sort(ch);
		if (i<=col)	//如果后面的字符已经处理,列计数器后移动
			{
				i=col;
				col++;
			}
		if (col==count)//如果当前行已经处理完,就返回处理。
			break;
	}
	return this->err;
}

/*********************************************************************/
//函数说明:扫描下一个字符
//参数说明:无
//返回值:返回下一个字符
/*********************************************************************/
char scan::ScanNextChar()
{
	col++;	//列计数器后移
	char c;
	if(col < count)	//当前行还有字符,就取当前字符
	{
		c = buf[col];		
	}
	else
	{
		c = '\n';	
	}
	return c;
}

/*********************************************************************/
//函数说明://分类处理字符
//参数说明:s-传来的一行信息,row-当前是第几行,count-这一行的字符个数
//返回值:分析后得到的token、错误信息、符号表
/*********************************************************************/
void scan::Sort(char ch)
{
	//如果是空格就跳过
	bool flag=true;
	do{
		if (ch==' ')
			ch = ScanNextChar();
		if (ch !=' ')
			flag=false;
	}while(flag);

	//识别标识符
	if (IsLetter(ch))
		Recogid(ch);	
	//处理注释及界限符/
	else if (ch=='/')
		Handlecom(ch);	
	
	//识别数字常数
	else if (IsNumber(ch))
		Recogdig(ch);
	
	//识别字符常数
	else if (ch == 39)
		Recogstr(ch);	
	
	//识别各种界符
	else if (IsIdent(ch))
		Recogdel(ch);
	//处理错误的符号
	else Error(ch);
}

/*********************************************************************/
//函数说明:处理注释
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
void scan::Handlecom(char ch)
{
	bool flag = false;	//注释完成的标志
	char c = ScanNextChar();
	//是/号就返回除号的Token
	if(c != '*')
	{
		col--;
		AddToken("/",46,0);
		return;
	}
	c = ScanNextChar();
	//删除注释信息
	while(col < count)
	{
		char temp = c;
		c = ScanNextChar();
		if(temp=='*' && c=='/')//注释结束
		{
			flag = true;	//注释完成标志
			break;
		}
	}
	if(!flag)//注释不正确,就提示注释错误
	{
		char buffer[20]="";
		err+="(";
		err+=_itoa( row+1, buffer, 10 );
		err+=",";
		
		err+=_itoa( col+1, buffer, 10 );
		err+=")";
		err+="\t错误类型:";
		err+="未知注释!\r\n";
		errnum++;
	}
}

/*********************************************************************/
//函数说明:识别标识符
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
void scan::Recogid(char ch)
{
	CString word=_T("");
	word+=ch;
	//如果是正确的字符就连接成单词
	do 
	{
		ch=ScanNextChar();
		if (IsLetter(ch)|| IsNumber(ch))
			word+=ch;
	} while (IsLetter(ch) || IsNumber(ch));
	col--;
	
	int token=0;
	unsigned entry=0;
	if(IsKeyword(word,token))	//如果是关键字
		AddToken(word,token+1,0);
	else	//不是关键字,就查找符号表
	{
		LookUp(word,INDEX,entry);	//查询符号表
		AddToken(word,33,entry);
	}
}

/*********************************************************************/
//函数说明:识别数字常数
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
void scan::Recogdig(char ch)
{
	bool IsInt = true;	//是否是整常数的标志
	char array[100];
	memset(array,0,100);
	array[0] = ch;
	int i = 1;	
	do 
	{
		ch = ScanNextChar();
		//是实数
		if(ch == '.'&& IsInt)
		{
			array[i] = '.';
			i++;
			IsInt = false;	//不是整常数,是实常数
		}
		else if(IsNumber(ch))//如果是数字就连接起来
		{
			array[i] = ch;
			i++;
		}
		else
		{
			//数字常数结束
			CString s=_T("");
			unsigned p=0;
			//整常数
			if(IsInt)
			{
				s.Format("%s",array);
				LookUp(s,INTEN,p);//查找符号表,返回地址
				AddToken(s,34,p);//加入相应的Token
			}
			//实常数
			else
			{
				s.Format("%s",array);
				LookUp(s,REAL,p);//查找符号表,返回地址
				AddToken(s,35,p);//加入相应的Token
			}
			col--;
			break;
		}
	} while(1);
}

/*********************************************************************/
//函数说明:得到传来的一行信息开始扫描
//参数说明:c-待处理的一个字符
//返回值:无
/*********************************************************************/
//识别字符常数
void scan::Recogstr(char c)
{
	char array[100];
	int i = 0;
	unsigned p=0;
	char ch = ScanNextChar();
	//字符没有完
	while(ch != 39  && col < count)
	{
		array[i] = ch;
		ch = ScanNextChar();
		i++;
	}
	//在遇到'''号,字符完了
	if(ch == 39)
	{
		array[i] = '\0';
		CString s=_T("");
		s.Format("%s",array);
		LookUp(s,CARCTER,p);
		AddToken(s,36,p);
	}
	//报错
	else
	{
		char buffer[20]="";
		err+="(";
		err+=_itoa( row+1, buffer, 10 );
		err+=",";
		
		err+=_itoa( col+1, buffer, 10 );
		err+=")";
		err+="\t错误类型:";
		err+="缺少单引号!\r\n";	
		errnum++;
	}
}

/*********************************************************************/
//函数说明:得到传来的一行信息开始扫描
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
//识别各种界符
void scan::Recogdel(char ch)
{
	switch(ch)
	{
	case '<':
		{
			char c = ScanNextChar();
			//加入<=
			if(c == '=')
			{
				AddToken("<=",51,0);
			}
			//加入<>
			else if(c == '>')
			{
				AddToken("<>",52,0);
			}
			//加入<
			else
			{
				col--;
				AddToken("<",50,0);
			}
		}
		break;
	case '>':

⌨️ 快捷键说明

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