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

📄 程序代码.txt

📁 这是一个词法分析器
💻 TXT
字号:
#include "stdafx.h"
#include "scanner.h"
#include "scannerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
CString bm[60]={"and","array","begin","bool","call","case",
				"char","constant","do","else","end","false",
				"for","if","input","integer","not","of","or",
				"output","procedure","program","read","real",
				"repeat","set","then","to","true","until","var",
				"while","write","000","001","002","003","'","(",
				")","*","*/","+",",","-","004","..","/","/*",":",
				":=",";","<","<=","<>","=",">",">=","[","]"};
 
CMapStringToString hash;

//CList<int,int> tab_list;
CList<symbol_table,symbol_table&> tab_list;   
CString str_serial;  
CList<token,token&> token;   

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



	enum { IDD = IDD_ABOUTBOX };
	

	
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	
protected:
	
	DECLARE_MESSAGE_MAP()
};

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

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

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()


CScannerDlg::CScannerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CScannerDlg::IDD, pParent)
{
	
	m_source = _T("");
	 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	this->InitialScanner();
}

void CScannerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	
	DDX_Control(pDX, IDC_TOKEN_LIST, m_token);
	DDX_Control(pDX, IDC_ERR_LIST, m_err);
	DDX_Control(pDX, IDC_SOURCE_EDIT, m_csource);
	DDX_Text(pDX, IDC_SOURCE_EDIT, m_source);

}

BEGIN_MESSAGE_MAP(CScannerDlg, CDialog)

	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_COMPILE_BUTTON, OnCompile)
	ON_BN_CLICKED(IDC_EXIT_BUTTON, OnExit)
	
END_MESSAGE_MAP()


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

	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
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CScannerDlg::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 CScannerDlg::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 CScannerDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

bool CScannerDlg::InitialScanner()		 
{
	CString s1;
	hash.InitHashTable(60,true);
	for(int i=0;i<60;i++)
	{
		s1.Format("%d",i+1);
		hash.SetAt(bm[i],s1);
	}
	line=0;
	column=0;

	return true;
}

void CScannerDlg::OnCompile() 
{
	UpdateData(true);

	CString s_line,s_buf;
	int len;
	char ch_1;
	if(m_source=="") 
	{
		AfxMessageBox("源程序为空,请输入程序");
		return;
	}

	len=m_csource.GetLineCount();
	while(line<m_csource.GetLineCount())
	{
		column=0;
		len=m_csource.LineLength(line);
		m_csource.GetLine(line,s_line.GetBuffer(len),len);//
		s_line.ReleaseBuffer();
		s_line.TrimLeft(32);  //去掉空格
		s_line.TrimRight(32);
		if (s_line=="")			//去掉空行
		{
			line++;
			continue;
		}

		line_length=s_line.GetLength();
		while(column<line_length)
		{
			ch_1=s_line[column];
			if(ch_1==32)		
			{
				column++;   
				continue;
			}
			if(!err_decide(ch_1))  
			{
				continue;
			}

		    if ((ch_1>='a'&&ch_1<='z')||(ch_1>='A'&&ch_1<='Z')||(ch_1=='_'))
			Indicator(s_line); 
			else 
			{		
				    if(ch_1>=48&&ch_1<=57)
					ScanConstNum(s_line); 
					else //分界符,运算符注解识别
			}
		}
		line++;
	}
	
}

void CScannerDlg::Indicator(CString s_line)
{
	char ch_1;
	int col_initial,pos;
	col_initial=column;
	CString s_return,s_word;
	symbol_table s_tab;
    ch_1=s_line[column];

	//读一个完整的单词
	while(((ch_1>='a'&&ch_1<='z')||(ch_1>='A'&&ch_1<='Z')||ch_1=='_')&&(column<line_length))
	{
		if(!err_decide(ch_1))
			return;
		column++;
		if (column>=line_length) 
		{
			break;
		}
		ch_1=s_line[column];
	}

	if(col_initial<column)
		s_word=s_line.Mid(col_initial,column-col_initial);//取完整单词
	else
		return;

	if(hash.Lookup(s_word,s_return)) //是关键词
		m_token.AddString("("+s_return+",_)");
	else             //是标示符
	{  
		pos=str_serial.Find(s_word,0);
		if(pos==-1)         //符号串中不存在该符号,插入
		{
			if(tab_list.IsEmpty()) 
				s_tab.entry=0;
			else 
			{
				s_tab.entry=tab_list.GetTail().entry+1;
			}
				s_tab.pos=str_serial.GetLength();      //插入符号表
				s_tab.len=s_word.GetLength();        //增加字符#
			    tab_list.AddTail(s_tab);
				str_serial+=s_word+'#';                //每个单词用#隔开
				CString s;
				s.Format("%d",s_tab.entry);
				m_token.AddString("(34,"+s+")");       //添加token串

		}
		else										//符号串中存在该符号
		{
			symbol_table s_temple;
			POSITION ps;
			ps=tab_list.GetHeadPosition();
			s_temple=(symbol_table)tab_list.GetHead();
			while(s_temple.pos!=pos)
			{
				s_temple=tab_list.GetNext(ps);
			}
			CString s1;
			s1.Format("%d",s_temple.entry);
			m_token.AddString("(34,"+s1+")");
		}
	}
}

bool CScannerDlg::err_decide(char ch)
{
	CString s_return,s_err,s1;
	if(hash.Lookup(&ch,s_return)||(ch==32)||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>=48&&ch<=57)||ch=='_')   
		return true;
	else
	{
		s_err.Format("第%d行第%d列非法字符",line+1,column+1);
		column++;
		m_err.AddString(s_err);
		return false;
	}
}

void CScannerDlg::OnExit() 
{
	this->OnOK();
}

void CScannerDlg::ScanConstNum(CString s_line)//数字常量识别
{
	char ch;
	int col_ini;
	CString s_word;
	symbol_table s_tab;

	col_ini=column;
	ch=s_line[column];
	
	while(ch<=57&&ch>=48&&column<line_length)
	{
		if(!err_decide(ch))
			return;
		column++;
		if(column>=line_length) 
		{
			break;
		}
		ch=s_line[column];
	}

	if(ch!='.')		//整型数据
	{
		if(col_ini<column)
			s_word=s_line.Mid(col_ini,column-col_ini);//取完整单词
		else
			return;
		
		if(tab_list.IsEmpty()) 
		   s_tab.entry=0;
		else 
		   s_tab.entry=tab_list.GetTail().entry+1;

		s_tab.type=1;//整型
		s_tab.kind=2;//常量
		s_tab.val=s_word;
		tab_list.AddTail(s_tab);
		CString s0;
		s0.Format("%d",s_tab.entry);
		m_token.AddString("(35,"+s0+")");
	}
	else		//符点型数据
	{
		if(column>=line_length-1)//出错
			return;
		else
		column++;   //跳过.
	
		ch=s_line[column];
		while(ch<=57&&ch>=48&&column<line_length)
		{
			if(!err_decide(ch))
				return;
			column++;
			if(column>=line_length) 
			{
				break;
			}
			ch=s_line[column];
		}
		if(ch!='e')
		{
			if(col_ini<column)
		      s_word=s_line.Mid(col_ini,column-col_ini);//取完整单词
			else
				return;

			if(tab_list.IsEmpty()) 
		      s_tab.entry=0;
		    else 
		       s_tab.entry=tab_list.GetTail().entry+1;

			s_tab.type=2;//实型
			s_tab.kind=2;//常量
			s_tab.val=s_word;
			tab_list.AddTail(s_tab);
			CString s0;
			s0.Format("%d",s_tab.entry);
			m_token.AddString("(36,"+s0+")");
		}
		else   //带e
		{
			if(column>=line_length-1)
				return;
			else
				column++;
			ch=s_line[column];
			if((ch=='+'||ch=='-'||(ch<=57&&ch>=48)))
			{
				if(!err_decide(ch))
					return;
				if((ch=='+'||ch=='-')&&(column<line_length-1))
					column++;
			
				while(ch<=57&&ch>=48&&column<line_length)
				{
					if(!err_decide(ch))
						return;
					column++;
					if(column>=line_length) 
					{
						break;
					}
					ch=s_line[column];
				}
				if(col_ini<column)
		           s_word=s_line.Mid(col_ini,column-col_ini);//取完整单词
				else
					return;
				if(tab_list.IsEmpty()) 
				  s_tab.entry=0;
				else 
		          s_tab.entry=tab_list.GetTail().entry+1;

				s_tab.type=2;//实型
				s_tab.kind=2;//常量
				s_tab.val=s_word;
				tab_list.AddTail(s_tab);
				CString s0;
				s0.Format("%d",s_tab.entry);
				m_token.AddString("(36,"+s0+")");
			}
			else
			{
				CString s_err;
				s_err.Format("第%d行第%d列--->第%d行第%d列实常数表示形式错误",line+1,col_ini+1,line+1,column+1);
				m_err.AddString(s_err);
				return;
			}
		}
	}
}

void CScannerDlg::cacusymbol_scan(CString s_line)   
{
	char ch;
	int col_ini;
	CString s_word;
	CString s1,s_return;
	symbol_table s_tab;

	col_ini=column;
	ch=s_line[column];

	if(ch=='/')
	{
		if(column==line_length-1)//'/'后无字符
		{
			s1.Format("第%d行第%d列非法注释符",line+1,column+1);
			m_err.AddString(s1);
			column=line_length-1;
			return;
		}
		else
		{
			if(s_line[column+1]=='/')
			{
				column=line_length-1;
				return;
			}
			else
			{
				if(column==0)   //如果/为首字符,错误
				{
					s1.Format("第%d行第%d列是非法除号",line+1,column+1);
					m_err.AddString(s1);
					if(column<line_length-1)
					column++;
					return;
				}
				else
				{
					m_token.AddString("(48,_)");
				}
				
			}

		}
	}
	else		//运算符或者分界符
	{
		if(err_decide(ch))
		{
			CString s3;
			s3.Format("%c",ch);
			if(hash.Lookup(s3,s_return))
			{
			if(s_return>"38")
			{
				s1=CString(s_return);
				if(column>=line_length-1)
				{
					m_token.AddString("("+s_return+",_)");
					column++;
					return;
				}
				ch=s_line[column+1];
				s3.Format("%c",ch);
				if(err_decide(ch))
				{
					if(hash.Lookup(s3,s_return)&&s_return>"38")
					{
						s_word=s_line.Mid(column,2);
						hash.Lookup(s_word,s_return);
						m_token.AddString("("+s_return+",_)");
						column+=2;
						return;
					}
					else
					{
						m_token.AddString("("+s1+",_)");
						column++;
					}
					
				}
			}
			}
		}
	}
}

⌨️ 快捷键说明

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