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

📄 fc-compile.cpp

📁 编译原理的一个课程设计
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "stdafx.h"
#include "FC.h"
#include "FCDlg.h"
#include <math.h>

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

CFCDlg::ZIdentType CFCDlg::GetIdentType(char ident[IDENTLENGTH])
{
	int i;
	for(i=0;i<=m_iFunction;i++)//查找函数名字列表
		if(strcmp(ident,m_function[i].name)==0)
			return IT_FUNCTION;
	if(m_iFunction>=0 && m_iFunction<=m_iFunction)
	{
		for(i=m_function[m_iFunction].iIdent-1;i>=0;i--)//查找变量列表
			if(strcmp(ident,m_function[m_iFunction].ident[i].name)==0)//标识符名相同
			{
				if(m_function[m_iFunction].ident[i].level==m_function[m_iFunction].level)
					return m_function[m_iFunction].ident[i].type;//当前作用域的变量或数组
				else if(m_function[m_iFunction].ident[i].level>=0)
				{
					switch(m_function[m_iFunction].ident[i].type)
					{
					case IT_INT:return IT_INTINRANG;
					case IT_DOUBLE:return IT_DOUBLEINRANG;
					case IT_INTARRAY:return IT_IARRAYINRANG;
					case IT_DOUBLEARRAY:return IT_DARRAYINRANG;
					}
				}
			}
		for(i=0;i<m_function[m_iFunction].iParam;i++)//查找参数列表
			if(strcmp(ident,m_function[m_iFunction].param[i].name)==0)
				return m_function[m_iFunction].param[i].type;
	}
	return IT_NULL;
}

BOOL CFCDlg::ErrorReport(CFCErrorDlg::ZErrorType et)
{
	m_iErrorCount++;
	int i,i0,cnt=0;
	for(i=0;cnt<m_iLine;i++)
		if(m_source[i]=='\n')
			cnt++;
	i0=i;
	for(i0=i;i<m_SourceLength;i++)
		if(m_source[i]=='\r')
			break;
	CFCErrorDlg dlg;
	MessageBeep(0);
	if(dlg.ErrorReport(m_iLine+1,m_source.Mid(i0,i-i0),et)==IDCANCEL)
	{
		if(m_iStatus==2)On_ExitCompile();
		else if(m_iStatus==4)On_ExitTranslate();
		return FALSE;
	}
	return TRUE;
}

BOOL CFCDlg::SearchMain(void)
{
	int i,cnt,n;
	for(i=0;i<m_iFunction;i++)
		if(strcmp("main",m_function[i].name)==0)
			break;
	if(i==m_iFunction)
	{
		if(!ErrorReport(CFCErrorDlg::ET_NOMAIN))
			return FALSE;
	}
	else if(m_function[i].iParam!=0)
	{
		if(!ErrorReport(CFCErrorDlg::ET_PARAMMAIN))
			return FALSE;
	}
	else if(m_function[i].ReturnType!=IT_VOID)
	{
		if(!ErrorReport(CFCErrorDlg::ET_NOVOIDMAIN))
			return FALSE;
	}
	n=2*i+1;
	cnt=0;
	for(i=1;cnt<n && i<nCODE;i++)
		if(m_code[i].op==OP_NULL)
			cnt++;
	m_code[0].op=OP_CALL;
	m_code[0].sd.iNumber=i-1;
	return TRUE;
}

BOOL CFCDlg::TestCode(void)
{
	if(m_iCode>=nCODE)
		return ErrorReport(CFCErrorDlg::ET_LONGPROGRAM);
	return TRUE;
}

BOOL CFCDlg::GetElement(void)//词法分析函数
{
	while(1)//跳过空格,tab,回车符,注释
	{
		if(m_iCount>=m_SourceLength)//到达源代码尾
		{
			m_curElement=E_FILEEND;
			return TRUE;
		}
		if(m_source[m_iCount]==' ' || m_source[m_iCount]=='\t' || //空白字符
			m_source[m_iCount]=='\r' || m_source[m_iCount]=='\n')	//换行字符
		{
			if(m_source[m_iCount]=='\n')
				m_iLine++;
			m_iCount++;
		}
		else if(m_source[m_iCount]=='/' && m_iCount+1<m_SourceLength) //可能为注释
		{
			if(m_source[m_iCount+1]=='/')//单行注释
			{
				for(m_iCount+=2;m_iCount<m_SourceLength && m_source[m_iCount]!='\n';m_iCount++);
				if(m_iCount!=m_SourceLength)
				{
					m_iCount++;
					m_iLine++;
				}
			}
			else if(m_source[m_iCount+1]=='*')//多行注释
			{
				m_iCount+=2;
				while(1)
				{
					if(m_iCount>=m_SourceLength)
					{
						m_curElement=E_FILEEND;
						return TRUE;
					}
					if(m_source[m_iCount]=='\r')
						m_iLine++;
					else if(m_source[m_iCount]=='*' && m_iCount+1<m_SourceLength &&
						m_source[m_iCount+1]=='/')
					{
						m_iCount+=2;
						break;
					}
					m_iCount++;
				}
			}
			else break;
		}
		else break;
	}
	switch(m_source[m_iCount])//此处处理运算符
	{
		case '+':
			m_iCount++;
			m_curElement=E_PLUS;
			return TRUE;
		case '-':
			m_iCount++;
			m_curElement=E_MINUS;
			return TRUE;
		case '*':
			m_iCount++;
			m_curElement=E_TIMES;
			return TRUE;
		case '/':
			m_iCount++;
			m_curElement=E_SLASH;
			return TRUE;
		case '%':
			m_iCount++;
			m_curElement=E_MOD;
			return TRUE;
		case '(':
			m_iCount++;
			m_curElement=E_LPAREN;
			return TRUE;
		case ')':
			m_iCount++;
			m_curElement=E_RPAREN;
			return TRUE;
		case '[':
			m_iCount++;
			m_curElement=E_LSUB;
			return TRUE;
		case ']':
			m_iCount++;
			m_curElement=E_RSUB;
			return TRUE;
		case '{':
			m_iCount++;
			m_curElement=E_BEGIN;
			return TRUE;
		case '}':
			m_iCount++;
			m_curElement=E_END;
			return TRUE;
		case ',':
			m_iCount++;
			m_curElement=E_COMMA;
			return TRUE;
		case ':':
			m_iCount++;
			m_curElement=E_COLON;
			return TRUE;
		case ';':
			m_iCount++;
			m_curElement=E_SEMICOLON;
			return TRUE;
		case '!':
			if(m_iCount+1<m_SourceLength && m_source[m_iCount+1]=='=')
			{
				m_iCount+=2;
				m_curElement=E_NOTEQUAL;
			}
			else
			{
				m_iCount++;
				m_curElement=E_NOT;
			}
			return TRUE;
		case '>':
			if(m_iCount+1<m_SourceLength && m_source[m_iCount+1]=='=')
			{
				m_iCount+=2;
				m_curElement=E_GREATEQUAL;
			}
			else
			{
				m_iCount++;
				m_curElement=E_GREAT;
			}
			return TRUE;
		case '<':
			if(m_iCount+1<m_SourceLength && m_source[m_iCount+1]=='=')
			{
				m_iCount+=2;
				m_curElement=E_LESSEQUAL;
			}
			else
			{
				m_iCount++;
				m_curElement=E_LESS;
			}
			return TRUE;
		case '=':
			if(m_iCount+1<m_SourceLength && m_source[m_iCount+1]=='=')
			{
				m_iCount+=2;
				m_curElement=E_EQUAL;
			}
			else
			{
				m_iCount++;
				m_curElement=E_BECOMES;
			}
			return TRUE;
		case '&':
			if(m_iCount+1<m_SourceLength && m_source[m_iCount+1]=='&')
			{
				m_iCount+=2;
				m_curElement=E_AND;
				return TRUE;
			}
			else
			{
				ErrorReport(CFCErrorDlg::ET_UNKNOWNTOKEN);
				return FALSE;
			}
		case '|':
			if(m_iCount+1<m_SourceLength && m_source[m_iCount+1]=='|')
			{
				m_iCount+=2;
				m_curElement=E_OR;
				return TRUE;
			}
			else
			{
				ErrorReport(CFCErrorDlg::ET_UNKNOWNTOKEN);
				return FALSE;
			}
	}//end switch
	if(m_source[m_iCount]>='0' && m_source[m_iCount]<='9')//此处处理数
	{
		int d=0,l=0,n=0;
		do
		{
			n*=10;
			n+=m_source[m_iCount]-'0';
			m_iCount++;
		}
		while(m_iCount<m_SourceLength &&
			m_source[m_iCount]>='0' && m_source[m_iCount]<='9');
		if(m_iCount<m_SourceLength && m_source[m_iCount]=='.')//有小数点
		{
			m_iCount++;
			if(m_iCount<m_SourceLength &&
				m_source[m_iCount]>='0' && m_source[m_iCount]<='9')
			{	//实数
				m_dCurNumber=n;
				do
				{
					l++;
					m_dCurNumber+=(m_source[m_iCount]-'0')/pow(10,l);
					m_iCount++;
				}
				while(m_iCount<m_SourceLength &&
					m_source[m_iCount]>='0' && m_source[m_iCount]<='9');
				m_curElement=E_DNUMBER;
				return TRUE;
			}
		}
		//无小数点或小数点后没有数字 -- 整数
		m_curElement=E_INUMBER;
		m_nCurNumber=n;
		return TRUE;
	}
	if((m_source[m_iCount]>='a' && m_source[m_iCount]<='z') ||//标识符或者关键字
		(m_source[m_iCount]>='A' && m_source[m_iCount]<='Z') || 
		m_source[m_iCount]=='_' )
	{
		char str[IDENTLENGTH];
		int i=0;
		while(m_iCount<m_SourceLength &&	//此循环获取连续的字母数字下划线串
			((m_source[m_iCount]>='a' && m_source[m_iCount]<='z') ||
			(m_source[m_iCount]>='A' && m_source[m_iCount]<='Z') ||
			(m_source[m_iCount]>='0' && m_source[m_iCount]<='9') ||
			m_source[m_iCount]=='_' ) )
		{
			if(i==IDENTLENGTH-1)//标识符过长
			{
				if(ErrorReport(CFCErrorDlg::ET_LONGIDENT))
				{//返回TRUE,继续编译,跳过过长的标识符
					while(m_iCount<m_SourceLength &&
						((m_source[m_iCount]>='a' && m_source[m_iCount]<='z') ||
						(m_source[m_iCount]>='A' && m_source[m_iCount]<='Z') ||
						(m_source[m_iCount]>='0' && m_source[m_iCount]<='9')))
							m_iCount++;
					m_curElement=E_IDENT;
					str[IDENTLENGTH-1]='\0';
					strcpy(m_curIdent,str);
					return TRUE;
				}
				else return FALSE;
			}
			str[i]=m_source[m_iCount];
			i++;
			m_iCount++;
		}//while end
		str[i]='\0';
		strlwr(str);
		switch(str[0])//根据首字母判断关键字
		{
		case 'b':
			if(strcmp("break",str)==0)
			{
				m_curElement=E_BREAK;
				return TRUE;
			}
			break;
		case 'c':
			if(strcmp("case",str)==0)
			{
				m_curElement=E_CASE;
				return TRUE;
			}
			if(strcmp("continue",str)==0)
			{
				m_curElement=E_CONTINUE;
				return TRUE;
			}
			break;
		case 'd':
			if(strcmp("default",str)==0)
			{
				m_curElement=E_DEFAULT;
				return TRUE;
			}
			if(strcmp("double",str)==0)
			{
				m_curElement=E_DOUBLE;
				return TRUE;
			}
			if(strcmp("do",str)==0)
			{
				m_curElement=E_DO;
				return TRUE;
			}
			break;
		case 'e':
			if(strcmp("else",str)==0)
			{
				m_curElement=E_ELSE;
				return TRUE;
			}
			if(strcmp("exit",str)==0)
			{
				m_curElement=E_EXIT;
				return TRUE;
			}
			break;
		case 'i':
			if(strcmp("if",str)==0)
			{
				m_curElement=E_IF;
				return TRUE;
			}
			if(strcmp("int",str)==0)
			{
				m_curElement=E_INT;
				return TRUE;
			}
			if(strcmp("input",str)==0)
			{
				m_curElement=E_INPUT;
				return TRUE;
			}
			break;
		case 'o':
			if(strcmp("output",str)==0)
			{
				m_curElement=E_OUTPUT;
				return TRUE;
			}
			break;
		case 'r':
			if(strcmp("return",str)==0)
			{
				m_curElement=E_RETURN;
				return TRUE;
			}
			break;
		case 's':
			if(strcmp("switch",str)==0)
			{
				m_curElement=E_SWITCH;
				return TRUE;
			}
		case 'v':
			if(strcmp("void",str)==0)
			{
				m_curElement=E_VOID;
				return TRUE;
			}
			break;
		case 'w':
			if(strcmp("while",str)==0)
			{
				m_curElement=E_WHILE;
				return TRUE;
			}
			break;
		}//switch end
		strcpy(m_curIdent,str);
		m_curElement=E_IDENT;
		return TRUE;
	}
	if(m_source[m_iCount]=='\"')//此处处理字符串
	{
		CString str="";
		BOOL bSys=FALSE;//转义字符标记
		for(m_iCount++;m_iCount<m_SourceLength;m_iCount++)
		{
			if(!bSys && m_source[m_iCount]=='\\')//转义字符
				bSys=TRUE;
			else if(bSys)
			{
				switch(m_source[m_iCount])
				{
				case 'n'://回车符
					str+="\r\n";
					break;
				case 't':
					str+='\t';
					break;
				case '\"'://引号
					str+='\"';
					break;
				case '\\':
					str+='\\';
					break;
				case '\r'://多行字符串
					m_iCount++;
					m_iLine++;
					break;
				default:
					str+='\\';
					str+=m_source[m_iCount];
					break;
				}
				bSys=FALSE;
			}
			else if(m_source[m_iCount]=='\"')//字符串结束
			{
				m_iCount++;
				m_curElement=E_STRING;
				m_curString=str;
				return TRUE;
			}
			else if(m_source[m_iCount]=='\r')//换行,字符串意外结束
			{
				if(ErrorReport(CFCErrorDlg::ET_STRINGNOEND))
				{	//返回TRUE,继续编译,
					m_curElement=E_STRING;
					m_curString=str;
					return TRUE;
				}
				else return FALSE;
			}
			else str+=m_source[m_iCount];
		}//end for
		//若能运行到此处,必有m_iCount==m_SourceLength,即到达源代码尾而字符串没结束
		if(ErrorReport(CFCErrorDlg::ET_STRINGNOEND))
		{	//返回TRUE,继续编译,
			m_curElement=E_STRING;
			m_curString=str;
			return TRUE;
		}
		else return FALSE;
	}
	//若能运行到此处,即碰到无法认识的字符
	ErrorReport(CFCErrorDlg::ET_UNKNOWNTOKEN);
	return FALSE;
}

int CFCDlg::SearchFunction(int n)

⌨️ 快捷键说明

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