Наверх

Пред. След.

 

 

Примитивный препроцессор.

 

Попробуем сделать удобную вещь – допустить, что часть программы хранится не в основном файле, а в другом, так называемом «включаемом» файле.

Директиву для включения запрячем внутрь комментария. В первой строке основного файла сразу или после пробелов (Аски-код пробела – 32) должен идти комментарий. Сразу после /* (начало комментария) должен идти знак #. Далее через пробел – INCLUDE. Далее опять через пробел в кавычках – имя включаемого файла. Тогда все это распознается как приказ препроцессору включить перед содержимым основного файла содержимое включаемого.

Таких строк может быть несколько (1-я и 2-я, 1-я,2-я и 3-я и так далее). Но если 2-я строка не удовлетворяет этому критерию, то 3-я уже не распознается как директива (приказ) препроцессору.

Еще одна тонкость – если строк с директивами несколько, то комментарий в конце каждой строки должен заканчиваться (*/), а потом идти пустой оператор (;) . Дело в том, что существующим на данный момент кодом два следующих друг за другом комментария распознаются как ошибочная ситуация. Так что, если мы хотим поставить друг за другом два комментария, их нужно разделить точкой с запятой, даже если они находятся на разных строчках.

Вот пример подключения файлов:

     /*# INCLUDE "C:\TEMP\Grammatics\Pr1.txt"  */   ;

     /*# INCLUDE "C:\TEMP\Grammatics\Pr2.txt"  */

PRINT("Out!!!");

 

START

A=1;

PRINT( A);

IF(1)

/*E=5;*/

PRINT("Inside if");

E=A11(4.5,100,-20);

ENDIF;

PRINT("AFTER");

 

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

Вот исходный код этого простого препроцессора

    /* Зачаточный препроцессор */

            int PrePro(char * fname,char * ProgText,char *End)

            {

                        int j=1;

                        char S0[5000]; /* Для чтения "макровключения" из осн.файла */

                        char S1[500];  /* Для чтения INCLUDE */

                        char S2[4500]; /* Для чтения путей к включаемым файлам */

                        char S[60000]; /* Для чтения файлов */

                        int k=4990;    /* Макс.длина строки с макровключением */

 

          FILE *f1;

          int Ch;

          char ch;

          int jc,J;

 

                        *ProgText=0;

                        *S=0;

 

                        while(j>0)

                        {

        FindStrN(fname,End,S0,k,j);

                        DelSpace(S0,32);

                        if(!(*S0==47&&*(S0+1)==42&&*(S0+2)==35))

                        {

                                    break;

                        }

                        j++;

 

                        CpWordN(S0,S1,32,2);

                        if(COMPstr(S1,"INCLUDE")==0)

                        {

                        CpWordN(S0,S2,34,2);

/****/  /* Чтение включаемого файла */

f1=fopen(S2,"rb");

 

if(f1==NULL)

{

    return 0;

}

 

jc=0;

J=0;

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

while(jc>-1)

{

    Ch=fgetc(f1);

    if(Ch==EOF)

    {

        fclose(f1);

        break;

    };

 

    ch=(char)Ch;

            *(S+J)=ch;

            J++;

}

            *(S+J)=0;

 

/****/

            StrCat(S,ProgText);

            *S=0;

                        }

                        else

                        {

                                    continue;

                        }

 

                        }

/****/  /* Чтение основного файла */

f1=fopen(fname,"rb");

 

if(f1==NULL)

{

    return -1;

}

 

*S=0;

jc=0;

J=0;

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

while(jc>-1)

{

    Ch=fgetc(f1);

    if(Ch==EOF)

    {

        fclose(f1);

        break;

    };

 

    ch=(char)Ch;

            *(S+J)=ch;

            J++;

}

            *(S+J)=0;

 

/****/

            StrCat(S,ProgText);

            return 1;

            }

 

Это – из проекта в папке Gramm95_019.

Последний проект из этой серии – Gramm95_020 (там добавлена проверка на наличие точки с запятой после окончания цикла, функции и условного оператора).

 

Посмотреть исходник.

Хостинг от uCoz