📄 程序代码.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 + -