Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Кафедра прикладної математики

Інформація про роботу

Рік:
2010
Тип роботи:
Лабораторна робота
Предмет:
Системне програмування
Група:
ПМ-31

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти та науки України Національний університет «Львівська політехніка» кафедра прикладної математики ЛАБОРАТОРНА РОБОТА №3 з системного програмування на тему: «Синтаксичний аналіз» Мета: побудувати граматику, яка породжує запропоновану підмножину мови програмування, визначити типи можливих помилок та форму відповідного повідомлення . Написати програму синтаксичного контролю методом рекурсивного спуску (низхідний аналіз), попередньо застосувавши еквівалентні перетворення граматики (якщо потрібно). При потребі внести доповнення у підпрограму лексичного аналізу. Написати програму – синтаксичний аналізатор, що отримує на вході – текст вхідної програми на запропонованій підмножині мови програмування (у вхідному файлі), а на виході – повідомлення про наявність синтаксичних помилок у вхідній програмі (можна вести контроль до першої помилки) з інформацією про тип помилки та місце її знаходження. Для виділення чергової лексеми використати підпрограму, розроблену у Лаб. Роботі №2. Варіант №9. Завдання: Розглянути підмножину мови Pascal, у якій є ідентифікатори (довжина – не більше 10 символів), цілі константи (довжина – не більше 6 символів), які використовуються у операторах опису (типи змінних – real , integer,boolean), оператори присвоєння, оператори циклу типу while (умова – логічний вираз, утворений з логічних змінних і відповідних логічних операцій). Граматика: S → Program I; [R] T R → var P P → Z: Y;{Z: Y;} Z → I {, I} Y → Real | Integer | Boolean T → begin A end. A → B {;B} B → V | W | L V → I := U W → while G do B L → begin A end U → M | M + U | M – U | M or U M → N | N * M | N / M | N and M N → I | C | (G) | not N D → = | < | > | <> | <= | >= G → U D U | (G) Де: S = <Програма> R = <Розділ описів> P = <Опис> Z = <Змінні> Y = <Тип> T = <Тіло програми> A = <Оператори> B = <Оператор> V=<Присвоєння> W = <While> L = <Блок> U = <Вираз> M = <Терм> N = <Множ> D = <Відношення> G = <Логічний вираз> Код програми: #include <fstream.h> #include <string.h> #include <stdio.h> #include <iostream.h> #include <ctype.h> #include <windows.h> //*********************Opus Global'nuh zminnuh***********************// FILE *in; char *f1 = "input.txt"; char *lex, syn, lit = ' ', ch = 0; int cl = 9, f = 0, num = 1, id_num = 0; struct st { char *id; int type; }; st M_id[100]; //************************Prototupu fynkcij**************************// int getlit(); int zarezerv(char*); void scan(); void S(); void R(); void P(); void Z(); void Y(); void T(); void A(); void B(); void V(); void W(); void L(); void U(); void M(); void N(); void G(); void D(); void Vudilutu_Lexemy(); //****************************MAIN***********************************// void main(void) { in=fopen(f1, "r"); S(); if(f) Vudilutu_Lexemy(); else cout<<"\n\nV programi nemae pomulok...\n"; for(int j = 0; j < id_num; j++) cout<<"\n"<<M_id[j].id<<"\t"<<M_id[j].type; } //*************************Opus fynkcij******************************// int getlit() { lit = fgetc(in); if(ch != 0) putchar(ch); ch = lit; if(lit >= 'A' && lit <= 'Z') lit -= 'A' - 'a'; switch (lit) { case '+': return 3; break; case '-': return 3; break; case '*': return 3; break; case '/': return 3; break; case ';': return 3; break; case '(': return 3; break; case ')': return 3; break; case ',': return 3; break; case '.': return 3; break; case '<': return 4; break; case ':': return 5; break; case '=': return 6; break; case '>': return 7; break; } if(isalpha(lit)) return 1; else if(isdigit(lit))return 2; else return 9; } int zarezerv(char* lex) { if (!stricmp(lex,"begin")) {syn ='G';return 1;} if (!stricmp(lex,"end")) {syn ='N';return 1;} if (!stricmp(lex,"integer")) {syn ='I';return 1;} if (!stricmp(lex,"real")) {syn ='R';return 1;} if (!stricmp(lex,"boolean")) {syn ='L';return 1;} if (!stricmp(lex,"do")) {syn ='T';return 1;} if (!stricmp(lex,"while")) {syn ='W';return 1;} if (!stricmp(lex,"var")) {syn ='V';return 1;} if (!stricmp(lex,"program")) {syn ='M';return 1;} if (!stricmp(lex,"or")) {syn ='O';return 1;} if (!stricmp(lex,"and")) {syn ='U';return 1;} if (!stricmp(lex,"not")) {syn ='C';return 1;} return 0; } void scan() { int i; lex=new char[30]; if(cl&&!feof(in)) { i=0; while (lit==' ' || lit=='\n' || lit=='\t') { if(lit == '\n') num++; cl=getlit(); } switch(cl) { case 1: lex[i++]=lit; cl=getlit(); while ((cl<=2)&&(cl!=0)) {lex[i++]=lit;cl=getlit();} lex[i]='\0'; if(zarezerv(lex)) { break;} else {if(i<=10) syn='A'; else {syn='E';break;}} break; case 2: lex[i++]=lit; cl=getlit(); while ((cl==2)&&(cl!=0)) {lex[i++]=lit; cl=getlit();} lex[i]='\0'; if(i<=6) syn='B';else syn='F';break; case 3: lex[0]=lit;lex[1]='\0'; syn=lit; cl=getlit();break; case 4: lex[i++]=lit; cl=getlit(); if (cl==7) {lex[i++]=lit; lex[i]='\0'; syn='D'; cl=getlit();break;} else {if (cl==6) {lex[i++]=lit; lex[i]='\0'; syn='H'; cl=getlit();break;}} lex[i]='\0';syn='J';break; case 5: lex[i++]=lit; cl=getlit(); if (cl==6) {lex[i++]=lit; lex[i]='\0'; syn='K'; cl=getlit();break;} lex[i]='\0';syn=':';break; case 6: lex[i++]=lit;lex[i]='\0'; cl=getlit(); syn='P';break; case 7: lex[i++]=lit;cl=getlit(); if (cl==6) {lex[i++]=lit; lex[i]='\0'; syn='Q'; cl=getlit();break;} lex[i]='\0';syn='R';break; case 9: lex[0]=lit;lex[1]='\0'; syn='X';cl=getlit();break; } } } void S() { scan(); if(syn != 'M'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": Programa povuna po4unatus' zi slova Program!!!\n"; return;} scan(); if(syn != 'A'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": Nekorektne imja programu!!!\n"; return;} scan(); if(syn != ';'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyet'sja ';'!!!\n"; return;} scan(); if(syn != 'V' && syn != 'G'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyet'sja BEGIN abo VAR!!!\n"; return;} if(syn == 'V') R(); if(f) return; T(); } void R() { if(f) return; scan(); P(); } void P() { if(f) return; Z(); if(f) return; if(syn != ':'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ':'!!!\n"; return;} scan(); Y(); if(f) return; if(syn != ';'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ';'!!!\n"; return;} scan(); while(syn != 'G') { Z(); if(f) return; if(syn != ':'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ':'!!!\n"; return;} scan(); Y(); if(f) return; if(syn != ';'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ';'!!!\n"; return;} scan(); } } void Z() { if(f) return; if(syn != 'A'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja identufikator!!!\n"; return;} M_id[id_num].id = lex; M_id[id_num++].type = 4; scan(); while(syn != ':') { if(syn != ','){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ':'!!!\n"; return;} scan(); if(syn != 'A'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja identufikator!!!\n"; return;} M_id[id_num].id = lex; M_id[id_num++].type = 4; scan(); } } void Y() { if(f) return; if(syn != 'I' && syn != 'R' && syn != 'L'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": Nevidomuj typ danuh!!!\n"; return;} while(M_id[id_num].type == 4) { } scan(); } void T() { if(f) return; if(syn != 'G'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja BEGIN!!!\n"; return;} scan(); A(); if(f) return; if(syn != 'N'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja END!!!\n"; return;} scan(); if(feof(in)) {printf(" "); lex = " ";} if(syn != '.'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja '.'!!!\n"; return;} } void A() { if(f) return; if(syn != 'N') B(); if(f) return; while(syn != 'N') { if(syn != ';'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ';'!!!\n"; return;} scan(); if(syn == 'N') break; B(); if(f) return; } } void B() { if(f) return; //while(syn == ';') scan(); if(syn == 'N') return; if(syn == 'W') W(); else if(syn == 'G') L(); else if(syn == 'A') V(); else {f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": Neo4ikyvani symvolu!!!\n"; return;} } void V() { if(f) return; if(syn != 'A'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja identufikator!!!\n"; return;} scan(); if(syn != 'K'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ':='!!!\n"; return;} scan(); G(); } void W() { if(f) return; scan(); G(); if(f) return; if(syn != 'T'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja DO!!!\n"; return;} scan(); B(); } void L() { if(f) return; scan(); A(); if(f) return; if(syn != 'N'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja END!!!\n"; return;} scan(); } void G() { U(); if(syn != 'P' && syn != 'J' && syn != 'R' && syn != 'D' && syn != 'H' && syn != 'Q') return; D(); U(); } void U() { if(f) return; M(); if(f) return; if(syn == '+' || syn == '-' || syn == 'O'){scan(); U();} } void M() { if(f) return; N(); if(f) return; if(syn == '*' || syn == '/' || syn == 'U'){scan(); M();} } void N() { if(f) return; if(syn == '(') { scan(); U(); if(f) return; if(syn != ')'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyjet'sja ')'!!!\n"; return;} } else if(syn == 'C'){scan(); N();} else if(syn == 'E'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": Dovzhuna identufikatora <= 10!!!\n"; return;} else if(syn == 'F'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": Dovzhuna ciloji konstantu <= 6!!!\n"; return;} else if(syn != 'A' && syn != 'B'){f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": Pomulka y vurazi!!!\n"; return;} scan(); } void D() { if(f) return; if(syn != 'P' && syn != 'J' && syn != 'R' && syn != 'D' && syn != 'H' && syn != 'Q') {f = 1; cout<<"\n\n!!!ERROR!!!Line "<<num<<": O4ikyet'sja logi4na operacija!!!\n"; return;} scan(); } void Vudilutu_Lexemy() { int X, Y; CONSOLE_SCREEN_BUFFER_INFO csbi; COORD coord; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); X = coord.X = csbi.dwCursorPosition.X; Y = coord.Y = csbi.dwCursorPosition.Y; coord.X -= strlen(lex); SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 192); printf(lex); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); while(!feof(in)) { lit = fgetc(in); if(ch != 0) putchar(ch); ch = lit; } } Функція Vudilutu_Lexemy() – виділяє лексему при аналізі якої виникла помилка. Спочатку курсор перемішується на довжину лексеми назад по рядку(функція SetConsoleCursorPosition), далі змінюється атрибут тексту(192 – чорний шрифт на червоному фоні), потім друкується лексема ще раз, на сам кінець атрибут повертається в стандартний(7 – стандартний атрибут) та додруковується залишок вхідної програми. Контрольний приклад: Приклад вхідного файлу: program a34; var abcd2, f: real; b, a, s: integer; se, c, d: BooLeAn; efw,dwewe,we:Real; Begin f:=(b*b)+a*s - f * s+b; while ((s>= (s*a/s)) do begin bEgin b:=165523; c:= not true; end; d:=not false or (not se or d); c := not c and se or false; se := TrUe or FaLsE and d or not c; end; end. Приклад виводу в консолі: program a34; var abcd2, f: real; b, a, s: integer; se, c, d: BooLeAn; efw,dwewe,we:Real; Begin f:=(b*b*)+a*s - f * s+b; while ((s>= (s*a/s)) do begin bEgin b:=165523; c:= not true; end; d:=not false or (not se or d); c := not c and se or false; se := TrUe or FaLsE and d or not c; end; end. !!!ERROR!!!Line 11: Pomulka y vurazi!!! Press any key to continue Висновок: На цій лабораторній я ознайомився з принципом синтаксичного аналізу – перевірки вхідної програми на належність написаній граматиці за допомогою методу рекурсивного спуску. Метод рекурсивного спуску полягає в аналізі «з гори – до низу» - ми рухаємось від початкового не терміналу граматики до вхідної стрічки(коду програми) використовуючи рекурсію – за допомогою якої легко описуються циклічні структури. Також я написав програму синтаксичного контролю вхідного тексту програми написаної на мові Pascal, яка при виявленні помилки виводить рядок програми що містить помилку та вказує тип помилки. Результати програми виводяться на екран.
Антиботан аватар за замовчуванням

01.01.1970 03:01-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!