Добавил:
Yanus
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Stcalc
.CPP//-[stdhead]-------------------------------------------------------
//Project:‘⥪®ўл© Є «мЄг«пв®а
//File :numcalc.cpp
//Started:10.01.99 11:25:38
//Updated:11.01.99 15:35:42
//Author :Nick E. Geht (thanx for idea & urgency to my father Eugene N. Geht)
//Subj :ўлзЁб«ҐЁҐ ўла ¦ҐЁ© ¬Ґв®¤®¬ Ї®бв஥Ёп б⥪
//Version:1.0
//Requres:
//=================================================================
//®ЎйҐҐ Їа ўЁ«® а §Ў®а бў®¤Ёвбп Є:
//1 § зҐЁп ўЄ« ¤лў овбп ў б⥪ Ї®б«Ґ¤®ў ⥫м®
//2 ®ЇҐа жЁЁ:
// ЇҐаў п = § Ї®¬Ё Ґвбп
// б«Ґ¤гойЁҐ:
// 1 ЇаЁ а ў®¬ ЇаЁ®аЁвҐвҐ = ЇаҐ¤л¤гй п ®ЇҐа жЁп
// ўЄ« ¤лў Ґвбп ў б⥪ ўла ¦ҐЁп
// ⥪гй п = ў б⥪ ®ЇҐа жЁ©
// 2 ЇаЁ Ў®«м襬 ЇаЁ®аЁвҐвҐ = ⥪гй пп ®ЇҐа жЁп ¤®Ї®«пҐв б⥪ ®ЇҐа жЁ©
// 3 ЇаЁ ¬Ґм襬 ЇаЁ®аЁвҐвҐ = Ё§ б⥪ ®ЇҐа жЁ© гЎЁа овбп ўбҐ ®ЇҐа жЁЁ
// б Ў®«миЁ¬ ЇаЁ®аЁвҐв®¬. (в ЄЁ¬ ®Ўа §®¬
// § ¤ з бў®¤Ёвбп Є ў аЁ вг 1 Ё«Ё 2)
//=================================================================
// ЇаЁ¬Ґа:
//
// 3@4+5*-6
//
// «ҐЄбҐ¬ б⥪ ўла ¦ҐЁп б⥪ ®ЇҐа жЁ©
// 3 3
// @ 3 @
// 4 3 4 @
// + 3 4 @ +
// 5 3 4 @ 5 +
// * 3 4 @ 5 + *
// = 3 4 @ 5 6 + * ~
// 6 3 4 @ 5 6
// <EOL> 3 4 @ 5 6 ~ * +
// а §Ў®а ЇаЁ ўлзЁб«ҐЁЁ б⥪ ўҐ¤Ґвбп б«Ґў Їа ў®
// н«Ґ¬Ґв б⥪ ўла ¦ҐЁп б⥪ § 票©
// 3 3
// 4 4
// @ 81
// 5 81 5
// 6 81 5 6
// ~ 81 5 =6
// * 81 =30
// + 51
//=================================================================
#include <windows.h>
#include <stdio.h>
#include <math.h>
typedef struct { //ќ«Ґ¬Ґв б⥪ ўла ¦ҐЁп
int nType; //’ЁЇ н«Ґ¬Ґв
//==0 value
//==1 unary -
//==2 swap
//==3 +
//==4 -
//==5 *
//==6 /
//==7 @
//==8 =
//==9 (
double value; //¤«п § 票©
}StackItem;
StackItem siStack[256]; //б⥪ ўла ¦ҐЁп
int nStackDeep; //Ј«гЎЁ б⥪ (®¬Ґа ЇҐаў®© бў®Ў®¤®©
//п祩ЄЁ, б⥪ а бвҐв ®в 0 Є 256)
//v ~ s + - * / @ =
int nPriority[]={0,4,0,1,1,2,2,3,-1}; //ЇаЁ®аЁвҐвл
//Ї®«гзЁвм н«Ґ¬Ґв аго з бвм ўла ¦ҐЁп - зЁб«®, ®ЇҐа жЁо Ё«Ё бЄ®ЎЄг («ҐЄбҐ¬г)
int GetLexem( //ў®§ўа й Ґв nType
//Ё«Ё -1 Ґб«Ё ўбҐ
char *pExpr, //ўла ¦ҐЁҐ
int *nOffset, //ᬥ饨Ґ ў ўла ¦ҐЁЁ
char *lexem) //бва®Є®ў®Ґ ЇаҐбв ў«ҐЁҐ «ҐЄбҐ¬л
{
int nPrognose=-1; //Їа®Ј®§
int i,l,goout=0;
i=*nOffset;
while (!goout) //Ї®Є Ґ ¤® бў «Ёў вм
{
switch (pExpr[i]) //祣® в ¬ § бЁ¬ў®«?
{
case 0: //<EOL>
goout=1;
break;
case '0': //жЁдЁам
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (nPrognose==-1)
{
nPrognose=0; //зЁб«®
}
else
{
if (nPrognose!=0) //§ Є ®ЇҐа жЁЁ
{
i--;
goout=1;
}
}
break;
//------®ЇҐа жЁЁ
case '-':
if ((nPrognose!=4)&&(nPrognose!=-1))
{
i--;
goout=1;
}
else
{
nPrognose=4;
goout=1;
}
break;
case '+':
if ((nPrognose!=3)&&(nPrognose!=-1))
{
i--;
goout=1;
}
else
{
nPrognose=3;
goout=1;
}
break;
case '*':
if ((nPrognose!=5)&&(nPrognose!=-1))
{
i--;
goout=1;
}
else
{
nPrognose=5;
goout=1;
}
break;
case '/':
if ((nPrognose!=6)&&(nPrognose!=-1))
{
i--;
goout=1;
}
else
{
nPrognose=6;
goout=1;
}
break;
case '@':
if ((nPrognose!=7)&&(nPrognose!=-1))
{
i--;
goout=1;
}
else
{
nPrognose=7;
goout=1;
}
break;
case '=':
if ((nPrognose!=8)&&(nPrognose!=-1))
{
i--;
goout=1;
}
else
{
nPrognose=8;
goout=1;
}
break;
//----- бЄ®ЎЄЁ
case '(':
if (nPrognose!=-1)
{
i--;
goout=1;
}
else
{
nPrognose=9;
goout=1;
}
break;
case ')':
if (nPrognose!=-1)
{
i--;
goout=1;
}
else
{
nPrognose=-1;
goout=1;
}
break;
default:
goout=1;
break;
}
i++;
}
if (nPrognose!=-1)
{
//бЄ®ЇЁа®ў вм Ї®«гзҐго «ҐЄбҐ¬г
//ў ЎгддҐа
memcpy(lexem,pExpr+*nOffset,i-*nOffset);
lexem[i-*nOffset]=0;
*nOffset=i;
}
return nPrognose;
}
//а §®Ўа вм ўла ¦ҐЁҐ ў б⥪
void ProcessExpr(char *pExpr,int *nLen=NULL);
void ProcessExpr(char *pExpr,int *nLen)
{
char lexem[256];
int nPrognose,nOffset=0,t;
int nPrev=1; //ЇаҐ¤л¤г饥 § 票Ґ
//==0 value
//==1 operation
int nOperStack[256]; //б⥪ ®ЇҐа жЁ©
int nOperSP=0; //б⥪ ®ЇҐа жЁ©
while ((nPrognose=GetLexem(pExpr,&nOffset,lexem))!=-1) //Ї®Є Ґбвм «ҐЄбҐ¬л
{
switch (nPrognose) //зв® § ⥪гй п «ҐЄбҐ¬ ?
{
case 0: //§ 票Ґ
if (nPrev==0)
{
printf ("!!!„ў § 票Ґ Ї®¤ап¤\n");
return;
}
siStack[nStackDeep].nType=0;
siStack[nStackDeep++].value=atof(lexem);
nPrev=0;
break;
case 3: //+
if (nPrev) continue; //г ал© Ї«об
nPrev=1;
break;
case 4: //-
if (nPrev) nPrognose=1; //г ал© ¬Ёгб
nPrev=1;
break;
case 5: // *
case 6: // /
case 7: // @
case 8: // =
if (nPrev)
{
printf ("!!!„ўҐ ®ЇҐа жЁЁ Ї®¤ап¤\n");
return;
}
nPrev=1;
break;
case 9: //®вЄалў ой пп бЄ®ЎЄ
//ўл§®ўҐ¬ ᥡп - ў १г«мв вҐ
//¤® § Єалў о饩 бЄ®ЎЄЁ
//ўла ¦ҐЁҐ Ўг¤Ґв ўл«®¦Ґ®
//ў и б⥪
ProcessExpr(pExpr+nOffset,&t);
nOffset+=t+1;
nPrev=0;
break;
}
//Ґб«Ё ®зҐаҐ¤ п «ҐЄбҐ¬ Ўл« ®ЇҐа жЁҐ©
if (nPrev==1)
{
repeat:
if (!nOperSP) //ЇҐаў п ®ЇҐа жЁп, г Ё § Ї®¬Ёвм ҐҐ
{
nOperStack[nOperSP++]=nPrognose;
}
else
{
//Ё зҐ г б ў®§¬®¦л ваЁ бЁвг жЁЁ
//v1 o1 v2 o2 v3
//
//1 o1==o2 - а ўлҐ ЇаЁ®аЁвҐвл
// ўл«®¦Ёвм o1 Ё§ б⥪ , Ї®«®¦Ёвм o2 ў б⥪
//2 o1<o2 - ЇаЁ®аЁвҐв ЇаҐ¤л¤г饩 ®ЇҐа жЁЁ Ё¦Ґ
// Є Ї«Ёў вм ў б⥪
//3 o1>o2 - ЇаЁ®аЁвҐв ЇаҐ¤л¤г饩 ®ЇҐа жЁЁ ўлиҐ
// ўлв®«Єгвм Ё§ б⥪ ўбҐ ®ЇҐа жЁЁ
// б Ў®«ҐҐ ўлб®ЄЁ¬ ЇаЁ®аЁвҐв®¬
// ¤ «ҐҐ Ї® ў аЁ вг 1 Ё«Ё 2 (¬ҐвЄ repeat:)
if (nPriority[nOperStack[nOperSP-1]]==
nPriority[nPrognose])
{
//ў аЁ в 1
siStack[nStackDeep++].nType=nOperStack[nOperSP-1];
nOperStack[nOperSP-1]=nPrognose;
}
else
if (nPriority[nOperStack[nOperSP-1]]<
nPriority[nPrognose])
{
//ў аЁ в 2
nOperStack[nOperSP++]=nPrognose;
}
else
if (nPriority[nOperStack[nOperSP-1]]>
nPriority[nPrognose])
{
//ў аЁ в 3
while ((nOperSP)&&
(nPriority[nOperStack[nOperSP-1]]>
nPriority[nPrognose]))
{
siStack[nStackDeep++].nType=nOperStack[--nOperSP];
}
goto repeat;
}
}
}
}
//ўлв®«Єгвм ®бв ўиЁҐбп ®ЇҐа жЁЁ Ё§ б⥪ ®ЇҐа жЁ©
while (nOperSP)
{
siStack[nStackDeep++].nType=nOperStack[--nOperSP];
}
if (nLen) *nLen=nOffset;
}
// ЇҐз в вм ўла ¦ҐЁҐ ў ®Ўа в®© Ї®«мбЄ®© § ЇЁбЁ
void DumpExpr()
{
int i;
for (i=0;i<nStackDeep;i++)
{
switch (siStack[i].nType)
{
case 0:
printf ("%.0f ",siStack[i].value);
break;
case 1:
printf ("~ ");
break;
case 2:
printf ("? ");
break;
case 3:
printf ("+ ");
break;
case 4:
printf ("- ");
break;
case 5:
printf ("* ");
break;
case 6:
printf ("/ ");
break;
case 7:
printf ("@ ");
break;
case 8:
printf ("= ");
break;
}
}
return;
}
//ўлзЁб«Ёвм ўла ¦ҐЁҐ
void CalcExpr(int fPrint)
{
double nDataStack[256]; //б⥪ Ј®в®ўле § 票©
int nStackP=0; //гЄ § ⥫м б⥪
int i; //
for (i=0;i<nStackDeep;i++) // з вм а §ЎЁа вм б⥪
//ўла ¦ҐЁп
{
if (siStack[i].nType==0)
{
//§ 票Ґ - ўв®«Єгвм ў б⥪ ўла ¦ҐЁп
nDataStack[nStackP++]=siStack[i].value;
}
else
{
//Ё зҐ - ўлЇ®«Ёвм ®ЇҐа жЁо
switch (siStack[i].nType)
{
case 1: //unary -
nDataStack[nStackP-1]=-nDataStack[nStackP-1];
break;
case 3: //+
nDataStack[nStackP-2]+=nDataStack[nStackP-1];
nStackP--;
break;
case 4: //-
nDataStack[nStackP-2]-=nDataStack[nStackP-1];
nStackP--;
break;
case 5: //*
nDataStack[nStackP-2]*=nDataStack[nStackP-1];
nStackP--;
break;
case 6: //div
nDataStack[nStackP-2]/=nDataStack[nStackP-1];
nStackP--;
break;
case 7: //@
nDataStack[nStackP-2]=pow(nDataStack[nStackP-2],nDataStack[nStackP-1]);
nStackP--;
break;
case 8: //let
nDataStack[nStackP-2]=nDataStack[nStackP-1];
nStackP--;
break;
}
}
}
if (fPrint)
{
if (nStackP==1)
{
//Ї® Є®жг а Ў®вл б⥪ § 票©
//¤®«¦Ґ ᮤҐа¦ вм в®«мЄ® ®¤г ®ЇҐа жЁо
printf (">>> %.5f\n",nDataStack[0]);
}
else
{
printf ("Stack pointer %i???\n",nStackP);
}
}
}
void main(int argc, char *argv[])
{
int i,j;
int ftick=0;
DWORD dwTick;
for (i=1;i<argc;i++)
{
if (!strcmp(argv[i],"/tick"))
{
ftick=1;
}
else
{
//Ї® Є ¦¤®¬г ўла ¦ҐЁо ў Є®¬¬ ¤®© бва®ЄҐ
nStackDeep=0; //бЎа®бЁвм б⥪
ProcessExpr(argv[i]); //§ Ї®«Ёвм б⥪ ўла ¦ҐЁп
DumpExpr(); // ЇҐз в вм
CalcExpr(1); //ўлзЁб«Ёвм
if (ftick)
{
dwTick=GetTickCount();
for (j=0;j<50000;j++)
{
CalcExpr(0);
}
printf ("establish time:%.2f",((double)GetTickCount()-dwTick)/1000);
}
}
}
printf ("%f",atof("1.5e10"));
}