Наверх

Пред. След.  

 

Плюс скобки.

 

Добавим обычные скобки. Форма Бэкуса-Наура такая:

 

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

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

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

<factor> := <integer>|(<expr>)

 

Обратим внимание – скобки «описаны» в конце последней формы БН. Здесь при составлении программы будет дополнительная рекурсия – вызов функции expr.

Вот программа:

 

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

 

 

    #include <stdio.h>

    #include <stdlib.h>

    #include "Str_ex.h"

    #include "QnS.h"

 

 

 

    int I=0;

            int n=5;

 

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

 

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

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

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

 

            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 J=1;

 

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

            {

                        int R;

                        *Lex=0;

                        R=FindStrN("Pr.txt",End,Lex,100,J);

                        J++;

 

                        if(R<0)

                        {

                                    *Lex=0;

            WrStr("Lexema.txt",End," THE END! ",1); /* В тестовых

                                                                                                                                                            целях

                                                                                                               пишем в файл */

                                    return;

                        }

                        else

                        {

        WrStr("Lexema.txt",End,Lex,1); /* В тестовых целях

                                                                                                               пишем в файл */

                        };

            }

 

 

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

            {

            if(*Lex==40)

            {

                        NextLexema();

                        expr();

                        if(*Lex!=41)

                        {

                        *Res=0;

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

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

                        }

                        else

                        {

                        NextLexema();

                        }

            }

            else

            {

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

            {

                        StrCat(Lex,Res);

                        StrCat(" ",Res);

                        NextLexema();

            }

            else

            {

                        if(*Lex==0)

                        {

                        *Res=0;

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

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

                        }

                        else

                        {

                        *Res=0;

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

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

                        }

            };

            };

            }

 

 

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(" ",Res);

            }

            }

 

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

            {

            char Lex1[150];

            Lex1[0]=0;

 

    sfact();

            /*while(COMPstr("*",Lex)==0||COMPstr("/",Lex)==0)*/

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

            {

                        CpStr(Lex,Lex1);

                        NextLexema();

                        sfact();

                        StrCat(Lex1,Res);

                        StrCat(" ",Res);

            }

            }

 

 

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

            {

            char Lex1[150];

            Lex1[0]=0;

 

            term();

            /*while(COMPstr("+",Lex)==0||COMPstr("+",Lex)==0)*/

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

            {

                        CpStr(Lex,Lex1);

                        NextLexema();

                        term();

                        StrCat(Lex1,Res);

                        StrCat(" ",Res);

            }

            }

 

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

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

 

            int iPF=1;

 

            int PostFix(char *S,int L,int N,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;

 

                        if(*S==0)

                        {

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

                        return -2;

                        }

 

                        pS1=malloc(L);

                        if(pS1==NULL)

                        {

                                    return -1;

                        }

                        S1=(char *)pS1;

                        *S1=0;

 

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

 

                        pSt=CreateStack(L*N);

 

                        while(iPF>0)

                        {

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

 

                        iPF1=CpWordN(S,S1,32,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;

                        WrStr("PostFix.txt",End,"Stack error!",1);

                                    }

                        }

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

                        {

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

                        {

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

        res=GetArrayFromStack(pSt,St,100);

                        if(res!=100)

                                    {

                                    r=-4;

                        WrStr("PostFix.txt",End,"Stack error (getting)!",1);

                                    }

                        F1=atol(St);

 

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

        res=GetArrayFromStack(pSt,St,100);

                        if(res!=100)

                                    {

                                    r=-5;

                        WrStr("PostFix.txt",End,"Stack error (getting)!",1);

                                    }

                        F2=atol(St);

 

 

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

                        {

                                    F3=F2+F1;

                        }

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

                        {

                                    F3=F2-F1;

                        }

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

                        {

                                    F3=F2*F1;

                        }

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

                        {

                                    F3=F2/F1;

                        }

                       

 

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

 

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

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

                                    res=AddArrayToStackNoPart(pSt,St,100);

                                    if(res!=100)

                                    {

                                    r=-6;

                        WrStr("PostFix.txt",End,"Stack error!",1);

                                    }

 

                        }

                        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;

                        WrStr("PostFix.txt",End,"Stack error (getting)!",1);

                                    }

                        F1=atol(St);

 

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

                        {

                                    F3=-F1;

                        }

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

                        {

                                    F3=F1;

                        }

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

 

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

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

                                    res=AddArrayToStackNoPart(pSt,St,100);

                                    if(res!=100)

                                    {

                                    r=-6;

                        WrStr("PostFix.txt",End,"Stack error!",1);

                                    }

                        }

                        }

                        }

 

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

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

        res=GetArrayFromStack(pSt,St,100);

                        if(res!=100)

                                    {

                                    r=-7;

                        WrStr("PostFix.txt",End,"Stack error (getting)!",1);

                                    }

                        *S1=0;

                        StrCat(St,S1);

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

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

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

                        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;

                        char dest[200];

 

                        NextLexema();

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

                        if(*Lex!=0)  /* Это если в конце разбора осталась лишняя

                                                             лексема (но не знак) */

                        {

                        *Res=0;

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

                        StrCat("ERROR - More Lexemas! ",Res);

                        }

 

 

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

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

                                                                                                             в файл */

 

              PostFix(Res,100,100,dest);

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

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

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

              sprintf(dest,"Длина посл. лексемы = %d ",lenstr(Lex));

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

 

 

              return;

            }

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

Папка этого проекта – Gramm3.

Хостинг от uCoz