Наверх

Пред. След.  

 

 

Транслятор формул (с действительными числами и строками) и новый сканер .

 

Теперь заменим сканер в нашем трансляторе формул. Напомним, что он обрабатывает плюсы-минусы, умножение и деление. Обрабатывает и скобки. Кроме того имеются и унарные плюс и минус (перед данным числом может быть лишь один унарный знак).

От целых чисел перейдем к действительным (разделитель – точка). Кроме того введем обработку строк. В тексте формулы строка заключается в кавычки – тогда транслятор распознает ее именно как строку символов, а не что-то другое. Таким образом в этой реализации транслятора имеются уже различные типы данных, с которыми работает программа. В строку с обратной польской записью данные-строки помещаются с сохраненной лидирующей (передней) кавычкой. Именно по этой кавычке их в дальнейшем и распознает функция PostFix, обрабатывающая ОПЗ (строку с обратной польской записью).

 Сумма строк – это обычная конкатенация (слияние). Дополним алгебру строк такими новыми операциями как вычитание и унарный минус. Вычитание:

“ABC”-“AB”=”C”

“ABC”-“DD”=”ABC”

То-есть если вычитаемое является передним фрагментом, этот фрагмент отбрасывается.

Действие же унарного минуса приводит к «переворачиванию» строки.

-“ABC”=”CBA

При наличии ошибок образуются текстовые файлы, содержащие в названии фрагмент err. В частности, ошибка буде при попытке сложить число и строку.

Если результатом формулы является строка, результат выдается с сохраненной передней кавычкой. При необходимости от этой кавычки можно легко избавиться.

Напомню, что строка здесь может быть длиной максимум 100 знаков. Итак, формула в текстовом файле Pr_str.txt (в том же каталоге, где и исполняемый файл транслятора), а результат – в Result.txt.

 

/****************************/

 

 

    #include <stdio.h>

    #include <stdlib.h>

    #include <ctype.h>

    #include <string.h>

    #include "Str_ex.h"

    #include "QnS.h"

 

 

 

    int I=0;

            int n=5;

 

            char Lex[150];  /* Это для лексем */

 

            char Res[250];  /* Это для результирующей постфиксной

                                                            польской строки */

            char End[3];    /* Это конец строки в текстовом файле */

 

 

    /* Переменные относятся к сканеру */

            char Prog[64000]; /* Это для текста программы */

            char *pProg;      /* Указатель, двигающийся по строке программы */

 

            char LastLex[150];  /* Это для последней лексемы */

            char *pProgLast;    /* Здесь указатель на начало последней

                                полученной лексемы */

            char *pProgLast2;  

 

    /**********************************/

 

            char DelimPol[2];   /* Разделитель в стеке */

            char S1[150];

            char *pRes;

 

            char Sign1[2]={43,0};

            char Sign2[2]={45,0};

            char Sign3[2]={42,0};

            char Sign4[2]={47,0};

 

            char Sign5[3]={43,85,0};

            char Sign6[3]={45,85,0};

 

                        void expr();

 

/**************************************************************/

 

 

 

 

 

 

            /*******************/

 

 

 

/**************************************************************/

/******************************/

/*           sprintf(A,"n=%d",n);*/

/******************************/

int is_Space(int S)  /* Является ли знак пробелом,концом строки,таб-й? */

            {

                        if(S==32||  /* Пробел */

           S==10||  /* Перевод строки */       

           S==13||  /* Возврат каретки */      

           S==9||  /* Табуляция */        

           S==11||  /* Верт.табуляция */   

           S==25)  /* Конец носителя */   

                        {

                                    return 1;

                        }

                        else

                        {

                                    return 0;

                        };

 

            }

 

int is_Alpha(int S)  /* Является ли знак лат.буквой или _ (подчеркиванием)? */

            {

                        if((S>=65&&S<=90)|| 

           (S>=97&&S<=122)||

                           S==95)

                        {

                                    return 1;

                        }

                        else

                        {

                                    return 0;

                        };

 

            }

 

            int isDelim(int S)  /* Является ли знак разделителем, */

            {

                        if(S==43||  /* - */

           S==45||  /* + */ 

           S==42||  /* * */ 

           S==47||  /* / */  

           S==37||  /* % */

           S==61||  /* = */ 

           S==60||  /* < */ 

           S==62||  /* > */ 

           S==59||  /* ; */  

           S==40||  /* ( */  

           S==41||  /* ) */  

           S==33||  /* ! */  

           S==44||  /* , */  

           S==46)   /* . */  

                        {

                                    return 1;

                        }

                        else

                        {

                                    return 0;

                        };

           

           

           

            }

 

 

 

            int isDelim1(int S,int SNext)  /* Является ли знак разделителем, плюс

                        учет того, что если после точки цифра, то точка уже не разделитель

                        (чтобы действительное число с дробной точкой не разбивалось) */

            {

                        if(S==43||  /* - */

           S==45||  /* + */ 

           S==42||  /* * */ 

           S==47||  /* / */  

           S==37||  /* % */

           S==61||  /* = */ 

           S==60||  /* < */ 

           S==62||  /* > */ 

           S==59||  /* ; */  

           S==40||  /* ( */  

           S==41||  /* ) */  

           S==33||  /* ! */  

           S==44||  /* , */  

           S==46)   /* . */  

                        {

                                    if(S=='.')

                                    {

                                                if(isdigit(SNext)!=0)

                                                {

                                                return 0;

                                                }

                                                else

                                                {

                                                            return 1;

                                                };

                                    }

                                    else

                                    {

                                                return 1;

                                    };

                        }

                        else

                        {

                                    return 0;

                        };

            }

 

 

            void ErrorScaner(int N)

            {

                        ;

        if(N==1) WrStr("Result_0.txt",End,"Unknown Sign - 1-st in Lexema! ",1);

        if(N==2) WrStr("Result_0.txt",End,"No 2-nd quota",1);

 

                        return;

            }

 

 

 

            void NextLexema() /* Получает очередную лексему */

            {

              char *pLex=(char *)Lex;

 

 

                        if(*pProg==0) /* Если на входе пустая строка */

                        {

                                    *pLex=0;

                                    return;

                        }

        

                        /* Сохраняем положение указателя на позицию

                        в тексте программы (если вдруг придется

                        возвращаться назад):  */

        pProgLast2=pProgLast;

                        pProgLast=pProg;

 

                        *pLex=0;  /* Для борьбы с "последней лексемой" */

 

                        while(is_Space(*pProg)) ++pProg; /* Убираем лидирующие пробелы */

 

 

                        if(*pProg==47&&*(pProg+1)==42) /* Обработка комментария */

                        {

                                    pProg++;

                                    pProg++;

                                    while(!(*pProg==42&&*(pProg+1)==47))

                                    {

                                                if(*pProg==0) return;

                                                pProg++;

                                    }

                                    pProg++;

                                    pProg++;

 

                                    /*return;*/

                        }

 

                        while(is_Space(*pProg)) ++pProg; /* Убираем  пробелы после комментария */

 

 

                        if(*pProg==45||  /* - */

           *pProg==43||  /* + */ 

           *pProg==42||  /* * */ 

           *pProg==47||  /* / */  

           *pProg==37||  /* % */

           *pProg==61||  /* = */ 

           *pProg==60||  /* < */ 

           *pProg==62||  /* > */ 

           *pProg==59||  /* ; */  

           *pProg==40||  /* ( */  

           *pProg==41||  /* ) */  

           *pProg==33||  /* ! */  

           *pProg==44||  /* , */  

           *pProg==46)   /* . */

                        {  /* Это мы рассматриваем знаки */

/***/   /* Обработка двухсимвольных знаков */

                                    if(*pProg==60&&*(pProg+1)==61)

                                    {

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=0;

                                    return;

                                    }

 

                                    if(*pProg==62&&*(pProg+1)==61)

                                    {

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=0;

                                    return;

                                    }

 

                                    if(*pProg==60&&*(pProg+1)==62)

                                    {

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=0;

                                    return;

                                    }

 

                                    if(*pProg==33&&*(pProg+1)==61)

                                    {

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=0;

                                    return;

                                    }

 

/***/   /* Теперь - односимвольные */

 

                                    *pLex=*pProg;

                                    pProg++;

                                    pLex++;

                                    *pLex=0;

                                    return;

                        }

 

                        if(*pProg==34) /* Обработка выражения в кавычках */

                        {

                                    *pLex=34;

                                    pProg++;

                                    pLex++;

                                    while(*pProg!=34)

                                    {

                                                if(*pProg==0)

                                                {

                                                            ErrorScaner(2);

                                                            return;

                                                }

                                                *pLex++=*pProg++;

                                    }

                                    pProg++;

                                    /* *pLex=34;

                                    pLex++; */

                                    *pLex=0;

                                    return;

                        }

 

 

                        if(isdigit(*pProg)) /* Начинаем рассматривать число */

                        {

                        int k=0;

                        while(k>-1)                            

                        {

                                    if(*pProg==0)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    /*if(*pProg==13)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    if(*pProg==10)

                                    {

                                                *pLex=0;

                                                return;

                                    }*/

                                    if(is_Space(*pProg)==1)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    if(isDelim1(*pProg,*(pProg+1))==1)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    *pLex=*pProg;

                                    pLex++;

                                    pProg++;

                        }

                        }

 

 

                        if(is_Alpha(*pProg)) /* Начинаем рассматривать имя переменной или

                                                                                    ключевое слово языка */

                        {

                        int k=0;

                        while(k>-1)                            

                        {

                                    if(*pProg==0)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    /*if(*pProg==13)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    if(*pProg==10)

                                    {

                                                *pLex=0;

                                                return;

                                    }*/

                                    if(is_Space(*pProg)==1)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    if(isDelim(*pProg)==1)

                                    {

                                                *pLex=0;

                                                return;

                                    }

                                    *pLex=*pProg;

                                    pLex++;

                                    pProg++;

                        }

                        }

 

                        if(!(is_Space(*pProg)!=0||*pProg==0)) ErrorScaner(1);

                        pProg++;

 

                        return;

            }

 

    /*  Конец "сканерной" части   */

 

            void ErrorLex(int N)

            {

        if(N==1)

                        {

                                    WrStr("err_lex.txt",End,"   ",1);

                                    WrStr("err_lex.txt",End,"No Bracket! ",1);

                                    WrStr("err_lex.txt",End,"---",1);

                        };

        if(N==2)

                        {

                                    WrStr("err_lex.txt",End,"   ",1);

                                    WrStr("err_lex.txt",End,"ERROR - 0-lexema, probably phrase is not finished! ",1);

                                    WrStr("err_lex.txt",End,"---",1);

                        };

        if(N==3)

                        {

                                    WrStr("err_lex.txt",End,"   ",1);

                                    WrStr("err_lex.txt",End,"ERROR - Wrong lexema! ",1);

                                    WrStr("err_lex.txt",End,"---",1);

                        };

        if(N==4)

                        {

                                    WrStr("err_lex.txt",End,"   ",1);

                                    WrStr("err_lex.txt",End,"ERROR - Last lexema exists! ",1);

                                    WrStr("err_lex.txt",End,"---",1);

                        };

        if(N==5)

                        {

                                    WrStr("err_lex.txt",End,"   ",1);

                                    WrStr("err_lex.txt",End,"ERROR - Long string! ",1);

                                    WrStr("err_lex.txt",End,"---",1);

                        };                     ;

            }

 

 

 

 

 

            void fact()  /* Это множитель - конечный пункт рекурсии */

            {

            if(*Lex==40)

            {

                        NextLexema();

                        expr();

                        if(*Lex!=41)

                        {

                        *Res=0;

                        /*sprintf(Res,"Lexema: %d ",J-1);

                        StrCat("ERROR - No Bracket !!!  ",Res);*/

                        ErrorLex(1);

                        }

                        else

                        {

                        NextLexema();

                        }

            }

            else

            {

    if(testnum_p(Lex)==0&&(*Lex>47&&*Lex<58))  /* Проверка - является ли действ. числом */

            {

                        StrCat(Lex,Res);

                        StrCat(DelimPol,Res); /* Добавляем разделитель в стеке */

                        NextLexema();

            }

            else

            {

              if(*Lex==34)

              {

        if(lenstr(Lex)<100) 

                        {

                        StrCat(Lex,Res);

                        StrCat(DelimPol,Res);

                        }

                        else

                        {

                        ErrorLex(5);

                        }

                        NextLexema();

              }

              else

              {

                        if(*Lex==0)

                        {

                        *Res=0;

                        /*sprintf(Res,"Lexema: %d ",J-1);

                        StrCat("ERROR - 0-lexema, probably phrase is not finished!  ",Res);*/

                        ErrorLex(2);

                        }

                        else

                        {

                        *Res=0;

                        /*sprintf(Res,"Lexema: %d ",J-1);

                        StrCat("ERROR - Wrong lexema!  ",Res);*/

                        ErrorLex(3);

                        }

              }

            };

            };

            }

 

 

void sfact()  /* Это множитель со знаком (унарным) */

            {

            char Lex1[150];

            Lex1[0]=0;

 

            if(*Lex==43||*Lex==45)

            {

            CpStr(Lex,Lex1);

            NextLexema();

            }

            fact();

            if(*Lex1!=0)

    {

            StrCat(Lex1,Res);

            StrCat("U",Res);

            StrCat(DelimPol,Res);

            }

            }

 

            void term() /* Обработка умножения-деления */

            {

            char Lex1[150];

            Lex1[0]=0;

 

    sfact();

            while(*Lex==42||*Lex==47)

            {

                        CpStr(Lex,Lex1);

                        NextLexema();

                        sfact();

                        StrCat(Lex1,Res);

                        StrCat(DelimPol,Res);

            }

            }

 

 

            void expr()  /* Обработка сложения-вычитания */

            {

            char Lex1[150];

            Lex1[0]=0;

 

            term();

            while(*Lex==43||*Lex==45)

            {

                        CpStr(Lex,Lex1);

                        NextLexema();

                        term();

                        StrCat(Lex1,Res);

                        StrCat(DelimPol,Res);

            }

            }

 

            /********************************/

            /*  Обработка строки с польской обратной записью  */

 

            void ErrorStack(int N)

            {

        if(N==-2)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"Empty Stack! ",1);

                        };

        if(N==-3)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"Stack Error - Adding! ",1);

                        };

        if(N==-4)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"Stack Error - getting (1)! ",1);

 

                        };

        if(N==-5)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"Stack Error - getting (2)!  ",1);

                        };

        if(N==-6)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"Stack Error - Adding!  ",1);

                        };        

        if(N==-7)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"Stack Error - getting in the end!  ",1);

                        };        

                        /* Ощибки с действиями */

        if(N==-8)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"+ No number!  ",1);

                        };                                

        if(N==-9)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"- No number!  ",1);

                        };

        if(N==-10)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"* No number!  ",1);

                        };

        if(N==-11)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"/ No number!  ",1);

                        };                    

        if(N==-12)

                        {

                                    WrStr("err_st.txt",End,"   ",1);

                                    WrStr("err_st.txt",End,"+(unar) No number!  ",1);

                        };

                        return;

            }

 

 

 

            int iPF=1;

 

            int PostFix(char *S,char *Dest)

            {

                        void * pSt;

                        char St[100];

                        int i,res;

                        int iPF1;

                        int iPF2;

                        int iPF3;

                        char *S1;

                        void *pS1;

                        /*char S2[50];

                        char S3[50];

                        char S4[100];*/

 

                        int r=0;

 

                        double F1,F2,F3; /* Для действий с числами */

                        char sF1[100];  /* Для работы со строками */

                        char sF2[100];

                        char sF3[100];

                        char sF2_1[100]; /* Для выч-я строк */

 

                        int l1;

                        int isStr1,isStr2; /* Для контроля типов */

 

                        if(*S==0)

                        {

                        ErrorStack(-2);

                        return -2;

                        }

 

                        sF1[0]=0;

                        sF2[0]=0;

                        sF3[0]=0;

                        int iStrW=0; /* Если 0, результат - число (тоже конт.типов)*/

 

                        pS1=malloc(100);

                        if(pS1==NULL)

                        {

                                    return -1;

                        }

                        S1=(char *)pS1;

                        *S1=0;

 

                        /*WrStr("PostFix.txt",End,"Coming",1);*/

 

                        pSt=CreateStack(10000);

 

                        while(iPF>0)

                        {

                        /*WrStr("PostFix.txt",End,"Cycle",1);*/

 

                        iPF1=CpWordN(S,S1,DelimPol[0],iPF); /* Использ. разд-ль в стеке */

                        if(iPF1<0)

                        {

                        break;

                        }

        iPF++;

 

        if(!(COMPstr(S1,Sign1)==0||COMPstr(S1,Sign2)==0||COMPstr(S1,Sign3)==0||COMPstr(S1,Sign4)==0||

                                    COMPstr(S1,Sign5)==0||COMPstr(S1,Sign6)==0))

                                    /* Если символ не знак, помещаем в стек */

                        {

                                    for(i==0;i<100;i++) *(St+i)=0;

                                    CpStr(S1,St);

                                    res=AddArrayToStackNoPart(pSt,St,100);

                                    if(res!=100)

                                    {

                                    r=-3;

                        ErrorStack(-3);

                                    }

                        }

                        else  /* Если символ - знак */

                        {

        if(COMPstr(S1,Sign1)==0||COMPstr(S1,Sign2)==0||COMPstr(S1,Sign3)==0||COMPstr(S1,Sign4)==0)

                        {

                                    /****/

                                    *sF1=0;

                                    *sF2=0;

                                    *sF3=0;

                                    /****/

                        for(i==0;i<100;i++) *(St+i)=0;

        res=GetArrayFromStack(pSt,St,100);

                        if(res!=100)

                                    {

                                    r=-4;

                                    ErrorStack(-4);

                                    }

                        if(*St!=34)

                        {

                                    F1=atof(St);

                                    isStr1=0; /* Для контроля типов */

                        }

                        else

                        {

                                    CpStr(St+1,sF1);

                                    isStr1=1;  /* Для контроля типов */

 

                        }

 

                        for(i==0;i<100;i++) *(St+i)=0;

        res=GetArrayFromStack(pSt,St,100);

                        if(res!=100)

                                    {

                                    r=-5;

                        ErrorStack(-5);

                                    }

                        if(*St!=34)

                        {

                                    F2=atof(St);

                                    isStr2=0;

 

                        }

                        else

                        {

                                    CpStr(St+1,sF2);

                                    isStr2=1;

                        }

 

 

                        if(COMPstr(S1,Sign1)==0) /* Если сложение */

                        {

                                    if(isStr1==0&&isStr2==0)

                                    {

                                    F3=F2+F1;

                                    iStrW=0;

                                    }

                                    else

                                    {

            if(isStr1==1&&isStr2==1)

                                    {

                                    *sF3=34;

            *(sF3+1)=0;

                                    StrCat(sF2,sF3);

                                    StrCat(sF1,sF3);

                                    iStrW=1;

                                    *sF1==0;

                                    *sF2==0;

                                    }

                                    else

                                    {

                                    *sF1=0;

                                    *sF2=0;

                                    *sF3=0;

                                    r=-8;

                        ErrorStack(-8);

                                    return r;

                                    }

                                    }

                        }

                        if(COMPstr(S1,Sign2)==0) /* Если вычитание */

                        {

                                    if(isStr1==0&&isStr2==0)

                                    {

                                    F3=F2-F1;

                                    iStrW=0;

                                    }

                                    else

                                    {

            if(isStr1==1&&isStr2==1)

                                    {

                                    *sF3=34;

            *(sF3+1)=0;

 

                                    l1=SearchOnFrag(sF2,sF1);

                                    if(l1==0)

                                    {

                                    CpStrNLast(sF2,sF2_1,lenstr(sF1));

                                    StrCat(sF2_1,sF3);

                                    }

                                    else

                                    {

                                    StrCat(sF2,sF3);

                                    }

                                    iStrW=1;

                                    *sF1==0;

                                    *sF2==0;

                                    }

                                    else

                                    {

                                    *sF1=0;

                                    *sF2=0;

                                    *sF3=0;

                                    r=-9;

                        ErrorStack(-9);

                                    return r;

                                    }

                                    }

                        }

                        if(COMPstr(S1,Sign3)==0) /* Если умножение */

                        {

                                    if(isStr1==0&&isStr2==0)

                                    {

                                    F3=F2*F1;

                                    iStrW=0;

                                    }

                                    else

                                    {

                                    *sF1=0;

                                    *sF2=0;

                                    *sF3=0;

                                    r=-10;

                        ErrorStack(-10);

                                    return r;

 

                                    }

                        }

                        if(COMPstr(S1,Sign4)==0) /* Если деление */

                        {

                                    if(isStr1==0&&isStr2==0)

                                    {

                                    F3=F2/F1;

                                    iStrW=0;

                                    }

                                    else

                                    {

                                    *sF1=0;

                                    *sF2=0;

                                    *sF3=0;

                                    r=-11;

                        ErrorStack(-11);

                                    return r;

 

                                    }

                        }

                       

 

        if(iStrW==0)

                        {

                        sprintf(St,"%f",F3);

                        }

                        else

                        {

                                    CpStr(sF3,St);

                                    iStrW=0;

                        }

 

                        /*Кладем результат в стек*/

                        /*            for(i==0;i<100;i++) *(St+i)=0;  */

 

 

                                    res=AddArrayToStackNoPart(pSt,St,100);

                                    if(res!=100)

                                    {

                                    r=-6;

                        ErrorStack(-6);

                                    }

 

                        }

                        if(COMPstr(S1,Sign5)==0||COMPstr(S1,Sign6)==0)

                        {

                        for(i==0;i<100;i++) *(St+i)=0;

        res=GetArrayFromStack(pSt,St,100);

                        if(res!=100)

                                    {

                                    r=-4;

                        ErrorStack(-4);

                                    }

                        /*F1=atof(St);*/

                        if(*St!=34)

                        {

                                    F1=atof(St);

                                    isStr1=0;

                        }

                        else

                        {

                                    CpStr(St+1,sF1);

                                    isStr1=1;

                        }

 

                        if(COMPstr(S1,Sign6)==0) /* Если унарный минус */

                        {

                                    /*F3=-F1;*/

                                    if(isStr1==0)

                                    {

                                    F3=-F1;

                                    iStrW=0;

                                    }

                                    else

                                    {

                                    InversStr(sF1,sF3);

                                    iStrW=1;

                                    *sF1=0;

                                    }

                        }

                        if(COMPstr(S1,Sign5)==0) /* Если унарный плюс */

                        {

                                    /*F3=F1;*/

                                    if(isStr1==0)

                                    {

                                    F3=F1;

                                    iStrW=0;

                                    }

                                    else

                                    {

                                    *sF1==0;

                                    *sF2==0;

                                    *sF3==0;

                                    r=-12;

                        ErrorStack(-12);

                                    return r;

                                    }

                        }

 

                        if(iStrW==0)

                        {

                        sprintf(St,"%f",F3);

                        }

                        else

                        {

                                    *St=34;

                                    *(St+1)=0;

                                    StrCat(sF3,St);

                                    iStrW=0;

                        }

 

                        /*Кладем результат в стек*/

                                    /*for(i==0;i<100;i++) *(St+i)=0;*/

                                    res=AddArrayToStackNoPart(pSt,St,100);

                                    if(res!=100)

                                    {

                                    r=-6;

                        ErrorStack(-6);

                                    }

                        }

                        }

                        }

 

                        /*Извлекаем из стека результат*/

 

                        for(i==0;i<100;i++) *(St+i)=0;

        res=GetArrayFromStack(pSt,St,100);

                        if(res!=100)

                                    {

                                    r=-7;

                        ErrorStack(-7);

                                    }

                        *S1=0;

                        StrCat(St,S1);

                        /*WrStr("PostFix.txt",End,"Result in stack: ",1);

                        WrStr("PostFix.txt",End,S1,1);*/

        /* Конец извлечения результата из стека*/

                        Del0Last(S1);

                        /*if(*S1==34)

                        {

                        CpStr(S1+1,Dest);

                        }

                        else

                        {

                        CpStr(S1,Dest);

                        }  Убираем предшеств. кавычку*/

                        CpStr(S1,Dest);

 

                        DeleteStack(pSt);

        free(pS1);

                        return r;

 

            }

 

/********************************/

 

            /*******************/

 

 

 

    void main(void)

 

    {

                        Lex[0]=0;

 

                        Res[0]=0;

 

                        End[0]=13;

                        End[1]=10;

                        End[2]=0;

                        DelimPol[0]=4; /* Задаем разделитель в стеке */

                        DelimPol[1]=0;

 

                        char dest[200];

/*  Чтение файла с программой   */

/*****/

FILE *f1;

int Ch;

char ch;

int jc,J;

 

pProg=Prog;

 

pProgLast=Prog;

pProgLast2=Prog;

 

f1=fopen("pr_str.txt","rb");

 

if(f1==NULL)

{

    return;

}

 

jc=0;

J=0;

/* Чтение программы из файла в строку */

while(jc>-1)

{

    Ch=fgetc(f1);

    if(Ch==EOF)

    {

        fclose(f1);

        break;

    };

 

    ch=(char)Ch;

            *(pProg+J)=ch;

            J++;

}

 

/*****/

 

 

/*  Конец чтения файла с программой   */

 

 

                        NextLexema();

 

                        expr(); /* Это вход в разбор формулы */

 

      WrStr("Result.txt",End,Res,1); /* Записываем результирующую

                                                                                                 польскую постфиксную строку

                                                                                                             в файл */

              PostFix(Res,dest);

              WrStr("Result.txt",End,"А число:",1);

 

              WrStr("Result.txt",End,dest,1);

 

                        /*Lex[0]=0;

                        NextLexema();*/

                        if(*Lex!=0)  /* Это тоже для борьбы с последней лексемой */

                        {

                WrStr("Result.txt",End,"Last lexema exists!",1);

                WrStr("Result.txt",End,Lex,1);

                        ErrorLex(4);

 

                        }

 

 

              return;

            }

/***********************/

Это проект Gramm3_002.

 

Кстати, при желании обработку данных-строк можно легко отключить.

Вообще нужно заметить, что при написании подобных программ нужно быть очень внимательным. Если следовать распространенным образцам обработки скобок, то можно попасть с такую ситуацию, когда формула

(1+2

распознается как ошибочная (нет завершающей скобки), а формула

1+2)

«проскочит».

Может быть и такой эффект, когда формула

(1+2))+4

даст 3 (то-есть учтет лишь 1+2). Все эти варианты нужно обязательно проверять.

 

Да, чуть не забыл. Здесь все таки имеет смысл опять привести БНФ, ведь добавлена обработка строк (если объект обрамлен кавычками, он распознается как строка).

 

<expr> := <term> {<add_op><term>}

<term> := <signed_factor>{<mul_op><signed_factor>}

<signed_factor> := [<add_op>]<factor>

<factor> := <float>|”<string>”|(<expr>)

 

Есть и комментарии (их сканер просто пропускает). Это как в языке Си –

/* Комментарий */. Комментарии должны находиться между лексемами (в данном случае между плюсом и двойкой)

12+/* Коммент */2

и не должны разбивать лексемы, как в этом случае:

1/* Коммент */2+2

 

 

Хостинг от uCoz