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

📄 impubasicview.cpp

📁 编译原理课程设计是用Microsoft Visual C++ 6.0编写。实现了语法词法及代码优化
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// IMPUBasicView.cpp : implementation of the CIMPUBasicView class
//

#include "stdafx.h"
#include "IMPUBasic语言程序设计器.h"

#include "IMPUBasic语言程序设计器Doc.h"
#include "IMPUBasicView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView

IMPLEMENT_DYNCREATE(CIMPUBasicView, CEditView)

BEGIN_MESSAGE_MAP(CIMPUBasicView, CEditView)
	//{{AFX_MSG_MAP(CIMPUBasicView)
	ON_COMMAND(ID_PROGRAM_RUN, OnProgramRun)
	ON_COMMAND(ID_RESULT_VIEW, OnResultView)
	ON_COMMAND(ID_HELP_VIEW, OnHelpView)
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView construction/destruction

CIMPUBasicView::CIMPUBasicView()
{
	// TODO: add construction code here

}

CIMPUBasicView::~CIMPUBasicView()
{
}

BOOL CIMPUBasicView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	BOOL bPreCreated = CEditView::PreCreateWindow(cs);
	cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL);	// Enable word-wrapping

	return bPreCreated;
}

/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView drawing

void CIMPUBasicView::OnDraw(CDC* pDC)
{
	CIMPUBasicDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

}

/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView printing

BOOL CIMPUBasicView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default CEditView preparation
	return CEditView::OnPreparePrinting(pInfo);
}

void CIMPUBasicView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// Default CEditView begin printing.
	CEditView::OnBeginPrinting(pDC, pInfo);
}

void CIMPUBasicView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// Default CEditView end printing
	CEditView::OnEndPrinting(pDC, pInfo);
}

/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView diagnostics

#ifdef _DEBUG
void CIMPUBasicView::AssertValid() const
{
	CEditView::AssertValid();
}

void CIMPUBasicView::Dump(CDumpContext& dc) const
{
	CEditView::Dump(dc);
}

CIMPUBasicDoc* CIMPUBasicView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIMPUBasicDoc)));
	return (CIMPUBasicDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView message handlers

void CIMPUBasicView::OnProgramRun() 
{
	    
	    val_Edit1 = "";
	    CFile file;
	    CFileDialog fdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("Basic Files(*.bas)|*.bas||"),NULL);
        CString strFilePath,strFileName;
		if(fdlg.DoModal()==IDOK)
		{
		   strFilePath = fdlg.GetPathName();
           strFileName = fdlg.GetFileName();
		}
		if(strFileName!="")
		{
		file.Open(strFilePath,CFile::modeReadWrite);
    	char str[PROG_SIZE];
		DWORD m_nLen = file.GetLength();
		file.Read(&str,m_nLen);
		str[m_nLen+1]='\0';
		prog=str;
		scan_labels();	
		do
		{   
			token_type=get_token();
			if(token_type==VARIABLE)
			{
				putback();
				assignment();
		}
				else
		         switch(tok){
		         	case PRINT: print();     break;
					case INPUT: input();     break;
					case IF:    exec_if();   break;
					case ELSE:  exec_else(); break;
					case ENDIF: exec_endif();break;
					case FOR:   exec_for();  break;
			        case NEXT:  next();      break;
					case WHILE: exec_while();break;
					case WEND:  wend();      break;
					case GOTO:  exec_goto(); break;
					case GOSUB:	gosub();	 break;
			        case RETURN:greturn();   break;
					case REM:   rem();       break;
					case DO:    exec_do();   break;
					case LOOP:  exec_loop(); break;
					case EXITDO:exitdo();    break;
					case SELECT:exec_select();break;
					case CASE:  exec_case();  break;
					case ENDSELECT:endselect();break;
					case STOP:  exec_stop();  break;
					case ON:    exec_on();    break;
					case END: ;
				}
		}while(tok!=END);//
//	    return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
		val_Edit2 += "* * * * * * * * * 欢迎使用IMPUBasic语言程序设计器* * * * * * * * * * * * * * * * * * * * * * * * * \r\n";
	    val_Edit2 += val_Edit1;
	}
		else
		{
			val_Edit1= "文件名为空!!!";
		}
	CRunDlg *m_RunDlg;
	m_RunDlg = new CRunDlg(val_Edit1);
	m_RunDlg->Create();
}

void CIMPUBasicView::OnResultView() 
{
	// TODO: Add your command handler code here
	CRunResultDlg *m_RunResultDlg;
	m_RunResultDlg = new CRunResultDlg(val_Edit2);
	m_RunResultDlg->Create();
}

void CIMPUBasicView::OnHelpView() 
{
	// TODO: Add your command handler code here
	CHelpDlg *m_HelpDlg;
	m_HelpDlg = new CHelpDlg;
	m_HelpDlg->Create();
}
void CIMPUBasicView::Error(int error)//错误提示库
{
		CString e[19]={
		"语法错误!",
		"插入不匹配!",
		"表达式不存在!",
		"赋值错误!",
		"变量名不存在!",
		"标号表已满!",
		"标号不匹配!",
		"标号没定义!",
		"不是THEN!",
		"不是TO!",
		"NEXT没有FOR!",
		"RETURN 没有GOSUB!",
		"while缺少wend!",
		"else 没有 if!",
		"endif 没有 if!",
		"if或else没有endif!",
		"do缺少loop!",
		"loop缺少do!",
		"case缺少select!"

	};
		val_Edit1 += e[error];
		val_Edit1 += "\r\n";
    
}
int CIMPUBasicView::isdelim(CString c)//判断字符是否是运算符或数字字符
{
   CString m_str1 = "0123456789+-*%/^(<>,\r=;).Mod";
	int i=m_str1.Find(c);
	if (i>0)
	  return 1;
	    else
		   return 0;
}

int CIMPUBasicView::isdelim1(CString c)//判断字符是否是运算符
{
	CString m_str1 = "=+-*%/^(,\r;)\"Mod";
	int i=m_str1.Find(c);
	if (i>=0)
	  return 1;
      else 
	     return 0;
}

int CIMPUBasicView::iswhite(CString c)//判断字符是否是空格或制表符
{
    if(c==' '||c=='\t')
	   return 1;
	  else 
		return 0;
}

int CIMPUBasicView::look_up(CString str)
{
	CCommands table[31];
		table[0].command="print"; 
		table[0].tok= PRINT;
		table[1].command="input"; 
		table[1].tok= INPUT;
		table[2].command="if"; 
		table[2].tok= IF;
		table[3].command="then"; 
		table[3].tok= THEN;
		table[4].command="goto"; 
		table[4].tok= GOTO;
		table[5].command="for"; 
		table[5].tok= FOR;
		table[6].command="next"; 
		table[6].tok= NEXT;
		table[7].command="to"; 
		table[7].tok= TO;
		table[8].command="gosub"; 
		table[8].tok= GOSUB;
		table[9].command="return"; 
		table[9].tok= RETURN;
		table[10].command="while"; 
		table[10].tok= WHILE;
		table[11].command="wend"; 
		table[11].tok= WEND;
		table[12].command="end"; 
		table[12].tok= END;
		table[13].command="null"; 
		table[13].tok= END;
		table[14].command="endif"; 
		table[14].tok= ENDIF;
		table[15].command="else"; 
		table[15].tok= ELSE;
		table[16].command="rem"; 
		table[16].tok= REM;
		table[17].command="do"; 
		table[17].tok= DO;
		table[18].command="loop"; 
		table[18].tok= LOOP;
		table[19].command="exitdo"; 
		table[19].tok= EXITDO;
        table[20].command="until"; 
		table[20].tok= UNTIL;
		table[21].command="select"; 
		table[21].tok= SELECT;
		table[22].command="case"; 
		table[22].tok= CASE;
		table[23].command="endselect"; 
		table[23].tok= ENDSELECT;
		table[24].command="step"; 
		table[24].tok= STEP;
		table[25].command="is"; 
		table[25].tok= IS;
		table[26].command="stop"; 
		table[26].tok= STOP;
		table[27].command="on"; 
		table[27].tok= ON;
		table[28].command="and"; 
		table[28].tok= AND;
		table[29].command="or"; 
		table[29].tok= OR;
		table[30].command="not"; 
		table[30].tok= NOT;
    int i,j=0;
	str.MakeLower();
	for(i=0;i<31;i++)
	{   
		int n=table[i].command.CompareNoCase(str);
	    if(n==0)
		{
			j=table[i].tok;
		    break;
		}
		else
			j=0;
	}
		return j;
}

int CIMPUBasicView::get_token()//语句分解函数
{  
	char *temp;
    token_type=0;
	tok=0;
	temp=token;
	while(*temp!='\0')//将token[80]清空
	{
		*temp='\0';
		temp++;
	}
	temp=token;
	if(*prog=='\0')//判断文件是否结束,结束将tok赋结束标志
	{
		*token='\0';
		tok=FINISHED;
		token_type=DELIMITER;
		return(token_type);
	}
	while(iswhite(CString(*prog)))//处理空白符
		++prog;
	if(*prog=='\r')//处理回车换行符
	{
		++prog;
		++prog;
		tok=EOL;
		*token='\r';
		token[1]='\n';
		token[2]='\0';
		token_type=DELIMITER;
		return(token_type);
	}
	if(isdelim2(CString(*prog)))//处理算数运算符
	{
		*temp++=*prog++;
		*temp='\0';
		token_type=DELIMITER;
		return(token_type);
	}
	if(isdelim3(CString(*prog)))//处理关系运算符
	{
		while(isdelim3(CString(*prog)))*temp++=*prog++;
		*temp='\0';
		token_type=DELIMITER;
		return(token_type);
	}
	if(*prog=='"')//处理空符
	{
		prog++;
		while(*prog!='"'&&*prog!='\r')
			*temp++=*prog++;
		if(*prog=='\r')
			Error(1);
		prog++;*temp='\0';
		token_type=QUOTE;
        return(token_type);
	}
	if(isdigit(*prog))
	{
		while(!isdelim1(CString(*prog))&&*prog!=' ')
			*temp++=*prog++;
		*temp = '\0';
		token_type=NUMBER;
		return(token_type);
		}
	if (isalpha(*prog))
	{
		while (isalpha(*prog))	
		*temp++=*prog++;
		token_type=STRING;
	}
	*temp='\0';
	if(token_type==STRING){
		tok=look_up(CString(token));
		if(!tok)token_type=VARIABLE;
		else token_type=COMMAND;
	}
	return token_type;

}

int CIMPUBasicView::isdelim2(CString c)//判断字符是否是运算符
{
	CString m_str1 = "+-*%/^(,;)";
	int i=m_str1.Find(c);
	if (i>=0)
	  return 1;
      else 
	     return 0;
}
int CIMPUBasicView::isdelim3(CString c)//判断字符是否是运算符
{
	CString m_str1 = "=><";
	int i=m_str1.Find(c);
	if (i>=0)
	  return 1;
      else 
	     return 0;
}
void CIMPUBasicView::get_exp(int *result)//表达式运算函数
{
	get_token();
	if(!*token)
	{
		Error(2);
		return;
	}
	level2(result);
	putback();
}

void CIMPUBasicView::level2(int *result)//计算+、-
{
    char op;
	int hold;
	level3(result);
	while((op=*token)=='+'||op=='-') 
	{
		get_token();
		level3(&hold);
		arith(op,result,&hold);
	}
}

void CIMPUBasicView::level3(int *result)//计算*、/、%
{
    char op;
	int hold;
	level4(result);
	while((op=*token)=='*'||op=='/'||op=='%')
	{
		get_token();
		level4(&hold);
		arith(op,result,&hold);
	}
}

void CIMPUBasicView::level4(int *result)//计算^
{
	int hold;
	level5(result);
	while(*token=='^'){
		get_token();
		level4(&hold);
		arith('^',result,&hold);
	}

}

void CIMPUBasicView::level5(int *result)//计算自+、-
{
    char op;
	op=0;
	if((token_type==DELIMITER)&&*token=='+'||*token=='-')
	{
		op=*token;
		get_token();
	}
    level6(result);
    if(op) 
		unary(op,result);
}

void CIMPUBasicView::level6(int *result)//计算(
{
  if((*token=='(')&&(token_type==DELIMITER))
  {
		get_token();
		level2(result);
		if(*token!=')')
			Error(1);
		get_token();
	}
	else
		primitive(result);
}

void CIMPUBasicView::primitive(int *result)//处理变量、数字
{
    switch(token_type){
		case VARIABLE:
			*result=find_var(token);
			get_token();
			return;
		case NUMBER:
			*result=atoi(token);
			get_token();
			return;
		default:
		Error(0);
	}
}

void CIMPUBasicView::arith(char o, int *r, int *h)//算术运算
{
    int t,ex;
	switch(o){
		case '-':
			*r=*r-*h;
			break;
		case '+':
			*r=*r+*h;
			break;
		case'*':
			*r=*r**h;
			break;
		case '/':
			*r=(*r)/(*h);
			break;
		case '%':
			t=(*r)/(*h);
			*r=*r-(t*(*h));
			break;
		case '^':
			ex=*r;
			if(*h==0){
				*r=1;
				break;
			}
			for(t=*h-1;t>0;--t)*r=(*r)*ex;
			break;
	}
}

void CIMPUBasicView::unary(char o, int *r)//负号运算
{
	if(o=='-') 
		*r=-(*r);
}

int CIMPUBasicView::find_var(char *s)//返回变量值
{
  if(!isalpha(*s)){
	Error(4);
		return 0;
	}
	return variables[toupper(*token)-'A'];
}

void CIMPUBasicView::putback()//文件指针后退一个单位
{
    char *t;
	t=token;
	for(;*t;t++)prog--;
}

int CIMPUBasicView::assignment()//赋值函数
{
   int var,value;
   get_token();
   if(!isalpha(*token)){
	Error(4);
	return 0;
}
   var=toupper(*token)-'A';
   get_token();
   if(*token!='='){
	Error(3);
	return 0;
   }
   get_exp(&value);
   variables[var]=value;
  return 0;
}
void CIMPUBasicView::print()//关键字print
{
	 char  m_buf[80];
     int answer;
     int len=0;
     char last_delim;

   do{
	  get_token();
	  if(tok==EOL||tok==FINISHED)
		  break;
	  if(token_type==QUOTE)
	  {
		val_Edit1 += CString(token);		
		len++;
		get_token();
	  }
	  else{
		   putback();
		   get_exp(&answer);
		   
		   len++;
           int m=sprintf(m_buf,"%d",answer);
	       val_Edit1 += CString(m_buf);
		   get_token();
	   	}
	last_delim=*token;
	if(*token==';')
	{
		if(len<8)
           val_Edit1 += "\t";
		else
		{
			val_Edit1 += "\r\n";
			len=0;
		}
	}
	else if(*token==',')
			val_Edit1 += " ";
	     else if(tok!=EOL&&tok!=FINISHED&&token_type!=COMMAND) 
		 {
		Error(0);
		 }
  }while(*token==';'||*token==',');
  if(tok==EOL||tok==FINISHED||token_type==COMMAND)
  {
	if(last_delim!=';'&&last_delim!=',')
		val_Edit1 += "\r\n";
  }
  else 
  {
	  Error(0);
  }
  if(token_type==COMMAND)
	  putback();
}


void CIMPUBasicView::exec_if()//关键字if
{
	int x,y,cond=0;
	get_exp(&x);
	get_token();
    CString str1,str2;
	str1=CString(token);
	get_exp(&y);
    cond=get_rel(x,str1,y);
	get_token();
	if(tok!=THEN)
		{
			Error(8);
			return;
		}
	else
	{
	   get_token();
	   if(token_type==COMMAND||token_type==NUMBER||token_type==VARIABLE)
	   {
		   if(!cond)
		   {
		     CString str = "MFALSE";
		     ifpush(str);
	        findeolelse();
		   }
          else
		  {	
		   CString str = "MTRUE";
		   ifpush(str);
		   putback();
		  }
	   }
	  else
	   {
		putback();
	   if(!cond)
	   {
		CString str = "FALSE";
		ifpush(str);
		findendifelse();
		}
       else
	   {	
		  CString str = "TRUE";
		  ifpush(str);
		}
	   }
	   }

}

void CIMPUBasicView::find_eol()//文件指针移向行尾
{
	while(*prog!='\n'&&*prog!='\0')
		++prog;
	if (*prog) 
		prog++;

}

void CIMPUBasicView::exec_for()//关键字for
{
    struct for_stack *i = new for_stack;
	int value;
	get_token();
	if(!isalpha(*token))
	{
		Error(4);
		return;
	}
	i->var=toupper(*token)-'A';
	get_token();
	if(*token!='=')
	{
		Error(3);
		return;
	}
	get_exp(&value);
	variables[i->var]=value;
	get_token();
	if(tok!=TO)
		Error(9);
	get_exp(&i->target);
	get_token();
	if(token_type==COMMAND)
	{
		CString str = "step";
		CString str1 = CString(str);
		int m=str.CompareNoCase(str1);
		if(m==0)
		{
			get_exp(&i->step);
			i->loc=prog;
		}
		else
		{
			putback();
			i->step=1;
			i->loc=prog;
		}
	}
	else
	{
		putback();
		i->step=1;
		i->loc=prog;
	}
		fpush(i);
}

void CIMPUBasicView::next()//关键字next
{
    struct for_stack *i = new for_stack;
	i=fpop();
	variables[i->var]=variables[i->var]+i->step;
	if(variables[i->var]>i->target)
		return;
	fpush(i);
	prog=i->loc;
}

void CIMPUBasicView::fpush(struct for_stack *i)//for入栈
{
	fstack1.AddTail(i);
}

struct for_stack * CIMPUBasicView::fpop()//for弹栈
{
    if(fstack1.IsEmpty())
	{
		Error(10);
		return NULL;
	}
	else
	{
	for_stack *q=(for_stack *)fstack1.RemoveTail();
	return q;
	}
}

void CIMPUBasicView::exec_goto()//关键字goto
{
	int i;
	get_token();
	i=find_label(CString(token));
	if(i<0)
	  Error(7);
      else 
	  prog=label_table[i].p;

}
void CIMPUBasicView::label_init()//标号表初始化
{

⌨️ 快捷键说明

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