Міністерство науки, вищої школи і технічної політики Російської p>
Федерації. p>
Новосибірський Державний p>
Технічний Університет. p>
p >
Курсова робота з системного програмування. p>
Розробка синтаксичного розпізнавача обчислюваного оператора переходу мови FORTRAN.
Факультет: АВТ.
Кафедра: АСУ.
Група: А-513.
Студент: Борзов Андрей Николаевич.
Викладач: Шорников Юрій Володимирович.
Асистент: Панова Віра Борисівна.
Дата: 19 травня 1997 року.
Відмітка про захист: _______________________________ p>
Новосибірськ - 1997. P>
Мова оператора. P>
Мова обчислюваного оператора переходу мови FORTRAN. P>
GOTO МЕТКА ( КОНСТАНТА (арифметичних виразів p>
МЕТКА - Ідентифікатор p>
КОНСТАНТА - ЦЕЛОЕ БЕЗ ЗНАКА p>
арифметичних виразів - вираз, що містить У СЕБЕ ОПЕРАЦІЇ *, /, -,
+, **, А ТАКОЖ (). P>
** - Піднесення до степеня. P>
Граматика мови. P>
G []:
1. (GOTO
2. (Т (+ Т ((Т
3. Т (О (Т (О (Т/О (Т ((Про
4. Про (() ((
5. (Б (Б (Ц }[(]< br>6. (Ц (Ц) [. Ц (Ц }][(] p>
| Т | - | ТЕРМ |
| Про | - | Операнд |
| Б | - | БУКВА |
| Ц | - | ЦИФРА |
| ДБЗ | - | Дробная БЕЗ ЗНАКА |
| (| - | КІНЕЦЬ СТРОКИ (пусто) |
| ** | - | Піднесення до степеня | p>
Класифікація граматики. P>
Дана граматика G [], згідно з класифікацією Хомського,є контекстно-вільною, так як права частина кожної редукціїпочинається або з термінального символу, або з нетермінального,що належить об'єднаному словника. p>
A (a, A (Vn, a (V (. p>
Граматика G [] не є автоматною, тому що не всі їїредукції починаються з термінального символу. З цієї ж причини данаграматика не є S - граматикою. p>
Метод аналізу. p>
Для даної граматики реалізований розбір методом рекурсивного спуску,оскільки вона належить до класу контекстно-вільних. p>
Ідея методу полягає в тому, що кожному нетермінальному символуставиться у відповідність певна програмна одиниця (функція), якарозпізнає ланцюжок, що породжуються цим нетерміналом. p>
Ці процедури і функції викликаються відповідно до правилграматики і іноді викликають самі себе. p>
Даний метод реалізований на мові C + +, оскільки він володієрекурсивними можливостями. p>
Діагностика та нейтралізація помилок. p>
Для даної граматики проводиться тільки діагностика та нейтралізаціяпомилок. Виправлення помилок не проводиться. P>
Нейтралізація помилок здійснюється за методом Айронса, тобто,спускаючись по синтаксичному дереву без повернення на контекст, привиявленні тупикової ситуації відкидаються ті літери (символи), якіпривели в контексте і розбір триває. p>
Тестування. p>
(((((((((((((((((((((((((( (((((((((((((( p>
Протокол роботи синтаксичного розпізнавача обчислюваного оператора переходу мови FORTRAN.
((((((((((((((((((((((((((((((((((((((((< br>GOTO A + B-DD ** (CC/(23 +34 ** R)) + Y * ((C))
((((((((((((((((((((((((((((((((((((((((< br>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.
((((((((((((((((((((((((((((((((((((((((< br>((((((((((((((((((((((((((((((((((((((((< br>GOTO A
((((((((((((((((((((((((((((((((((((((((< br>AB - Перевірка на Арифметичне Вираз.
SCAN - Сканування. Поточний символ 'A' з кодом 65.
T - Перевірка на Терм.
O - Перевірка на Операнд.
IDENT - Перевірка на Ідентифікатор з символу A.
SCAN - Сканування. Поточний символ NULL з кодом 0.
(((((((((((((((((((((((((((((((((((((((( p>
Лістинг програми. p>
//(((((((((((((((((((((((((((((((((((((((< br >//FILE "KURSOVIK.CPP".
//(((((((((((((((((((((((((((((((((((((((< br>//ВАРІАHТ № 3.
//(((((((((((((((((((((((((((((((((((((((< br>//Оператор переходу обчислюваний мови FORTRAN.
//(((((((((((((((((((((((((((((((((((((((< br>//Кафедра: АСУ.
//Група: А-513.
//Студент: Борзов Андрій Hіколаевіч.
//Викладачі: кандидат технічних наук, доцент Шорников Юрій
Володимирович,
//Асистент Панова Віра Борисівна.
//Дата: 29 квітня 1997р.
//(((((((((((((((((((((((((((((((((((((((< br>//Підключаються файли.
//(((((((((((((((((((((((((((((((((((((((< br># include
# include
# include
# include
# include
# include
# include
# include "keyboard.h"
//(((((((((((((((((((((((((((((((((((((((< br>//Макровизначеннями.
//(((((((((((((((((((((((((((((((((((((((< br># 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// Визначено, якщо включений налагоджувальний режим.
//(((((((((((((((((((((((((((((((((((((((< br>//Прототипи функцій.
//(((((((((((((((((((((((((((((((((((((((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);// Реалізація нетермінала.int FLOAT (void);// Реалізація нетермінала.void Error (int = 0, char * ="");// Обробка помилки.
//(((((((((((((((((((((((((((((((((((((((< br>//Глобальні змінні.
//(((((((((((((((((((((((((((((((((((((((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;// Дескриптор файлу.
//(((((((((((((((((((((((((((((((((((((((< br>//Функція MAIN.
//(((((((((((((((((((((((((((((((((((((((void main (int argc, char * argv []) p>
(textcolor (LIGHTGRAY); textbackground (BLACK); p>
_setcursortype (_NOCURSOR); clrscr (); if (argc> 2) p>
( p>
Usage (); p>
MyExit (); p>
) if (argc == 2) strcpy (filename , argv [1]); else p>
( p>
Welcome (); gettext (20,7,60,17, screen); p>
GetFilename () ; p>
) while (OpenFile ()) p>
(puttext (20,7,60,17, screen); p>
GetFilename (); p >
) p>
Menu (); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Вивід повідомлень про помилки.
//(((((((((((((((((((((((((((((((((((((((void Message (int j) p>
(window (42,3,79,23); textcolor (BLUE); textbackground (CYAN); clrscr (); for (int i = 0; i GOTO rn " ); cputs ( "2. -> T | + T |-Trn"); cputs ( "3. T -> O | T * O | T/O | T ** Orn"); cputs ( "4. O -> () | | rn "); cputs (" 5. -> Б (Б | Ц) [(] rn "); cputs (" 6. -> Ц (Ц) [. Ц (Ц)] [( ] rnn "); cputs (" T - Теpм; rn "); cputs (" O - Опеpанд; rn "); cputs (" Б - Буква; rn "); cputs (" Ц - цифр; rn "); cputs ( "ДБЗ - дробове Без Знака; rn"); cputs ( "** - піднесення до степеня ."); p>
I_ReadKey (); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Мова оператора.
//(((((((((((((((((((((((((((((((((((((((void Language (void) p>
(window (1,25,80,25); textattr (112); p>
MyPuts ( "~ F1 ~ F2 Help ~ ~ Grammar ~ F3 ~ Language ~ F9 ~ Compile ~ F10 ~
Quit ~ Alt-X ~ p>
Quit ~ ~ Esc Quit ", DARKGRAY); window (20,8,60,18); textcolor (WHITE); textbackground (GREEN); clrscr (); p>
DrawBox (2,1,40,11, "Мова оператора"); window (22,9,58,17); textcolor (BLACK); cputs ( "rn"); cputs ( "GOTO CONST | VAR | АВrnn "); cputs (" CONST - дробове без знака, rn "); cputs (" VAR - ідентіфікатоp, rn "); cputs (" АВ - аpіфметіческое виpаженіе ."); p>
I_ReadKey ( ); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Компіляція.
//(((((((((((((((((((((((((((((((((((((((void Compile (void) p>
(static int compile = 0; window (1,25,80,25); textattr (112); p>
MyPuts ( "~ F1 ~ ~ Help F2 ~ Grammar ~ F3 ~ Language ~ F9 ~ Compile ~ F10 ~
Quit ~ Alt-X ~ p>
Quit ~ ~ Esc Quit ", DARKGRAY); window (20,8,60,18); textcolor (WHITE); textbackground (RED); clrscr (); p>
DrawBox (2,1,40,11, "Компіляція"); window (22,9,58,17); textcolor (YELLOW); cputs ( "rn"); if (compile> 0)
(cputs ( "Текст ВЖЕ відкомпілювати !!!"); p>
Beep (900,1000); return; p>
) errors = fopen (" PROTOCOL. TXT "," wt "); cputs (" Йде компіляція.rnn Будь ласка, почекайте ...");< br># ifdef TESTwindow (1,1,80,25);textattr (78);clrscr ();
# endif p>
fprintf (errors ,"/*********************************** ******************** n ")
; p>
fprintf (errors ,"------------------------------------- ------------------- n ")
; Fprintf (errors, "(Протокол роботи синтаксичного розпізнавачаобчислюваного (n "); fprintf (errors," (оператора переходу мови
FORTRAN. (n "); p>
fprintf (errors ,"--------------------------------- ----------------------- n ")
; For (int i = 0; text [i]! = NULL; i ++) p>
Scaner (text [i ]); p>
fprintf (errors ,"----- -------------------------------------------------- -n ")
; Fprintf (errors, "(КОНЕЦ. p>
(n "); p>
fprintf (errors ,"----------------- --------------------------------------- n ")
; p>
fprintf (errors ,"************************************* ******************/ n ")
; p>
Beep (900,100); compile ++; p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Обробка рядка.
//(((((((((((((((((((((((((((((((((((((((int Scaner (char * string) p>
(char tmpstr [STR_LEN]; strcpy (tmpstr, string); p>
Delspace (tmpstr); p>
ScanStr (tmpstr ); return 0; p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Пошук в рядку оператора GOTO.
//(((((((((((((((((((((((((((((((((((((((int ScanStr (char * string) p>
(int j; int i = 0; int k = 0; static int a = 0; char tmp [80]; char label = NO; strcpy (STR, string ); p>
fprintf (errors ,"------------------------------------ -------------------- n ")
; Fprintf (errors, "% sn", string); p>
fprintf (errors ,"------------------------- ------------------------------- n ")
; Do p>
(tmp [0] = NULL; j = 0; while (! Isspace (string [k + +]) & & string [k-1]! = NULL) p>
( tmp [j + +] = string [k-1]; p>
) tmp [j] = NULL; if ((strcmp (tmp, "GOTO")! = 0) & &! isdigit (tmp [0] )) p>
(
# ifdef TESTcprintf ( "Не визначено ідентифікатор% s.rn", tmp);
# endif p>
ERR1 = a; p>
ERR2 = i; i ++; p>
Error (5, tmp); p>
) else if (! isdigit (tmp [0 ])) p>
(label = YES; p>
ERR1 = a; p>
ERR2 = i; pos = k; while ( AB ()! = OK); break; p>
) p>
) while (string [k]! = NULL); if (label == NO) p>
(
# ifdef TESTcprintf ( "Не знайдено оператор GOTO.rnСтрока розбору не подлежіт.rn");
# endif p>
Error (6); p>
) a + +; return (OK); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Видалення в рядку пробілів.
//(((((((((((((((((((((((((((((((((((((((void Delspace (char * string) p>
(char str [STR_LEN]; int j = 0; int i = 0; while (isspace (string [i]) & & string [i]! = NULL) i + + ; for (; string [i]! = NULL; i ++) p>
(if (islower (string [i])) string [i] = toupper (string [i]); str [j + +] = string [i]; p>
) str [j] = NULL; sprintf (string, "% s", str); string [j-1] = NULL;
# ifdef TESTtextattr (30);clreol ();cputs (string);textattr (78);cputs ( "rn");
# endif p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Реалізація нетермінала.
//(((((((((((((((((((((((((((((((((((((((int AB (void) p>
(
# ifdef TESTcprintf ( "AB - Перевірка на Арифметичне Вираженіе.rn");
# endif fprintf (errors, "AB - Перевірка на Арифметичне Вираженіе.n "); p>
Scan (); p>
T (); if (nx =='+')
( p>
AB (); p>
) else if (nx =='-') p>
( p>
AB (); p>
) if (nx == NULL) return (OK); else if (nx !='*' & & nx !='/' & & nx !=')')
Error (1); return (YES); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Реалізація нетермінала.
//(((((((((((((((((((((((((((((((((((((((int T (void) p>
(
# ifdef TESTcprintf ( "T - Перевірка на Терм.rn");
# endif fprintf (errors, "T - Перевірка на Терм.n "); p>
O (); if (nx =='/') p>
( p> < p> Scan (); p>
T (); p>
) else if (nx =='*') p>
( p>
Scan (); if (nx =='*') p>
( p>
Scan (); p>
T (); p>
) else T (); p>
) if (nx == NULL) return (OK); else if (nx !='+' & & nx !='-' & & nx !=')') p>
Error (2); return (OK); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Реалізація нетермінала.
//(((((((((((((((((((((((((((((((((((((((int O (void) p>
(
# ifdef TESTcprintf ( "O - Перевірка на Операнд.rn");
# endif fprintf (errors, "O - Перевірка на Операнд.n"); if (nx =='(') p>
( p>
AB (); if (nx! = ')') p>
Error (3); else p>
( p>
Scan (); return (OK); p>
)
) else if (IDENT () == NO) p>
(if (FLOAT () == NO) p>
Error (4); p>
) return (OK); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Реалізація нетермінала.
//(((((((((((((((((((((((((((((((((((((((int IDENT (void) p>
(
# ifdef TESTcprintf ( "IDENT - Перевірка на Ідентифікатор з символу% c.rn", nx);getch ();
# endif fprintf (errors, "IDENT - Перевірка на Ідентифікатор з символу
% cn ", nx); if (isalpha (nx)) p>
(while (isalpha (nx) | | isdigit (nx)) p>
Scan (); return (YES) ; p>
) return (NO); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Реалізація нетермінала.
//(((((((((((((((((((((((((((((((((((((((int FLOAT (void) p>
(
# ifdef TESTcprintf ( "FLOAT - Перевірка на дробове Без Знака з цифри% c.rn", nx);getch ();
# endif fprintf (errors, "FLOAT - Перевірка на дробове Без Знака з цифри
% cn ", nx); if (isdigit (nx)) p>
(while (isdigit (nx)) p>
Scan (); if (nx =='.')
( p>
Scan (); while (isdigit (nx)) p>
Scan (); p>
) return (YES);
) return (NO); p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Сканування наступного символу з рядка.
//(((((((((((((((((((((((((((((((((((((((void Scan (void) p>
(
# ifdef TESTcprintf ( "SCAN - Сканування. Поточний символ '% c' з кодом
% d.rn ", STR [pos], STR [pos]);getch ();
# endif fprintf (errors, "SCAN - Сканування. Поточний символ '% c' з кодом p>
% dn", STR [pos], STR [pos]); nx = STR [pos]; pos + +; p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Обробка помилок.
//(((((((((((((((((((((((((((((((((((((((void Error (int num, char * s) p>
(char * E [40] = p>
( p>
"Очікується '+' або '-'" , p>
"Очікується '*', '/' або'**'", p>
" Очікується')'", p>
"Очікується ідентифікатор або дробові без знаку ", p>
" Не визначено ідентифікатор ", p>
" Не знайдено оператор GOTOrnСтрока розбору не підлягає ", p>
NULL p>
) ; sprintf (mes [ERR1] [ERR2], "% s% s", E [num-1], s); p>
fprintf (errors ,"---------- ---------------------------------------------- n ") < br>; Fprintf (errors, "Error - Помилка рядок% d, помилка #% dn", ERR1, ERR2);
# ifdef TESTcprintf ( "Error - Помилка: string #% d, помилка #% d.rn", ERR1, ERR2);cprintf ( "% srn", mes [ERR1] [ERR2]);
Beep (1000,200);getch ();
# endif fprintf (errors, "% sn", mes [ERR1] [ERR2 ]); p>
fprintf (errors ,"------------------ -------------------------------------- n ")
; p>
ERR2 + +; mes [ERR1] [ERR2] [0] = NULL; p>
)
//(((((((((((((((((((((((((((((((((((((((< br>//Підключається файл.
//(((((((((((((((((((((((((((((((((((((((< br># include "intface.h"// Файл з функціями інтерфейсу.
//(((((((((((((((((((((((((((((((((((((((< br>//(1997 Борзов Андрій Hіколаевіч. E-mail: [email protected].
//((((((((((((((((((((((((((((((((((((((( p>
Література. p>
1. Курс лекцій з системного програмування.
2. Герберт Шилдт «C для професійних програмістів». P>
p>