Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Stcalc

.CPP
Скачиваний:
6
Добавлен:
15.06.2014
Размер:
18.91 Кб
Скачать
//-[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"));
}


Соседние файлы в предмете Технология программирования