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

📄 fen.cpp

📁 做实习时的一个简单的词法分析器。适合初学的人
💻 CPP
字号:
// Fen.cpp: implementation of the CFen class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "cif.h"
#include "Fen.h"

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

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

CFen::CFen()
{
	errFlag = false;
    m_Cur = 0;
	m_Error = "";
	m_Line = 1;

}

CFen::~CFen()
{

}

bool CFen::CiFaC()
{
	m_Line = 1;
	char word[20];//存放当前读取的单词,长度不超过20

	this->initiate();
    this->Delete();//释放前一次分析结果

	CString strCharacter;
	int n = 0;//指示当前字符位置
	m_nNum = 0;//词法分析结果的个数
    int sign = -1;//记录关键字的标志
    CString str = m_strS;
	int m = str.GetLength();
    while(n < m )
	{
		while (1)
		{
			//跳过回车,换行,空格
			while ((m_strS[n]==32) || (m_strS[n]==9))
				n++;
			
			if (!((m_strS[n]==13) && (m_strS[n+1]==10)))
				break;
			
			n++;
			n++;
			m_Line++;
		}
		if(isalpha(m_strS[n]))
		{//若当前字符是字母
            int k = 0;
			do
			{
				if(k < 20)
				{
					word[k] = m_strS[n];
					n++;
					k++;
				}
			}while(isalpha(m_strS[n])||isdigit(m_strS[n]));
			word[k] = 0;
			//判断当前单词是否是关键字
			sign = isR(word);
			if(sign)
                this->SaveR(sign,word);
			else
			    this->SaveI(word);
		}
		else if(isdigit(m_strS[n]))
		{//若当前字符是数字
            int k=0;
			BOOL error = false;
			do//拼数
			{
				if (k<10) 
					word[k++]=m_strS[n++];
				else
				{
					error=true;
					n++;
				}
			}while(isdigit(m_strS[n]));
			word[k]=0;
			int num = ::strtol(word,NULL,10);
			if (error)
			{
				m_CResult[m_nNum]=new CF;
				m_CResult[m_nNum]->value=23;
				m_CResult[m_nNum]->type=0;
				m_CResult[m_nNum]->line=m_Line;
				strcpy(m_CResult[m_nNum]->data,word);
				m_nNum++;
			}
			else
			{
				m_CResult[m_nNum]=new CF;
				m_CResult[m_nNum]->value=num;
				m_CResult[m_nNum]->type=25;
				m_CResult[m_nNum]->line=m_Line;
				strcpy(m_CResult[m_nNum]->data,word);
				m_nNum++;
			}	
		}
        else
		{
			switch(m_strS[n])
			{//其他合法的界符
			    case '=':
				case ',':
				case '<':
				case '>':
			    case '(':
                case ')':
				case '+':
				case '-':
				case '*':
				case '/':
					word[0] = m_strS[n];
					word[1] = 0;
					sign = this->isR(word);
					this->SaveR(sign,word);
					n++;
					break;
				case '"':
					word[0] = m_strS[n];
					word[1] = 0;
					sign = this->isR(word);
					this->SaveR(sign,word);
					n++;
					while(m_strS[n] < 0)
					{
						strCharacter += m_strS[n];
						n++;
					}
					strCharacter += '\0';
					strcpy(word,strCharacter);
					m_CResult[m_nNum]=new CF;
				    m_CResult[m_nNum]->value=-1;
			    	m_CResult[m_nNum]->type=23;
				    m_CResult[m_nNum]->line=m_Line;
				    strcpy(m_CResult[m_nNum]->data,word);
				    m_nNum++;
					if(m_strS[n] == '"')
					{
				        word[0] = m_strS[n];
					    word[1] = 0;
					    sign = this->isR(word);
					    this->SaveR(sign,word);
					    n++;
					}
					break;
				default:
					if(m_strS[n]!=0)
					{
						word[0]=m_strS[n];
						word[1]=0;
						m_CResult[m_nNum]=new CF;
						m_CResult[m_nNum]->value=2;
						m_CResult[m_nNum]->type=0;
						m_CResult[m_nNum]->line=m_Line;
						strcpy(m_CResult[m_nNum]->data,word);
						m_nNum++;
						n++;}
						break;
			}
		}
	}
	m_CResult[m_nNum]=new CF;
	m_CResult[m_nNum]->value=0;
	m_CResult[m_nNum]->type=-1;	//结束符
    m_CResult[m_nNum]->line=m_Line;
	strcpy(m_CResult[m_nNum]->data,"");

	for(int r = 0;r<m_nNum;r++)
	{
			if(m_CResult[r]->type == 23&&m_CResult[r]->value!=-1)
				if(!isdigit(m_CResult[r]->data[1])&&m_CResult[r]->data[1]!='\0')
					return false;
	}
	return true;
}

void CFen::initiate()
{
    strcpy(m_str[0],"");
	strcpy(m_str[24],"FOR");
	strcpy(m_str[1],"TO");
	strcpy(m_str[2],"NEXT");
	strcpy(m_str[3],"UNLOOP");
	strcpy(m_str[4],"IF");
	strcpy(m_str[5],"THEN");
	strcpy(m_str[6],"GOTO");
	strcpy(m_str[7],"GOSUB");
	strcpy(m_str[8],"RETURN");
	strcpy(m_str[9],"INPUT");
	strcpy(m_str[10],"PRINT");
	strcpy(m_str[11],"END");
	strcpy(m_str[12],"REM");
	strcpy(m_str[13],"=");
	strcpy(m_str[14],",");
	strcpy(m_str[15],"(");
	strcpy(m_str[16],")");
	strcpy(m_str[17],"<");
	strcpy(m_str[18],">");
	strcpy(m_str[19],"+");
	strcpy(m_str[20],"-");
	strcpy(m_str[21],"*");
	strcpy(m_str[22],"/");
	strcpy(m_str[23],"");
	strcpy(m_str[25],"");
	strcpy(m_str[26],"CR");
	CString str = '"';
	strcpy(m_str[27],str);
	strcpy(m_str[28],"program");
	strcpy(m_Err[0],"正确!");
	strcpy(m_Err[23],"数字位数过长!");
	strcpy(m_Err[2],"非法字符!");
}

int CFen::isR(char * a)
{
    for (int i=0;i<30;i++)
		if (!::stricmp(m_str[i],a))
			return i;

		return 0; 
}

void CFen::SaveR(int sign,char *word)
{
    m_CResult[m_nNum] = new CF;
    m_CResult[m_nNum]->type = sign;
	m_CResult[m_nNum]->value = 0;
	m_CResult[m_nNum]->line=m_Line;
	strcpy(m_CResult[m_nNum]->data,word);
    m_nNum++;
}

void CFen::SaveI(char *word)
{
    m_CResult[m_nNum] = new CF;
	int q = 1;
	for(int i = 0;i < m_nNum;i++)
		{
			if(m_CResult[i]->type == 23)
			{
				q++;
				if (!::stricmp(m_CResult[m_nNum]->data,word))
					m_CResult[m_nNum]->value = m_CResult[i]->value;
			}
		}
	m_CResult[m_nNum]->value = q;
	m_CResult[m_nNum]->type=23;
	m_CResult[m_nNum]->line=m_Line;
	strcpy(m_CResult[m_nNum]->data,word);
    m_nNum++;
}

void CFen::Delete()
{
    for(int i = 0;i < m_nNum;i++)
	    delete m_CResult[i];//再次进行分析时释放前一次分析的结果
}

bool CFen::Factor()
{
    switch (m_CResult[m_Cur]->type)
	{
	case 23:	
		m_Cur++;
		break;

	case 25:
		m_Cur++;
		break;

	case 15:
		m_Cur++;

		if (!Expression())
			return false;

		switch (m_CResult[m_Cur]->type)
		{
		case 16:
			break;
		default:
			return false;
		}
		m_Cur++;

		break;

	default:
		return false;
	}
	return true;
}

bool CFen::Expression()
{
	if(m_CResult[m_Cur]->type == 19 || m_CResult[m_Cur]->type == 20)  
		m_Cur++;
	if (!Term())
		return false;

	while (m_CResult[m_Cur]->type == 19 || m_CResult[m_Cur]->type == 20)
	{
		m_Cur++;
		if (!Term()) 
			return false;
	}
    return true;
}

void CFen::YuFaC()
{
	errFlag = false;
	if (m_nNum==0) 
		return;
	
	m_Cur=0;

	if(!ChengXu())
		errFlag = true;
	
}

bool CFen::Term()
{
	if(m_CResult[m_Cur]->type == 21||m_CResult[m_Cur]->type == 22)
		m_Cur++;
	if (!Factor()) 
		    return false;

	while (m_CResult[m_Cur]->type == 21||m_CResult[m_Cur]->type == 22)
	{
		m_Cur++;
		if (!Factor())
			return false;
	}

	return true;
}

bool CFen::Condition()
{
    if(m_CResult[m_Cur]->type == 15) // (
	{
		m_Cur++;
		if(m_CResult[m_Cur]->type == 23)
		{
			m_Cur++;
			switch(m_CResult[m_Cur]->type)
			{
			case 13:
			case 17: 
			case 18: 
				m_Cur++;
				break;
			default:
				return false;
			}
			if(m_CResult[m_Cur]->type == 25)   //constant
			{
				m_Cur++;
				if(m_CResult[m_Cur]->type == 16)   // )
				{
				    m_Cur++;
				    return true;
				}
			    else
                   return false;
			}
			else
			    return false;
		}
		else
			return false;
	}
	else
		return false;
    return true;
}


bool CFen::Sentence()
{
    switch (m_CResult[m_Cur]->type)
	{
		case 23:
			if(!Variable())
				return false;
			break;

		case 24:
			if (!For()) 
				return false;
			break;

		case 2:
			m_Cur++;
			if(m_CResult[m_Cur]->type != 23)
				return false;
			m_Cur++;
			break;
	
		case 3:
			m_Cur++;
			if(m_CResult[m_Cur]->type != 23)
				return false;
			m_Cur++;
			break;
    
		case 4:
			if(!If())
				return false;
			break;

		case 6:
			m_Cur++;
			if(m_CResult[m_Cur]->type != 25)
				return false;
			m_Cur++;
			break;

		case 7:
		    m_Cur++;
			if(m_CResult[m_Cur]->type != 25)
				return false;
			m_Cur++;

			break;

		case 8:
			m_Cur++;
			break;
		
		case 9:
			if(!Input())
				return false;
			break;

		case 10:
			if(!Print())
				return false;
			break;

		case 11:
			m_Cur++;
			break;

		case 12:
			if(!Rem())
				return false;
			break;
		default:
			return false;
	}
	if(m_CResult[m_Cur]->type == 26)
		 m_Cur++;
	else
		return false;
	return true;
}

bool CFen::Variable()
{
	m_Cur++;

	if(m_CResult[m_Cur]->type == 13)
		m_Cur++;
    else
		return false;

	if(!Expression())
        return false;
    return true;
}

bool CFen::For()
{
	                   
	m_Cur++;
	if(m_CResult[m_Cur]->type != 23)
		return false;
	m_Cur++;
    if(m_CResult[m_Cur]->type != 13)
		return false;
	m_Cur++;
    if(m_CResult[m_Cur]->type != 23 && m_CResult[m_Cur]->type != 25)
		return false;
	m_Cur++;
	if(m_CResult[m_Cur]->type != 1)
		return false;
	m_Cur++;
	if(m_CResult[m_Cur]->type != 23 && m_CResult[m_Cur]->type != 25)
		return false;
	m_Cur++;
    return true;
}

bool CFen::If()
{
    m_Cur++;
	if(!Condition())
		return false;
	if(m_CResult[m_Cur]->type != 5)
		return false;
	m_Cur++;
	if(m_CResult[m_Cur]->type != 25)
		return false;
	m_Cur++;
	return true;
}

bool CFen::Input()
{
    m_Cur++;
    if(m_CResult[m_Cur]->type != 23)
		return false;
	m_Cur++;
	if(m_CResult[m_Cur]->type == 14)
	{
		m_Cur++;
        if(m_CResult[m_Cur]->type != 23)
		    return false;
		m_Cur++;
		if(m_CResult[m_Cur]->type == 14)
		{
		    m_Cur++;
            if(m_CResult[m_Cur]->type != 23)
		        return false;
		    m_Cur++;
		}
	}
    return true;
}

bool CFen::Rem()
{
    m_Cur++;
	if(m_CResult[m_Cur]->type != 27)
		return false;
    m_Cur++;
	m_Cur++;

    if(m_CResult[m_Cur]->type != 27)
		return false;
	m_Cur++;
	return true;
}

bool CFen::ChengXu()
{
	this->m_Error = "";
   	switch (m_CResult[m_Cur]->type)
	{
		case 28:
			break;

		default:
			return false;
	}
   m_Cur++;	
   if (!ChengXuTi())
		return false;
   return true;
}


bool CFen::ChengXuTi()
{
	int flag[50];
	for(int i = 0;i<m_Line;i++)
		flag[i] = 1;
	int line = 1;
	while(m_CResult[m_Cur]->type != -1)
	{
        switch (m_CResult[m_Cur]->type)
		{
	        case 25:
		       break;

	        default:
			   flag[line] = 0;
			   line++;
		       return false;
		}
        m_Cur++;
        flag[line] = Sentence();
		line++;

		while(m_CResult[m_Cur]->line - m_CResult[m_Cur - 1]->line ==0)
			m_Cur++;

		for(i = 0;i<m_Line;i++)
		    if(flag[i] == 0&&m_CResult[m_Cur]->type == -1)
		       return false;
	}
   return true;
}

CString CFen::Format(int a)
{
    CString str;
	str.Format("%d",a);
	return str;
}

bool CFen::Print()
{
    m_Cur++;
    if(m_CResult[m_Cur]->type != 23)
		return false;
	m_Cur++;
	if(m_CResult[m_Cur]->type == 14)
	{
		m_Cur++;
        if(m_CResult[m_Cur]->type != 23)
		    return false;
		m_Cur++;
		if(m_CResult[m_Cur]->type == 14)
		{
		    m_Cur++;
            if(m_CResult[m_Cur]->type != 23)
		        return false;
		    m_Cur++;
		}
	}
    return true;
}

⌨️ 快捷键说明

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