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

📄 cifadlg.cpp

📁 simple语言的词法和语法分析
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// CIFADlg.cpp : implementation file
//

#include "stdafx.h"
#include "CIFA.h"
#include "CIFADlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCIFADlg dialog

CCIFADlg::CCIFADlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCIFADlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCIFADlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCIFADlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCIFADlg)
	DDX_Control(pDX, IDC_YUFA, m_yufa);
	DDX_Control(pDX, IDC_FUHAO, m_fuhao);
	DDX_Control(pDX, IDC_EDIT2, m_result);
	DDX_Control(pDX, IDC_EDIT1, m_program);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCIFADlg, CDialog)
	//{{AFX_MSG_MAP(CCIFADlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, OnScanner)
	ON_BN_CLICKED(IDOK2, OnYufa)
	ON_BN_CLICKED(IDTEST, OnTest)
	ON_BN_CLICKED(IDOK3, OnFuhao)
	ON_BN_CLICKED(IDABOUT, OnAbout)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCIFADlg message handlers

BOOL CCIFADlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	strcpy(kw[0],"");
	strcpy(kw[1],"and");
	strcpy(kw[2],"array");
	strcpy(kw[3],"begin");
	strcpy(kw[4],"bool");
	strcpy(kw[5],"call");
	strcpy(kw[6],"case");
	strcpy(kw[7],"char");
	strcpy(kw[8],"constant");
	strcpy(kw[9],"do");
	strcpy(kw[10],"else");
	strcpy(kw[11],"end");
	strcpy(kw[12],"false");
	strcpy(kw[13],"for");
	strcpy(kw[14],"if");
	strcpy(kw[15],"input");
	strcpy(kw[16],"integer");
	strcpy(kw[17],"not");
	strcpy(kw[18],"of");
	strcpy(kw[19],"or");
	strcpy(kw[20],"token");
	strcpy(kw[21],"procedure");
	strcpy(kw[22],"program");
	strcpy(kw[23],"read");
	strcpy(kw[24],"real");
	strcpy(kw[25],"repeat");
	strcpy(kw[26],"set");
	strcpy(kw[27],"then");
	strcpy(kw[28],"to");
	strcpy(kw[29],"true");
	strcpy(kw[30],"until");
	strcpy(kw[31],"var");
	strcpy(kw[32],"while");
	strcpy(kw[33],"write");
	strcpy(kw[34],"");		//标识符
	strcpy(kw[35],"");		//整常数
	strcpy(kw[36],"");		//实常数
	strcpy(kw[37],"");		//实符常数
	strcpy(kw[38],"'");
	strcpy(kw[39],"(");
	strcpy(kw[40],")");
	strcpy(kw[41],"*");
	strcpy(kw[42],"*/");
	strcpy(kw[43],"+");
	strcpy(kw[44],",");
	strcpy(kw[45],"-");
	strcpy(kw[46],"`");
	strcpy(kw[47],".");		//......
	strcpy(kw[48],"/");
	strcpy(kw[49],"/*");
	strcpy(kw[50],":");
	strcpy(kw[51],":=");
	strcpy(kw[52],";");		
	strcpy(kw[53],"<");
	strcpy(kw[54],"<=");
	strcpy(kw[55],"<>");
	strcpy(kw[56],"=");
	strcpy(kw[57],">");
	strcpy(kw[58],">=");
	strcpy(kw[59],"[");
	strcpy(kw[60],"]");

	strcpy(m_szErrMsg[0],"正确!");
	strcpy(m_szErrMsg[1],"数字位数过长!");
	strcpy(m_szErrMsg[2],"非法字符!");
	strcpy(m_szErrMsg[3],"缺少关键字“ program ”!");
	strcpy(m_szErrMsg[4],"program 后缺少标识符!");
	strcpy(m_szErrMsg[5],"缺少“ ; ”符号!");
	strcpy(m_szErrMsg[6],"缺少程序结束符“ . ”符号!");
	strcpy(m_szErrMsg[7],"缺少《程序体》,应为 begin,integer,real,char,bool,procedure");
	strcpy(m_szErrMsg[8],"缺少保留字“ begin ”!");
	strcpy(m_szErrMsg[9],"缺少《语句》,应为 begin,ID,if,while,call");
	strcpy(m_szErrMsg[10],"缺少保留字“ end ”!");
	strcpy(m_szErrMsg[11],"缺少《声明》,应为 integer,real,char,bool,procedure");
	strcpy(m_szErrMsg[12],"缺少保留字 integer 或 real!");
	strcpy(m_szErrMsg[13],"procedure 后缺少标识符!");
	strcpy(m_szErrMsg[14],"变量声明后缺少标识符!");
	strcpy(m_szErrMsg[15],"缺少保留字“ procedure ”!");
	strcpy(m_szErrMsg[16],"缺少 “ ( ”符号!");
	strcpy(m_szErrMsg[17],"缺少 “ ) ”符号!");
	strcpy(m_szErrMsg[18],"缺少形参标识符 !");
	strcpy(m_szErrMsg[19],"缺少 “ : ”符号!");
	strcpy(m_szErrMsg[20],"缺少标识符!");
	strcpy(m_szErrMsg[21],"缺少赋值符号“ := ”!");
	strcpy(m_szErrMsg[22],"缺少保留字“ if ”!");
	strcpy(m_szErrMsg[23],"缺少保留字“ then ”!");
	strcpy(m_szErrMsg[24],"缺少保留字“ while ”!");
	strcpy(m_szErrMsg[25],"缺少保留字“ do ”!");
	strcpy(m_szErrMsg[26],"缺少保留字“ call ”!");
	strcpy(m_szErrMsg[27],"缺少被调过程名标识符!");
	strcpy(m_szErrMsg[28],"缺少项");
	strcpy(m_szErrMsg[29],"缺少《布尔表达式》,应为(,ID,NUMBER");
	strcpy(m_szErrMsg[30],"缺少《关系》!");
	strcpy(m_szErrMsg[31],"变量名不能和过程名相同!");
	strcpy(m_szErrMsg[32],"标识符重复声明!");
	strcpy(m_szErrMsg[33],"未声明标识符!");
	strcpy(m_szErrMsg[34],"不能直接引用过程名!");
	strcpy(m_szErrMsg[35],"不能从real转换为integer类型!");
	strcpy(m_szErrMsg[36],"不能用常数作实参!");
	strcpy(m_szErrMsg[37],"变参应为变量!");
	strcpy(m_szErrMsg[38],"实参个数不足!");
	strcpy(m_szErrMsg[39],"只有integer和integer才能比较!");
	strcpy(m_szErrMsg[40],"不能这样调用过程!");
	strcpy(m_szErrMsg[41],"");
	strcpy(m_szErrMsg[42],"");
	strcpy(m_szErrMsg[43],"");
	strcpy(m_szErrMsg[96],"源程序结束符 end. 后还有多余内容!");
	strcpy(m_szErrMsg[97],"语法错误太多,终止语法分析!");
	strcpy(m_szErrMsg[98],"源程序不正常结束!");
	strcpy(m_szErrMsg[99],"内存不足!词法分析终止!");

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CCIFADlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CCIFADlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CCIFADlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


void CCIFADlg::OnTest() 
{
	// TODO: Add your control notification handler code here
	CString test;
	test="/*欢迎使用词法语法扫描测试程序*/";
	test+="/*\r\n本程序由哈工大(威海)*/";
    test+="/*\r\n   计算机0304101班完成*/";
	test+="\r\nprogram abc;";
	test+="\r\n  integer x,y,z;  ";
	test+="\r\n  real a,b;";
	test+="\r\n  procedure ab(var m,n:integer; t:real); ";
	test+="\r\n    begin";
	test+="\r\n     t:=(n+2)*m;";
	test+="\r\n      if m>n then   ";
	test+="\r\n         n:=m ";
	test+="\r\n      else ";
	test+="\r\n         t:=m;";
	test+="\r\n      while n<m do ";
	test+="\r\n        begin";
	test+="\r\n          n:=n+1";
	test+="\r\n        end";
	test+="\r\n    end;";
	test+="\r\nend";
	test+="\r\n.  ";

	m_program.SetWindowText(test);
}

void CCIFADlg::OnScanner() 
{
	// TODO: Add your control notification handler code here
	m_result.SetWindowText("");
	//initiate
	n=0;
	tn=0;
	p=0;
	en=0;
	strcpy(strtable,"");
	token="\t词法分析结果\r\n二元式(类型,值)单词\r\n";

	int sz=m_program.GetWindowText(program,10000);   //获得源代码

	while(program[n])
	{
		m_cifa[n].entry=-1;
		m_cifa[n].kind=-2;
		m_cifa[n].length=-1;
		strcpy(m_cifa[n].type,"空\0");
		m_cifa[n].val=-1;
		m_cifa[n].addr=-1;
		sort();
	}

	m_cifa[tn].kind=-1;	//输入结束符
	outputr();		//输出
}

void CCIFADlg::sort()
{	
	if(isalpha(program[n]))			//字母
		recogid();
	else if(isdigit(program[n]))	//数字
		recogdig();
	else if(program[n]=='/')		//注释
		handlecom();
	else if(program[n]==' ')		//空格
		n++;
	else							//各种界限符
		recogdel();
}

void CCIFADlg::recogid()
{
	int i=0,kn;
	bool flag=true;

	strcpy(word,"");

	while(flag)
	{
		if(isalnum(program[n]))		//字母或数字
		{
			word[i]=program[n];
			i++;
			n++;
		}
		else	flag=false;
	}
	word[i]='\0';		//给word加入结束符

	kn=iskeyword(word);
	if(kn>0)		//是否为关健字
	{
		str.Format("(%d,'%s')\t%s\r\n",kn,word,word);
		token+=str;
		m_cifa[tn].kind=kn; 
		tn++;
	}
	else		//不是则查填符号表
		lookup();
}

void CCIFADlg::recogdig()
{ 
	int i=0;
	bool flag=true;
	
	strcpy(word,"");

	while(flag)
	{
		if(isdigit(program[n]))
		{
			word[i]=program[n];
			i++;
			n++;
		}
		else if(isalpha(program[n]))	
		{
			printerr("变量格式错误");				//变量格式错误		
			n++;
			break;
		}
		else
			flag=false;
	}

	if(!flag)
	{
		word[i]='\0';
		long v;
		v=strtol(word,NULL,10);

		m_cifa[tn].kind=35;
		strcpy(m_cifa[tn].type,"整变量\0");
		str.Format("(35,%ld)\t%ld\r\n",v,v);		//整常数
		token+=str;
		tn++;
	}

}

void CCIFADlg::handlecom()
{
	int kn;
	char sign[3];
	bool flag=false;

	n++;
	if(program[n]!='*')
	{
		sign[0]=program[n-1];
		sign[1]='\0';
		kn=iskeyword(sign);
		str.Format("(%d,_)\t/\r\n",kn);
		token+=str;
	}
	else{
		while(program[n])
		{
			n++;
			if(program[n]=='*')
			{
				n++;
				if(program[n]=='/')
				{
					n++;
					flag=true;
					break;
				}
			}
		}
	}
	if(!flag)						//没有注解的结束符
		printerr("没有注解的结束符");
}

void CCIFADlg::recogdel()
{
	
	int kn1,kn2;
	char sign[3];

	sign[0]=program[n];				//假设为一位编码
	sign[1]='\0';
	kn1=iskeyword(sign);
	str.Format("(%d,_)\t%s\r\n",kn1,sign);
	n++;
	m_cifa[tn].kind=kn1;

	sign[1]=program[n];			//若为两位的编码,则改写
	sign[2]='\0';
	kn2=iskeyword(sign);
	if(kn2)
	{
		str.Format("(%d,_)\t%s\r\n",kn2,sign);
		m_cifa[tn].kind=kn2;
		n++;
	}

	if(!(kn1||kn2))					//为回车或不存在这个符号
		if(sign[0]=='\r'&&sign[1]=='\n')
			n++;//还需要行计数加1,列计数为0
		else
			printerr("存在非法符号");
	else
		{	token+=str;
			tn++;
		}
	
}

void CCIFADlg::lookup()
{
	if(isalpha(word[0]))		//标识符或字符串
	{
		int existp=check();	//是否已存在符号表中
		if(existp<0)	//不存在
		{
			strcat(strtable,word);	
			m_cifa[tn].entry=p;
			m_cifa[tn].kind=34;			//34为标识符
			strcpy(m_cifa[tn].type,"简变\0");
			m_cifa[tn].length=strlen(word);
			p+=m_cifa[tn].length;
			tn++;
		}	
		else{		//存在
			m_cifa[tn].entry=existp;
			m_cifa[tn].kind=34;			//34为标识符
			strcpy(m_cifa[tn].type,"简变\0");
			m_cifa[tn].length=strlen(word);
			tn++;
		}
		str.Format("(34,'%s')\t%s\r\n",word,word);
		token+=str;
	}
	else if(isdigit(word[0]))		//数字常数
	{

	}
//	else
}


void CCIFADlg::outputr()
{
	CString st="";
	
	//输出token串
	str.Format("\r\n共发现%d个错误",en);
	token+=str;	

	token+=st;
	m_result.SetWindowText(token);
}


void CCIFADlg::OnFuhao() 
{
	// TODO: Add your control notification handler code here
	int num=0,i;
	CString st="";
	
	while(m_cifa[num].kind>=0)
		num++;

	//输出符号串
	st+="符号串:";
	st+=strtable;
	st+="\r\n";

	//输出符号表
	str.Format("\t\t符号表\r\nentry\tkind\tlength\ttype\tval\taddr\r\n");
	st+=str;	

	//输出符号表
	for(i=0;i<num;i++)					///////////////////////////////////////////
	{
		if(m_cifa[i].entry>=0)	{str.Format("%d\t",m_cifa[i].entry);	st+=str;}
			else	st+="\t";
		if(m_cifa[i].kind>=-1)	{str.Format("%d\t",m_cifa[i].kind);	st+=str;}
			else	st+="\t";
		if(m_cifa[i].length>0)	{str.Format("%d\t",m_cifa[i].length);	st+=str;}
			else	st+="\t";
		if(strcmp(m_cifa[i].type,"空")&&m_cifa[i].kind>=34&&m_cifa[i].kind<=37)	
			{st+=m_cifa[i].type;}
			else	st+="\t";
		if(m_cifa[i].val>0)	{str.Format("%d\t",m_cifa[i].val);	st+=str;}
			else	st+="\t";
		if(m_cifa[i].addr>0)	{str.Format("%d",m_cifa[i].addr);	st+=str;}
			else	st+="\t";

		str.Format("\r\n");
		st+=str;
	}

	m_fuhao.SetWindowText(st);
}



int CCIFADlg::check()
{
	int num=0,i,j;
	int en;
	char temp[20];
	
	while(m_cifa[num].kind>=0)
		num++;

	for(i=0;i<num;i++)
	{		
		for(j=0,en=m_cifa[i].entry;j<m_cifa[i].length;j++,en++)
			temp[j]=strtable[en];
		temp[j]='\0';	

		if(!strcmp(temp,word))
			return m_cifa[i].entry;
	}
	return -1;
}

int CCIFADlg::iskeyword(char *tmpstr)
{
	for (int i=1;i<=60;i++)
		if (!strcmp(kw[i],tmpstr))   //找到
			return i;

	return 0; //未找到
}



void CCIFADlg::printerr(CString err)
{
	en++;
	token+="错误:"+err+"\r\n";
}

void CCIFADlg::OnYufa() 
{
	// TODO: Add your control notification handler code here
	m_yufa.SetWindowText("");

	tn=0;
	yufafenxi();

	m_yufa.SetWindowText(m_szErrMsg[m_nErrNo]);
}

bool CCIFADlg::yufafenxi()
{
	switch (m_cifa[tn].kind)
	{
	case 22:				//从program开始
		break;

	default:
		m_nErrNo=3;		//缺少关键字“ program ”!
		m_nErrAddr=tn;
		return false;
	}

	tn++;			//分析下一个单词


	switch (m_cifa[tn].kind)
	{
	case 34:				//标志符
		break;

	default:
		m_nErrNo=4;		//program 后缺少标识符!
		m_nErrAddr=tn;
		return false;
	}


	tn++;

	switch (m_cifa[tn].kind)
	{
	case 52:			//;
		break;
	default:
		m_nErrNo=5;		//缺少“ ; ”符号!
		m_nErrAddr=tn;

⌨️ 快捷键说明

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