📄 cifadlg.cpp
字号:
// 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 + -