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

📄 一个表达式求值程序.txt

📁 一个表达式求值程序 ACM常用
💻 TXT
📖 第 1 页 / 共 2 页
字号:
//This is a version in BC31.
//and can be easily ported to VC.
//and make a dll that can be used by Delphi 
/*
  this program can caculate expresions.
  E => E+T|E-T
  T => T*F|T/F
  F => F^M
  M => (E)|Func(E)|Number
  1.main algorithm uses 递归;
  2.uses command lines(help for more info)
  3.include a demo(esc to cancel)
  4.cannot compile in tiny mode
  5.last edited at 12.1

  mail address: szhao@mail.ustc.edu.cn
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <string.h>
#include <conio.h>
#include <stdarg.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <dir.h>

//#define SOUND
#define TIMER
#define  PI	3.14159265358979324
extern unsigned _stklen=50000;
#define DOUBLE long double
//#ifdef    SOUND
#define		GETVALUE	0
#define		PUTVALUE	1

#define  ERRORBEEP(HZ,TIME) {	sound(HZ); \
			delay(TIME); \
			nosound();  \
		   }

//#endif


#define IDK_ESC    0x011b
#define IDK_ENTER    0x1c0d
#define IDK_BKSPACE  0x0e08
#define IDK_TAB      0x0f09
#define IDK_INSERT   0x5200
#define IDK_DEL      0x5300
#define IDK_HOME     0x4700
#define IDK_END      0x4f00
#define IDK_SPACE    0x3920
#define IDK_F1       0x3b00
#define IDK_UP       0x4800
#define IDK_DOWN     0x5000
#define IDK_LEFT     0x4b00
#define IDK_RIGHT    0x4d00
#define POS(m)	     (long)(char far *)m-(long)(char far *)strbuf

#define LOBYTE(m)	(m&0x00FF)
#define HIBYTE(m)	(m&0xFF00)

#define BKGNDCOLOR		0	//BLACK
#define NORMALCOLOR		(BKGNDCOLOR<<4)+5	//yellow
#define RESULTCOLOR		(BKGNDCOLOR<<4)+14	//yellow
#define VARCOLOR                (BKGNDCOLOR<<4)+9
#define NUMBERCOLOR		(BKGNDCOLOR<<4)+11
#define CMDCOLOR              (BKGNDCOLOR<<4)+GREEN
#define HISCOLOR              (BKGNDCOLOR<<4)+CYAN
#define RESERVEWORDCOLOR 	(BKGNDCOLOR<<4)+15	//include optr
#define ALERTCOLOR		(BKGNDCOLOR<<4)+RED
#define ALERTCOLOR1     	(MESSAGEBARBKCOLOR<<4)+RED
#define MESSAGEBARBKCOLOR	7
#define MESSAGEERROR		4
#define TIMECOLOR		((MESSAGEBARBKCOLOR<<4)+9)
#define MESSAGEHELP		0
#define ATTR2			((MESSAGEBARBKCOLOR<<4)+MESSAGEHELP)
#define ATTR			NORMALCOLOR

/////oprator ids
#define ID_OP_ADD	0
#define ID_OP_SUB	1
#define ID_OP_DIV	2
#define ID_OP_MUL	3


#define MAXVAR		100
#define MAXSTEP		100
#define MAXTOKENLEN     100


typedef	unsigned int	WORD;


#define FUNCNUM   15
char *funcname[]={
	"sin",
	"cos",
	"tg",
	"ctg",
	"atg",
	"actg",
	"asin",
	"acos",
	"sqrt",
	"sqr",
	"fact",
	"log",
	"ln",
	"abs",
	"int"
};


#define ERRNUM  11

enum	ERRORCODE
{
	ERR_ALLOCATEMEMORY,
	ERR_BADPOINTER,
	ERR_ILLEAGLEOP,
	ERR_VARNOTDEFINED,
	ERR_UNDEFINED,
	ERR_UNEXPECTEDTOKEN,
	ERR_UNEXPECTEDEND,
	ERR_UNMATCHKH,
	ERR_ILLEAGLENUMBER,
	ERR_OVERFLOW,
	ERR_TOOLONGTOKEN,
	ERR_COMMADLINE,
	ERR_FILEOPENERROR,
	ERR_PARAERROR,
	ERR_NOERROR
};

char *errmsg[]=
{
	"Error:cannot allocate memory! At file %s line %d ",
	"Error:pointer is bad! At file %s line %d",
	"Error:illeagle operator! At file %s line %d",
	"Error:bad variable or  command! At file %s line %d",
	"Error:undefined error! At file %s line %d",
	"Error:meet unexpected token! At file %s line %d",
	"Error:unexpected end! At file %s line %d",
	"Error:unmatch kuo hao! At file %s line %d",
	"Error:illeagle number! At file %s line %d",
	"Error:over flow ! At file %s line %d",
	"Error:the token name too long, less than 11! At file %s line %d",
	"Error:command para error! At file %s line %d",
	"Error:open file error!At file %s line %d",
	"Error:para error!check you paras,At file %s line %d"
};


struct	ERROR
{
	ERRORCODE	err;
	WORD		pos;//hold pointer in the str
	WORD		line;
	char            mod[100];
};


enum	BOOL
{
	FALSE,
	TRUE
};

struct	POINT
{
	WORD	x;
	WORD	y;
};



enum	TOKENTYPE
{
	ID_VAR,
	ID_FUNC,
	ID_NUMBER,
	ID_OPTR,
	ID_DELIMITER,
	ID_COMMAND,
	ID_UNKNOWN,
	ID_NONE
};

struct TOKEN
{
	TOKENTYPE type;
	char      name[MAXTOKENLEN];
	int	  index;
	int 	  pos;
};

#define MAXHISTORY  10
struct STRLIST
{
	char *str;
	STRLIST *next;
};

#define MAXVARS  100
#define MAXVARLEN  10
struct VARLIST
{
	char	*name;
	DOUBLE  value;
	VARLIST	*next;

};

static STRLIST header={NULL,NULL};
static VARLIST vhead={NULL,0,NULL};


char	promptmsg[10]="Math$";
char	*defaultmsg="Please input command.Use help to get help.";
char	*demostring="In demo mode.Esc To Cancel";

struct COMMAND
{
  char *cmd;
  BOOL (*proc)();
};


void 	showmsg2(int attr,const char *__format, ...);
void 	showmsg(int attr,const char *__format, ...);
void	savecursor(POINT *p);
void	restorecursor(POINT *p);
void	clearwindow();
void	clearwindow2();
void	seterror(ERRORCODE e,WORD pos,WORD line,char *s);
void	handleerror();
BOOL	getstring();
BOOL	getdemostring();


BOOL	init();
BOOL	quit();
BOOL	getnexttoken();
BOOL	commandproc();
BOOL	evalexp();
BOOL	evalexp0(DOUBLE *answer);
BOOL	evalexp1(DOUBLE *answer);
BOOL	evalexp2(DOUBLE *answer);
BOOL	evalexp3(DOUBLE *answer);
BOOL	setvarvalue(char *nid,DOUBLE value);
BOOL	showvarvalue(char *nid);
BOOL	evalexp5(DOUBLE *answer);
BOOL	evalexp4(DOUBLE *answer);
BOOL  atom(DOUBLE *answer);
BOOL	func(DOUBLE *answer,int index);
BOOL	exec(char *str);

BOOL	findandinsert(char *s);

int 	getlistcount();
char  *gethisstr(int i);

BOOL findvar(char *name,int flag=GETVALUE,DOUBLE *value=NULL);
BOOL newvar(char *name,DOUBLE value=0);
BOOL delvar(char *name);


BOOL  showstrlist();
BOOL  flush();
BOOL  close();
BOOL  help();
BOOL  version();
BOOL  prompt();
BOOL  cls();
BOOL  funclist();
BOOL  sound();
BOOL listvars();
BOOL  delvars();
BOOL  load();
BOOL  dir();
BOOL  cd();
BOOL  demo();

BOOL installtimer();
BOOL uninstalltimer();

#define CMDNUM	16
COMMAND cmdtab[]=
{
	{"quit",close},
	{"close",close},
	{"ver",version},
	{"help",help},
	{"cls",cls},
	{"prompt",prompt},
	{"list",showstrlist},
	{"flush",flush},
	{"funclist",funclist},
	{"sound",sound},
	{"lv",listvars},
	{"del",delvars},
	{"load",load},
	{"cd",cd},
	{"dir",dir},
        {"demo",demo}
};


BOOL	soundon=TRUE;
ERROR	error;
WORD	strbuflen;
char	*strbuf;
char	*pchar;
POINT	cursorpos1,cursorpos2;
static int 	mexit=0;
TOKEN   r,r1;
int	status=0;
int   hispos=0;
int   ccc;
int   demomode = 1;
BOOL  ifshow;
BOOL	main()
{
	if (!init())handleerror();
	while (!mexit)
	{

		if (demomode ?getdemostring():getstring())
		{
			ccc=0;
			pchar=strbuf;
			while (*pchar)
			{
				if (*pchar=='(') ccc++;
				else if (*pchar==')')ccc--;
				pchar++;
			}
			seterror(ERR_NOERROR,0,__LINE__,__FILE__);
			if (!evalexp())
			{
				showmsg2(ALERTCOLOR1,errmsg[error.err],error.mod,error.line);
				if (ccc!=0)showmsg(ATTR,"LC-RC=%d \n\r",ccc);
				status=error.err+100;
			}
			else
				showmsg2(ATTR2,demomode?demostring:defaultmsg);

		}
//		if ((strlen(strbuf)<79-strlen(promptmsg)) && (strlen(strbuf)>0))
		if (strlen(strbuf))
			if(strcmp(strbuf,"flush"))
					findandinsert(strbuf);
		memset(strbuf,0,strbuflen);
		showmsg(ATTR,"\n\r%s",promptmsg);
	}
	if (quit())
		return TRUE;
	return FALSE;
}

BOOL	init()
{
#ifdef  TIMER
	installtimer();
#endif
	clearwindow();
	clearwindow2();
	strbuflen=2000;
	strbuf=new char[strbuflen+1];
	if (!strbuf)
	{
		seterror(ERR_ALLOCATEMEMORY,0,__LINE__,__FILE__);
		return	FALSE;
	}

	memset(strbuf,0,strbuflen);
	ifshow = FALSE;
	exec("pi=3.1415926");
	exec("e = 1");
	exec("n = 1");

	ifshow = TRUE;
	showmsg2(ATTR2,defaultmsg);
	version();
	showmsg(ATTR, "\n\rEnter Into Demo Mode\n\r");
	showmsg(ATTR, "\n\r");
	showmsg(ATTR,promptmsg);
	return	TRUE;
};


BOOL	close()
{
	mexit=1;
	return TRUE;
}
BOOL	quit()
{
	if (strbuf)
		delete strbuf;
	flush();
#ifdef  TIMER
	uninstalltimer();
#endif

	asm{
		mov ax,0x0003
		int 0x10
	}
	return	TRUE;
}

BOOL	getstring()
{
	int e=0;
	int key;
	int hispos=getlistcount();
	int nCount=0,mCount=0;
	if (!strbuf)
	{
		seterror(ERR_BADPOINTER,0,__LINE__,__FILE__);
		return FALSE;
	}
	while (!e)
	{
		if (bioskey(1))
		{
			key=bioskey(0);
			if (status!=99)
			{
				status=99;
				showmsg2(ATTR2,defaultmsg);
			}
		}
		else
			continue;
		switch (key)
		{
		case    IDK_ESC:
			{
				if (nCount>79-strlen(promptmsg))
					break;
				if (mCount<nCount)
					mCount=nCount;
				nCount=0;
				gotoxy(strlen(promptmsg)+1,wherey());
				textattr(ATTR);
				clreol();
				break;
			}
		case	IDK_ENTER:
			e=1;
			break;
		case	IDK_TAB:
			break;
		case    IDK_HOME:
			break;
		case    IDK_END:
			break;
		case	IDK_DEL:
		case    IDK_BKSPACE:
		case    IDK_LEFT:
			if (nCount>mCount)
				mCount=nCount;
			if (nCount>0 && wherex()>0)
			{
				nCount--;
				showmsg(ATTR,"\b \b");
			}

			break;
		case    IDK_RIGHT:
			{
				if (nCount<mCount)
				{
					nCount++;
					char c=strbuf[nCount];
					strbuf[nCount]=0;
					showmsg(ATTR,&strbuf[nCount-1]);
					strbuf[nCount]=c;

				}
			}
			break;
		case    IDK_UP:
			if (getlistcount()<1)
				break;
			if (nCount>79-strlen(promptmsg))
				break;
			hispos++;
			if (hispos>getlistcount()) hispos=1;
			strcpy(strbuf,gethisstr(hispos));
			nCount=strlen(strbuf);
			mCount=0;
			gotoxy(strlen(promptmsg)+1,wherey());
			textattr(ATTR);
			clreol();
			gotoxy(strlen(promptmsg)+1,wherey());
			showmsg(ATTR,"%s",strbuf);
			break;
		case    IDK_DOWN:
			if (getlistcount()<1)
				break;
			if (nCount>79-strlen(promptmsg))
				break;
			hispos--;
			if (hispos<1) hispos=getlistcount();
			strcpy(strbuf,gethisstr(hispos));
			nCount=strlen(strbuf);
			mCount=0;
			gotoxy(strlen(promptmsg)+1,wherey());
			textattr(ATTR);
			clreol();
			gotoxy(strlen(promptmsg)+1,wherey());
			showmsg(ATTR,"%s",strbuf);
			break;

			break;
		default:
			//	showmsg(ATTR,"%4x\n\r",key);
			//	showmsg(ATTR,promptmsg);
			if (LOBYTE(key) && !(*((int far *)MK_FP(0,0x0417)) & 4))
			{
				if (nCount<strbuflen)
				{
					strbuf[nCount]=LOBYTE(key);
					nCount++;
					char c=strbuf[nCount];
					strbuf[nCount]=0;
					showmsg(ATTR,&strbuf[nCount-1]);
					strbuf[nCount]=c;
				}
			}
			break;
		}

	}

	if (nCount==0)
		return FALSE;
	strbuf[nCount]=0;
	return TRUE;
}

void	handleerror()
{
	for (int i=0;i<error.pos;i++)
	{
		showmsg(ATTR,"%c",strbuf[i]);
	}
	showmsg(ALERTCOLOR,"%s\n\r",&strbuf[i]);
	showmsg(ALERTCOLOR,"syntax error found!\n\r");
}

void	seterror(ERRORCODE e,WORD pos,WORD line,char *s)
{
//#ifdef SOUND
	if (soundon)
		ERRORBEEP(500,100);
//#endif
	error.err=e;
	error.pos=pos;
	error.line=line;
      strcpy(error.mod,s);
}
void	savecursor(POINT *p)
{
	p->x=wherex();
	p->y=wherey();

}

void	restorecursor(POINT *p)
{
	gotoxy(p->x,p->y);
}

void showmsg(int attr,const char *__format, ...)
{
	char *string=(char *)new char[2000];
	va_list argptr;
	va_start(argptr,__format);
	vsprintf(string,__format,argptr);
	va_end(argptr);
	textattr(attr);
	if (ifshow)
	cprintf("%s",string);
	delete string;
}


void showmsg2(int attr,const char *__format, ...)
{
	char *string=(char *)new char[2000];
	va_list argptr;
	va_start(argptr,__format);
	vsprintf(string,__format,argptr);
	va_end(argptr);
	savecursor(&cursorpos1);
	window(1,25,80,25);
//	restorecursor(&cursorpos2);
	textattr(attr);
	clrscr();
	cprintf("%s",string);
	window(1,1,80,24);
	restorecursor(&cursorpos1);
	delete string;
}


void	clearwindow()
{
	textbackground(BKGNDCOLOR);
	window(1,1,80,24);
	clrscr();
}

void	clearwindow2()
{
	window(1,25,80,25);
	textbackground(MESSAGEBARBKCOLOR);
	clrscr();
}

BOOL	commandproc()
{

	return TRUE;
}

BOOL	evalexp()
{
	DOUBLE result;
	int i;
	pchar=strbuf;
	getnexttoken();
	switch (r.type)
	{
	case ID_COMMAND:
		if (!(*cmdtab[r.index].proc)())
		{
		     showmsg(ALERTCOLOR,"command failed\n\r");
		     return FALSE;
		}
		break;
	case ID_VAR:
		TOKEN r2;
		getnexttoken();
		if ( r.name[0]=='=')
		{

			memcpy(&r2,&r1,sizeof(TOKEN));
			getnexttoken();
			if (!evalexp0(&result))return FALSE;
			if (!setvarvalue(r2.name,result))return FALSE;
		}
		else
			goto   doexp;
		break;
	default:
doexp:
		pchar=strbuf;
		memset(&r,0,sizeof(r));
		memset(&r1,0,sizeof(r));
		getnexttoken();
		if (!evalexp0(&result)) return FALSE;
		break;

	}
	return TRUE;
}

BOOL	setvarvalue(char *nid,DOUBLE value)
{
	if (!findvar(nid,PUTVALUE,&value))
		if (!newvar(nid,value))return FALSE;
	return TRUE;

} 

BOOL	showvarvalue(char *nid)
{
	return TRUE;
}

BOOL    evalexp0(DOUBLE *answer)
{
		showmsg(ATTR,"\n\ryou input:");
		if (evalexp1(answer))
		{
			if (r.type!=ID_NONE)
			{
				seterror(ERR_UNEXPECTEDEND,r.pos,__LINE__,__FILE__);
				handleerror();
				return FALSE;
			}
			showmsg(ATTR,"%s\n\r",strbuf);
			if (error.err == ERR_NOERROR)
			{
				showmsg(ATTR,"the result:");
				showmsg(RESULTCOLOR,"%.19LG\n\r",*answer);
			}
			return TRUE;
		}
		else
		{
			handleerror();
			return FALSE;
		}

}


BOOL 	evalexp1(DOUBLE *answer)
{
	char op=0;
	DOUBLE temp;

	if ((r.type==ID_DELIMITER) && (r.name[0]=='+'|| r.name[0]=='-'))
	{
/*		if (r1.name[0]!='(' && r1.pos!=0)
		{
			seterror(ERR_UNEXPECTEDTOKEN,r.pos,__LINE__,__FILE__);
			return FALSE;
		}*/

		op=r.name[0];
		getnexttoken();
	}
	if (!evalexp2(answer))
		return FALSE;
	if (op=='-') *answer=-*answer;
	while ((op=r.name[0])=='+' || op=='-') 
	{
		getnexttoken();
		if (!evalexp2(&temp))
			return FALSE;

		switch (op)
		{
		case '-':
			*answer=*answer-temp;
			break;
		case '+':
			*answer=*answer+temp;
			break;
		}

	}
	/*
	if (r1.name[0]!=')' && r1.type!=ID_NUMBER && r1.type!=ID_VAR)
	{
		seterror(ERR_UNEXPECTEDTOKEN,r.pos,__LINE__,__FILE__);
		return FALSE;
	} */
	return TRUE;

}

BOOL 	evalexp2(DOUBLE *answer)
{
	char op=0;
	DOUBLE temp;
	if (!evalexp3(answer))
		return FALSE;
	while ((op=r.name[0])=='*' || op=='/' || op=='%')
	{
		getnexttoken();
		if (!evalexp3(&temp))
			return FALSE;
		switch (op)
		{
		case '*':
			*answer=*answer*temp;
			break;
		case  '/':
			if (temp == 0)
			{
				seterror(ERR_OVERFLOW,r.pos,__LINE__,__FILE__);
				return FALSE;
			}

			*answer=*answer/temp;
			break;
		case '%':
			*answer=(long)*answer%(long)temp;
			break;
		default:
			seterror(ERR_ILLEAGLEOP,r.pos,__LINE__,__FILE__);
			return FALSE;
		}

	}
	return TRUE;
}


BOOL 	evalexp3(DOUBLE *answer)
{
	DOUBLE temp,ex;
	if (!evalexp5(answer))
		return FALSE;
	if ((r.name[0])=='^')
	{
		getnexttoken();
		if (!evalexp3(&temp))
			return FALSE;
		if (*answer>0)
		{
			*answer=exp(log(*answer)*temp);
			return TRUE;
		}
		seterror(ERR_ILLEAGLENUMBER,r.pos,__LINE__,__FILE__);

		return FALSE;
		//seterror

	}
	return TRUE;
}

BOOL	evalexp4(DOUBLE *answer)
{
	char op=0;
	if ((r.type==ID_DELIMITER) && (r.name[0]=='+'|| r.name[0]=='-'))
	{
/*		if (r1.name[0]!='(' && r1.pos!=0)
		{
			seterror(ERR_UNEXPECTEDTOKEN,r.pos,__LINE__,__FILE__);
			return FALSE;
		}*/

		op=r.name[0];
//		getnexttoken();
	}
	if (!evalexp5(answer))
		return FALSE;
//	if (op=='-')*answer=-*answer;
//	return TRUE;
}

BOOL	evalexp5(DOUBLE *answer)
{
	int index;
	if (r.type ==ID_FUNC)
	{
		index=r.index;
		getnexttoken();

⌨️ 快捷键说明

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