Разработка синтаксического распознавателя вычисляемого оператора перехода языка FORTRAN

Министерство науки, высшей школы и технической политики Российской Федера­ции.

Новосибирский Государственный

Техниче­ский Университет.

Курсовая работа по системному программированию.

Разработка синтаксического распознавателя вычисляемого оператора перехода языка FORTRAN.

Факультет: АВТ.

Кафедра: АСУ.

Группа: А-513.

Студент: Борзов Андрей Николаевич.

Преподаватель: Шорников Юрий Владимирович.

Ассистент: Панова Вера Борисовна.

Дата: 19 мая 1997 года.

Отметка о защите: _______________________________

Новосибирск – 1997.

Язык оператора.

Язык вычисляемого оператора перехода языка FORTRAN.

GOTO МЕТКА½КОНСТАНТА½АРИФМЕТИЧЕСКОЕ ВЫРАЖЕНИЕ

МЕТКА           – Идентификатор

КОНСТАНТА – ЦЕЛОЕ БЕЗ ЗНАКА

АРИФМЕТИЧЕСКОЕ ВЫРАЖЕНИЕ – ВЫРАЖЕНИЕ, СОДЕРЖАЩЕЕ В СЕБЕ ОПЕРАЦИИ *, /, -, +, **, А ТАКЖЕ ( ).

** – ВОЗВЕДЕНИЕ В СТЕПЕНЬ.

Грамматика языка.

G[<ОПЕРАТОР>]:

1.<ОПЕРАТОР> ® GOTO <ВЫРАЖЕНИЕ>

2.<ВЫРАЖЕНИЕ> ® Т ç<ВЫРАЖЕНИЕ>+Т ç <ВЫРАЖЕНИЕ>-Т

3.Т ® О çТ*О ç Т/О êТ**О

4.О ®(<ВЫРАЖЕНИЕ>) ç<ИДЕНТИФИКАТОР> ç<ДБЗ>

5.<ИДЕНТИФИКАТОР> ® Б{Б çЦ}[L]

6.<ДБЗ> ® Ц{Ц}[.Ц{Ц}][L]

Т

ТЕРМ

О

ОПЕРАНД

Б

БУКВА

Ц

ЦИФРА

ДБЗ

ДРОБНОЕ БЕЗ ЗНАКА

L

КОНЕЦ СТРОКИ (пусто)

**

ВОЗВЕДЕНИЕ В СТЕПЕНЬ

Классификация грамматики.

Данная грамматика G[<ОПЕРАТОР>], согласно классификации Хомского, является контекстно-свободной, так как правая часть каждой редукции начинается либо с терминального символа, либо с нетерминального, принадлежащего объединённому словарю.

A ® a, AÎVn, aÎV*.

Грамматика G[<ОПЕРАТОР>] не является автоматной, так как не все её редукции начинаются с терминального символа. По этой же причине данная грамматика не является S - грамматикой.

Метод анализа.

Для данной грамматики реализован разбор методом рекурсивного спуска, поскольку она относится к классу контекстно-свободных.

        Идея метода состоит в том, что каждому нетерминальному символу ставится в соответствие определённая программная единица (функция), которая распознаёт цепочку, порождаемую этим нетерминалом.

        Эти процедуры и функции вызываются в соответствии с правилами грамматики и иногда вызывают сами себя.

        Данный метод реализован на языке C++, поскольку он обладает рекурсивными возможностями.

Диагностика и нейтрализация ошибок.

Для данной грамматики производится только диагностика и нейтрализация ошибок. Исправление ошибок не производится.

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

Тестирование.

¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

Протокол работы синтаксического распознавателя вычисляемого оператора перехода языка FORTRAN.

¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

GOTO A+B-DD**(CC/(23+34**R))+Y*((C))

¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ 'A' с кодом 65.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа A.

SCAN  - Сканирование. Текущий символ '+' с кодом 43.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ 'B' с кодом 66.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа B.

SCAN  - Сканирование. Текущий символ '-' с кодом 45.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ 'D' с кодом 68.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа D.

SCAN  - Сканирование. Текущий символ 'D' с кодом 68.

SCAN  - Сканирование. Текущий символ '*' с кодом 42.

SCAN  - Сканирование. Текущий символ '*' с кодом 42.

SCAN  - Сканирование. Текущий символ '(' с кодом 40.

T     - Проверка на Терм.

O     - Проверка на Операнд.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ 'C' с кодом 67.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа C.

SCAN  - Сканирование. Текущий символ 'C' с кодом 67.

SCAN  - Сканирование. Текущий символ '/' с кодом 47.

SCAN  - Сканирование. Текущий символ '(' с кодом 40.

T     - Проверка на Терм.

O     - Проверка на Операнд.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ '2' с кодом 50.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа 2.

FLOAT   - Проверка на Дробное Без Знака с цифры 2.

SCAN  - Сканирование. Текущий символ '3' с кодом 51.

SCAN  - Сканирование. Текущий символ '+' с кодом 43.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ '3' с кодом 51.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа 3.

FLOAT   - Проверка на Дробное Без Знака с цифры 3.

SCAN  - Сканирование. Текущий символ '4' с кодом 52.

SCAN  - Сканирование. Текущий символ '*' с кодом 42.

SCAN  - Сканирование. Текущий символ '*' с кодом 42.

SCAN  - Сканирование. Текущий символ 'R' с кодом 82.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа R.

SCAN  - Сканирование. Текущий символ ')' с кодом 41.

SCAN  - Сканирование. Текущий символ ')' с кодом 41.

SCAN  - Сканирование. Текущий символ '+' с кодом 43.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ 'Y' с кодом 89.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа Y.

SCAN  - Сканирование. Текущий символ '*' с кодом 42.

SCAN  - Сканирование. Текущий символ '(' с кодом 40.

T     - Проверка на Терм.

O     - Проверка на Операнд.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ '(' с кодом 40.

T     - Проверка на Терм.

O     - Проверка на Операнд.

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ 'C' с кодом 67.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа C.

SCAN  - Сканирование. Текущий символ ')' с кодом 41.

SCAN  - Сканирование. Текущий символ ')' с кодом 41.

SCAN  - Сканирование. Текущий символ NULL с кодом 0.

¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

GOTO A

¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

AB    - Проверка на Арифметическое Выражение.

SCAN  - Сканирование. Текущий символ 'A' с кодом 65.

T     - Проверка на Терм.

O     - Проверка на Операнд.

IDENT - Проверка на Идентификатор с символа A.

SCAN  - Сканирование. Текущий символ NULL с кодом 0.

¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

Листинг программы.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//          FILE "KURSOVIK.CPP".

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//          ВАРИАHТ № 3.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//          Оператор перехода вычисляемый языка FORTRAN.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Кафедра: АСУ.

//             Группа: А-513.

//             Студент: Борзов Андрей Hиколаевич.

//             Преподаватели: кандидат технических наук, доцент Шорников Юрий Владимирович,

//                                             ассистент Панова Вера Борисовна.

//             Дата: 29 апреля 1997г.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Подключаемые файлы.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

#include<string.h>

#include<conio.h>

#include<stdio.h>

#include<dos.h>

#include<stdlib.h>

#include<ctype.h>

#include<time.h>

#include"keyboard.h"

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Макроопределения.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

#define  ERROR                                 0                              // Код ошибки.

#define  COL_STR                             20                           // Максимальное количество строк.

#define  STR_LEN                             35                           // Длина строки.

#define  MAX_STR_LEN                 255                         // Максимальная длина строки.

#define  FILENAME                          "TEST.TXT"         // Имя файла, открываемого по умолчанию.

#define  YES                                        1

#define  NO                                          2

#define  OK                                          3

//#define TEST                                    // Определено, если включен отладочный режим.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Прототипы функций.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int           I_ReadKey(void);                                               // Опрос клавиатуры.

void        Welcome(void);                                                   // Экран при старте программы.

void        Menu(void);                                                         // Меню.

void        Help(void);                                                           // Помощь.

void        MyExit(int=0);                                                     // Корректный выход из программы.

void        Beep(int=500,int=100);                                      // Звуковой сигнал.

void        Usage(void);                                                         // Использование программы.

int           OpenFile(void);                                                    // Открытие файла.

void        DrawBox(int,int,int,int,char*);                          // Рисует рамку с заголовком.

void        PrintText(void);                                                   // Печатает основной текст.

void        Screen(void);                                                        // Перерисовка экрана.

void        Compile(void);                                                     // Компиляция.

void        Message(int);                                                        // Вывод сообщений об ошибках.

void        MyPuts(char*,int);                                              // Аналог puts(char*);.

void        Language(void);                                                  // Язык оператора.

void        Grammar(void);                                                  // Грамматика языка.

void        GetFilename(void);                                             // Запрос имени файла для открытия.

int           ScanStr(char*);                                                    // Поиск GOTO.

int           Scaner(char*);                                                     // Обработка строки.

void        Scan(void);                                                           // Сканирование следующего символа.

void        Delspace(char*);                                                 // Удаление ненужных пробелов в строке.

int           AB(void);                                                              // Реализация нетерминала <АВ>.

int           T(void);                                                                 // Реализация нетерминала <Т>.

int           O(void);                                                                 // Реализация нетерминала <О>.

int           IDENT(void);                                                       // Реализация нетерминала <IDENT>.

int           FLOAT(void);                                                      // Реализация нетерминала <FLOAT>.

void        Error(int=0,char* ="");                                        // Обработка ошибки.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Глобальные переменные.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

char        filename[MAX_STR_LEN];                             // Имя файла.

char        *text[COL_STR+1];                                           // Массив указателей на строки текста.

char        screen[4096];                                                       // Буфер под копию экрана.

char        mes[21][20][80];                                                 // Массив под сообщения об ошибках.

char        nx;                                                                          // Текущий символ.

int           pos;                                                                        // Текущая позиция в строке.

char        STR[80];                                                               // Сканируемая строка.

int           ERR1;                                                                    // Счетчик страниц в массиве ошибок.

int           ERR2;                                                                    // Счетчик строк в массиве ошибок.

FILE       *errors;                                                                  // Дескриптор файла.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Функция MAIN.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void main(int argc,char* argv[])

                {

                textcolor(LIGHTGRAY);

                textbackground(BLACK);

                _setcursortype(_NOCURSOR);

                clrscr();

                if(argc>2)

                                {

                                Usage();

                                MyExit();

                                }

                if(argc==2)

                                strcpy(filename,argv[1]);

                else

                                {

                                Welcome();

                                gettext(20,7,60,17,screen);

                                GetFilename();

                                }

                while(OpenFile())

                                {

                                puttext(20,7,60,17,screen);

                                GetFilename();

                                }

                Menu();

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Вывод сообщений об ошибках.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void Message(int j)

                {

                window(42,3,79,23);

                textcolor(BLUE);

                textbackground(CYAN);

                clrscr();

                for(int i=0;i<COL_STR && mes[j][i][0]!=NULL;i++)

                                cprintf("%-30s\r\n",mes[j][i]);

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Гpамматика языка.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void Grammar(void)

                {

                window(1,25,80,25);

                textattr(112);

                MyPuts(" ~F1~ Help  ~F2~ Grammar  ~F3~ Language  ~F9~ Compile  ~F10~ Quit  ~Alt-X~

Quit  ~Esc~ Quit",DARKGRAY);

                window(10,5,70,20);

                textcolor(WHITE);

                textbackground(MAGENTA);

                clrscr();

                DrawBox(2,1,60,16,"Гpамматика языка");

                window(12,6,78,19);

                textcolor(YELLOW);

                cputs("\r\n");

                cputs(" 1. <Опеpатоp> -> GOTO <Выpажение>\r\n");

                cputs(" 2. <Выpажение> -> T | <Выpажение>+T | <Выpажение>-T\r\n");

                cputs(" 3. T -> O | T*O | T/O | T**O\r\n");

                cputs(" 4. O -> (<Выpажение>) | <Идентификатоp> | <ДБЗ>\r\n");

                cputs(" 5. <Идентификатоp> -> Б{Б|Ц}[L]\r\n");

                cputs(" 6. <ДБЗ> -> Ц{Ц}[.Ц{Ц}][L]\r\n\n");

                cputs(" T     - Теpм;\r\n");

                cputs(" O     - Опеpанд;\r\n");

                cputs(" Б     - Буква;\r\n");

                cputs(" Ц     - Цифpа;\r\n");

                cputs(" ДБЗ   - Дробное Без Знака;\r\n");

                cputs(" **    - возведение в степень.");

                I_ReadKey();

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Язык оператора.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void Language(void)

                {

                window(1,25,80,25);

                textattr(112);

                MyPuts(" ~F1~ Help  ~F2~ Grammar  ~F3~ Language  ~F9~ Compile  ~F10~ Quit  ~Alt-X~

Quit  ~Esc~ Quit",DARKGRAY);

                window(20,8,60,18);

                textcolor(WHITE);

                textbackground(GREEN);

                clrscr();

                DrawBox(2,1,40,11,"Язык оператора");

                window(22,9,58,17);

                textcolor(BLACK);

                cputs("\r\n");

                cputs(" GOTO  CONST | VAR | АВ\r\n\n");

                cputs(" CONST - Дробное без знака,\r\n");

                cputs(" VAR   - идентификатоp,\r\n");

                cputs(" АВ    - аpифметическое выpажение.");

                I_ReadKey();

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Компиляция.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void Compile(void)

                {

                static int compile=0;

                window(1,25,80,25);

                textattr(112);

                MyPuts(" ~F1~ Help  ~F2~ Grammar  ~F3~ Language  ~F9~ Compile  ~F10~ Quit  ~Alt-X~

Quit  ~Esc~ Quit",DARKGRAY);

                window(20,8,60,18);

                textcolor(WHITE);

                textbackground(RED);

                clrscr();

                DrawBox(2,1,40,11,"Компиляция");

                window(22,9,58,17);

                textcolor(YELLOW);

                cputs("\r\n");

                if(compile>0)

                                {

                                cputs(" Текст УЖЕ откомпилирован!!!");

                                Beep(900,1000);

                                return;

                                }

                errors=fopen("PROTOCOL.TXT","wt");

                cputs(" Идет компиляция.\r\n\n Пожалуйста, подождите...");

#ifdef TEST

window(1,1,80,25);

textattr(78);

clrscr();

#endif

                fprintf(errors,"/*******************************************************\n");

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                fprintf(errors,"ç   Протокол работы синтаксического распознавателя вычисляемого ç\n");

                fprintf(errors,"ç                         оператора перехода языка FORTRAN.                       ç\n");

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                for(int i=0;text[i] != NULL;i++)

                                Scaner(text[i]);

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                fprintf(errors,"ç                                       КОНЕЦ.                                                        ç\n");

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                fprintf(errors,"*******************************************************/\n");

                Beep(900,100);

                compile++;

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Обработка строки.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int Scaner(char* string)

                {

                char tmpstr[STR_LEN];

                strcpy(tmpstr,string);

                Delspace(tmpstr);

                ScanStr(tmpstr);

                return 0;

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Поиск в строке оператора GOTO.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int ScanStr(char* string)

                {

                int j;

                int i=0;

                int k=0;

                static int a=0;

                char tmp[80];

                char label=NO;

                strcpy(STR,string);

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                fprintf(errors,"%s\n",string);

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                do

                                {

                                tmp[0]=NULL;

                                j=0;

                                while(!isspace(string[k++]) && string[k-1]!=NULL)

                                                {

                                                tmp[j++]=string[k-1];

                                                }

                                tmp[j]=NULL;

                                if((strcmp(tmp,"GOTO") != 0) && !isdigit(tmp[0]))

                                                {

#ifdef TEST

cprintf("Не определен идентификатор %s.\r\n",tmp);

#endif

                                                ERR1=a;

                                                ERR2=i;

                                                i++;

                                                Error(5,tmp);

                                                }

                                else if(!isdigit(tmp[0]))

                                                {

                                                label=YES;

                                                ERR1=a;

                                                ERR2=i;

                                                pos=k;

                                                while(AB()!=OK);

                                                break;

                                                }

                                }

                while(string[k] != NULL);

                if(label==NO)

                                {

#ifdef TEST

cprintf("Не найден оператор GOTO.\r\nСтрока разбору не подлежит.\r\n");

#endif

                                Error(6);

                                }

                a++;

                return(OK);

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Удаление в строке пробелов.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void Delspace(char* string)

                {

                char str[STR_LEN];

                int j=0;

                int i=0;

                while(isspace(string[i]) && string[i] != NULL)

                                i++;

                for(;string[i] != NULL;i++)

                                {

                                if(islower(string[i]))

                                                string[i]=toupper(string[i]);

                                str[j++]=string[i];

                                }

                str[j]=NULL;

                sprintf(string,"%s",str);

                string[j-1]=NULL;

#ifdef TEST

textattr(30);

clreol();

cputs(string);

textattr(78);

cputs("\r\n");

#endif

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Реализация нетерминала <Арифметическое Выражение>.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int AB(void)

                {

#ifdef TEST

cprintf("AB    - Проверка на Арифметическое Выражение.\r\n");

#endif

                fprintf(errors,"AB    - Проверка на Арифметическое Выражение.\n");

                Scan();

                T();

                if(nx=='+')

                                {

                                AB();

                                }

                else if(nx=='-')

                                {

                                AB();

                                }

                if(nx==NULL)

                                return(OK);

                else if(nx!='*' && nx!='/' && nx!=')')

                                Error(1);

                return(YES);

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Реализация нетерминала <Терм>.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int T(void)

                {

#ifdef TEST

cprintf("T     - Проверка на Терм.\r\n");

#endif

                fprintf(errors,"T     - Проверка на Терм.\n");

                O();

                if(nx=='/')

                                {

                                Scan();

                                T();

                                }

                else if(nx=='*')

                                {

                                Scan();

                                if(nx=='*')

                                                {

                                                Scan();

                                                T();

                                                }

                                else T();

                                }

                if(nx==NULL)

                                return(OK);

                else if(nx!='+' && nx!='-' && nx!=')')

                                Error(2);

                return(OK);

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Реализация нетерминала <Операнд>.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int O(void)

                {

#ifdef TEST

cprintf("O     - Проверка на Операнд.\r\n");

#endif

                fprintf(errors,"O     - Проверка на Операнд.\n");

                if(nx=='(')

                                {

                                AB();

                                if(nx!=')')

                                                Error(3);

                                else

                                                {

                                                Scan();

                                                return(OK);

                                                }

                                }

                else        

if(IDENT() == NO)

                                                {

                                                if(FLOAT() == NO)

                                                                Error(4);

                                                }

                return(OK);

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Реализация нетерминала <Идентификатор>.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int IDENT(void)

                {

#ifdef TEST

cprintf("IDENT - Проверка на Идентификатор с символа %c.\r\n",nx);

getch();

#endif

                fprintf(errors,"IDENT - Проверка на Идентификатор с символа %c.\n",nx);

                if(isalpha(nx))

                                {

                                while(isalpha(nx) || isdigit(nx))

                                                Scan();

                                return(YES);

                                }

                return(NO);

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Реализация нетерминала <Дробное Без Знака>.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

int FLOAT(void)

                {

#ifdef TEST

cprintf("FLOAT   - Проверка на Дробное Без Знака с цифры %c.\r\n",nx);

getch();

#endif

                fprintf(errors,"FLOAT   - Проверка на Дробное Без Знака с цифры %c.\n",nx);

                if(isdigit(nx))

                                {

                                while(isdigit(nx))

                                                Scan();

                                if(nx=='.')

                                                {

                                                Scan();

                                                while(isdigit(nx))

                                                                Scan();

                                                }

                                return(YES);

                                }

                return(NO);

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Сканирование следующего символа из строки.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void Scan(void)

                {

#ifdef TEST

cprintf("SCAN  - Сканирование. Текущий символ '%c' с кодом %d.\r\n",STR[pos],STR[pos]);

getch();

#endif

                fprintf(errors,"SCAN  - Сканирование. Текущий символ '%c' с кодом

%d.\n",STR[pos],STR[pos]);

                nx=STR[pos];

                pos++;

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Обработка ошибок.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

void Error(int num,char* s)

                {

                char *E[40]=

                                  {

                                  "Ожидается '+' или '-'",

                                  "Ожидается '*', '/' или '**'",

                                  "Ожидается ')'",

                                  "Ожидается идентификатор или Дробное без знака",

                                  "Не определен идентификатор ",

                                  "Не найден оператор GOTO\r\nСтрока разбору не подлежит",

                                  NULL

                                  };

                sprintf(mes[ERR1][ERR2],"%s%s",E[num-1],s);

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                fprintf(errors,"Error - Ошибка строка %d, ошибка # %d.\n",ERR1,ERR2);

#ifdef TEST

cprintf("Error - Ошибка: строка # %d, ошибка # %d.\r\n",ERR1,ERR2);

cprintf("%s\r\n",mes[ERR1][ERR2]);

Beep(1000,200);

getch();

#endif

                fprintf(errors,"%s\n",mes[ERR1][ERR2]);

                fprintf(errors,"––––––––––––––––––––––––––––––––––––––––––––––––––––––––\n");

                ERR2++;

                mes[ERR1][ERR2][0]=NULL;

                }

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

//             Подключаемый файл.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

#include"intface.h"             // Файл с функциями интерфейса.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

// Ó 1997 Борзов Андрей Hиколаевич. E-mail: ANDREY@RedHouse.nstu.nsk.su.

//¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾

Литература.

1. Курс лекций по системному программированию.

2. Герберт Шилдт «C для профессиональных программистов».