Синтаксичний аналіз

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

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

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

Рік:
2007
Тип роботи:
Лабораторна робота
Предмет:
Інші
Група:
ПМ-32

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

Міністерство освіти і науки України Національний університет «Львівська політехніка» ЛАБОРАТОРНА РОБОТА №3. Синтаксичний аналіз Львів – 2007 Мета: виконати синтаксичний аналіз вхідного файлу використовуючи результат лексичного аналізу. Вхідні дані – текст вхідної програми підмножині мови програмування С. В-19 Розглянути підмножину мови C, у якій є ідентифікатори (довжина – не більше 10 символів), цілі константи (довжина – не більше 6 символів), дійсні константи з фіксованою крапкою, які використовуються у операторах опису (типи змінних – float , int), оператори присвоєння, оператори циклу типу for. 1. Вхідний файл: (один з можливих варіантів, без помилок) void main( ) {int i,j , k = -10; //int ident10k ; int id40 ; i = 2567; j =-3239 ; float fiden = - 22.38; float abcd123ef ; avcd1dd2 = 1259.38 ; for (id40 = 0; id40< i ; i++) {j = j;dfd=43;}; for (ident10k = 200; ident10k >= 100; ident10k--) {abcd123ef= abcd123ef; }; for(uhuh=2;j==-1;j++){j=fdj;int df=34;}; } 2. Потік лексем: z void z main o ( o ) o { t int i i o , i j o , i k = = - - c 10 o ; t int i id40 o ; i i = = c 2567 o ; i j = = - - c 3239 o ; a float i fiden = = - - d 22.38 o ; a float i abcd123ef o ; i avcd1dd2 = = d 1259.38 o ; f for o ( i id40 = = c 0 o ; i id40 s < i i o ; i i p ++ o ) o { i j = = i j o ; i dfd = = c 43 o ; o } o ; f for o ( i ident10k = = c 200 o ; i ident10k n >= c 100 o ; i ident10k m -- o ) o { i abcd123ef = = i abcd123ef o ; o } o ; f for o ( i uhuh = = c 2 o ; i j t == - - c 1 o ; i j p ++ o ) o { i j = = i fdj o ; t int i df = = c 34 o ; o } o ; o } Всі символи були розбиті на класи: букви – для ідентифікаторів цифри – для цифр та ідентифікаторів лексеми одиничної довжини ( , ; { } * ) ( ) – для знаків одиничної довжини знак + - для виділення знаку + та інкременту ++ знак – - для виділення знаку – та декременту -- знак / - для виділення знаку / та коментарів знак < > - для виділення знаків <, > та <=, >= знак . – для визначення дійсного числа решта знаків які не ввійшли до класів 1-8, 10 знак = - для виділення знаку = та порівняння = = Дескриптори лексем: z – визначає службове (зарезервоване) слово: main, void f - визначає for a - визначає float t - визначає int i – ідентифікатор c – ціле число d – дійсне число o – одно символьна лексема: , ; { } * ) ( + - операцію + p - інкремент - - операція - m - декремент / - операцію / s – строга нерівність <, > n – нестрога нерівність <=, >= = - операція присвоєння = t – операція порівняння = = 3. Граматика: Примітка1. Крапка після «відкриваючого» символу і крапка до «закриваючого» символу вказує на те що ці символи не належать до термінальних символів Не термінальні символи: M T F P O I D N M – заголовок основної програми – main T – тіло програми або циклу F – оператор for P – операція присвоєння O – опис змінних I – ініціалізація оператора for D – інкремент або декремент ідентифікатора. Використовується в 3тій складовій ініціалізації for ( I ) N – порівняння в другій складовій ініціалізації for ( I ) Термінальні символи: z f a t i c d , ; { } ) ( p m s n t = Аксіома: M Правила виводу: M => [. z .] z ( [. z .] ) { T } T => F | P | O F => f ( I ) { T } ; P => i = (. i | d | c .) ; O => t i [. = (. i | c .) .] {. , i [. = (. i | c .) .] .} ; | a i [. = (. i | d .) .] {. , i [. = (. i | d .) .] .} ; I => (. O | P .) N D D => i (. p | m .) N => i (. s | n | t .) (. i | d | c .) ; 4. Реалізація виводу про помилки: Всі помилки розбиті на такі класи: 0 – Помилки в main (при наявності такої помилки подальший аналіз може не відбутись – для тіла T) 1 – Помилки в операторі for ( в тому числі і і його ініціалізації I ) 2 – Помилки в операторі присвоєння 3 – Помилки в описі змінних 4 – Помилки лексичного аналізу, що стосуються перевищення довжини ідентифікаторів, цілих і дійсних чисел. Примітка2. При виконанні лексичного аналізу дескриптору лексеми надається значення «е»(при наявності помилки 4). В подальшому, при синтаксичному аналізі це ствоює незручності. Тому при роботі синтаксичного аналізатора, при зчитуванні рядка в якому дескриптор лексеми має значення «е», читається наступний рядок. Тобто дана лексема не розглядається. Це приводить до виникнення ряду помилок після цієї лексеми. Тому при виправленні помилок необхідно враховувати цю особливість. 5 – Помилки в тілі циклу або main Інформація про виведені помилки включає в себе тип помилки та кількість помилок певного типу. 5. Контрольний приклад: Варіант вхідного файлу: void main( ) {int i,j , k = -10; //int ident10k ; int d id40 ; i = 4 2567; j =-3239 ; float fiden = - 22.38; float abcd123ef ; avcd1dd2 = 1259.38 ; for (id40 = 0; id40<> i ; i+++) {j = j;dfd=43;}; for (ident10k = 200; ident10k >= 100; ident10k--) {abcd123ef= abcd123ef; }; for(uhuh=2;j==-1;j++){j=fdj;int ddffgfsdqqw=34;}; } Результат виконання:  Висновок: Реалізована програма яка на основі результатів лексичного аналізу, виконує синтаксичний аналіз вхідного файлу. Спочатку відбувається лексичний прохід а потім синтаксичний. Після цього виконується вивід помилок. 6. Код програми: #include <stdio.h> #include <conio.h> #include <iostream.h> #include <string.h> #define path1 "c:/workpol/3kurs/sysprog/lab303/vhid.txt" #define path2 "c:/workpol/3kurs/sysprog/lab303/leksemy.txt" //#define path1 "p:/lab303/vhid.txt" //#define path2 "p:/lab303/leksemy.txt" //--------------------------FUNCTION PROTOTIPES-------------------------- void analize(FILE*fw,char *str); int setclas(char sym); void getlit(char *str,int* i,int* clasnum); void write(FILE*fw,char lekstype,int p,int q,char*str); void leksyka(void); //--------------------- void errors(void); void syntax(void); char getsym(void); //-------------------- void M(void); void T(void); void F(void); void P(void); void O(void); void I(void); void N(void); void D(void); //-----------------------GLOBAL VARIABLES----------------------------- char str[200]; //strichka. z vhidnogo faila zchytuem po strichci char sym; FILE *fr; //vhidny fail int maserror[6]; //masyv pomylok //------------------------------MAIN------------------------------------- void main(void) { clrscr(); leksyka(); syntax(); errors(); getch(); } //---------------------FUNCTION BODIES------------------------------------- void syntax(void) { fr=fopen(path2,"r"); sym=getsym(); M(); //provirka main fclose(fr); cout<<"\nSytaxsychny analiz vhidnogo potoku leksem ("<<path2<<")uspishno vykonanyy.\n"; } //------------------------------------------------------------------------- void errors(void) { if(maserror[0]>=1)cout<<"\nDopushceni pomylky v Main. Kilkist - "<<maserror[0]; if(maserror[1]>=1)cout<<"\nDopushceni pomylky v For. Kilkist - "<<maserror[1]; if(maserror[2]>=1)cout<<"\nDopushceni pomylky v Operacii prysvoennya. Kilkist - "<<maserror[2]; if(maserror[3]>=1)cout<<"\nDopushceni pomylky v Opysi zminnyh. Kilkist - "<<maserror[3]; if(maserror[4]>=1)cout<<"\nNa etapi syntaxsychnogo analizu vyyavleno pervyschenyya rozmiru identyfikatoriv abo cilyh chysel. Kilkist - "<<maserror[4]; if(maserror[5]>=1)cout<<"\nDopushceni pomylky v Tili main abo for. Kilkist - "<<maserror[5]; } //---------------------------------------------------------------------- void M(void) { int e; e=0; //pomylok nemae if((sym=='z')&&(str[2]=='v')) { sym=getsym(); if((sym=='z')&&(str[2]=='m')) { sym=getsym(); if((sym=='o')&&(str[2]=='(')) { sym=getsym(); if((sym=='z')&&(str[2]=='v')) { sym=getsym(); if((sym=='o')&&(str[2]==')')) { sym=getsym(); if((sym=='o')&&(str[2]=='{')) { sym=getsym(); T(); if((sym=='o')&&(str[2]=='}')) { //sym=getsym(); }else e=1; }else e=1; }else e=1; } else { if((sym=='o')&&(str[2]==')')) { sym=getsym(); if((sym=='o')&&(str[2]=='{')) { sym=getsym(); T(); if((sym=='o')&&(str[2]=='}')) { //sym=getsym(); }else e=1; }else e=1; }else e=1; }; }else e=1; }else e=1; }else { if((sym=='z')&&(str[2]=='m')) { sym=getsym(); if((sym=='o')&&(str[2]=='(')) { sym=getsym(); if((sym=='z')&&(str[2]=='v')) { sym=getsym(); if((sym=='o')&&(str[2]==')')) { sym=getsym(); if((sym=='o')&&(str[2]=='{')) { sym=getsym(); T(); if((sym=='o')&&(str[2]=='}')) { //sym=getsym(); }else e=1; }else e=1; }else e=1; } else { if((sym=='o')&&(str[2]==')')) { sym=getsym(); if((sym=='o')&&(str[2]=='{')) { sym=getsym(); T(); if((sym=='o')&&(str[2]=='}')) { //sym=getsym(); }else e=1; }else e=1; }else e=1; }; }else e=1; }else e=1; }; sym=getsym(); maserror[0]+=e; } //---------------------------------------------------------------------- void T()//tilo obovyazkovo v {} { while( (!feof(fr)) && (str[2]!='}') ) { if(maserror[5]>10000){cout<<"\nPomylka programy abo nadto velyka kilkist pomylok...";break;}; if((sym!='f')&&(sym!='i')&&(sym!='t')&&(sym!='a')){maserror[5]+=1;sym=getsym();}; if(sym=='f') { F(); }; if(sym=='i') { P(); }; if((sym=='t')||(sym=='a')) { O(); }; } } //------------------------------------------------------------------------ void F(void) { int e; e=0; if(sym=='f') { sym=getsym(); if((sym=='o')&&(str[2]=='(')) { sym=getsym(); I(); if((sym=='o')&&(str[2]==')')) { sym=getsym(); if((sym=='o')&&(str[2]=='{')) { sym=getsym(); T(); if((sym=='o')&&(str[2]=='}')) { sym=getsym(); if((sym=='o')&&(str[2]==';')) {} else e=1; } else e=1; } else { e=1; } } else e=1; } else e=1; } else e=1; if(e==0){sym=getsym();}; maserror[1]+=e; } //----------------------------------------------------------------------- void P(void) { int e=0; if(sym=='i') { sym=getsym(); if(sym=='=') { sym=getsym(); if(sym=='-'){sym=getsym();}; //neobhidno shob obiyty - sho stoit pered cilym chyslom if((sym=='i')||(sym=='d')||(sym=='c')) { sym=getsym(); if((sym=='o')&&(str[2]==';')){} else e=1; } else e=1; } else e=1; } else e=1; maserror[2]+=e; while(str[2]!=';'){sym=getsym();};//vse sho do ; ye pomylkove sym=getsym(); } //------------------------------------------------------------------------ void O(void) { int e=0; if((sym!='t')&&(sym!='a'))e=1; else { if(sym=='t') { sym=getsym(); if(sym=='i') { sym=getsym(); if(sym=='=') { sym=getsym(); if(sym=='-'){sym=getsym();}; //neobhidno shob obiyty - sho stoit pered cilym chyslom if((sym=='i')||(sym=='c')) { sym=getsym(); } else e=1; } else { while((sym=='o')&&(str[2]==',')) { e=1; sym=getsym(); if(sym=='i') { sym=getsym(); if(sym=='=') { sym=getsym(); if(sym=='-'){sym=getsym();}; //neobhidno shob obiyty - sho stoit pered cilym chyslom if((sym=='i')||(sym=='c')) { sym=getsym(); if((sym=='o')&&(str[2]==';')) { e=0; break; }; } else e=1; } else { if((sym=='o')&&(str[2]==';')) { e=0; break; }; }; } else e=1; }//while }; if(str[2]!=';')e=1; } else e=1;//yaksho ne identyf }; if(sym=='a') { sym=getsym(); if(sym=='i') { sym=getsym(); if(sym=='=') { sym=getsym(); if(sym=='-'){sym=getsym();}; //neobhidno shob obiyty - sho stoit pered cilym chyslom if((sym=='i')||(sym=='d')) { sym=getsym(); } else e=1; } else { while((sym=='o')&&(str[2]==',')) { e=1; sym=getsym(); if(sym=='i') { sym=getsym(); if(sym=='=') { sym=getsym(); if(sym=='-'){sym=getsym();}; //neobhidno shob obiyty - sho stoit pered cilym chyslom if((sym=='i')||(sym=='d')) { sym=getsym(); if((sym=='o')&&(str[2]==';')) { e=0; break; }; } else e=1; } else { if((sym=='o')&&(str[2]==';')) { e=0; break; }; }; } else e=1; }//while }; if(str[2]!=';')e=1; } else e=1; }; };//else maserror[3]+=e; while(str[2]!=';'){sym=getsym();};//vse sho do ; ye pomylkove sym=getsym(); } //------------------------------------------------------------------------ void I(void) { int e=1; if((sym=='t')||(sym=='a')) { e=0; O(); N(); D(); if((sym=='p')||(sym=='m'))sym=getsym(); }; if(sym=='i') {e=0; P(); N(); D(); if((sym=='p')||(sym=='m'))sym=getsym(); }; if(str[2]==')'){e=0;} else {e=1;while(str[2]!=')'){sym=getsym();};}; //shob mogna bulo dali prodovguvaty maserror[1]+=e; } //------------------------------------------------------------------------ void N(void) { int e=0; if(sym=='i') { sym=getsym(); if((sym=='s')||(sym=='n')||(sym=='t')) { sym=getsym(); if(sym=='-'){sym=getsym();}; if((sym=='i')||(sym=='d')||(sym=='c')) { sym=getsym(); if((sym=='o')&&(str[2]==';')){} else e=1; } else e=1; } else e=1; } else e=1; maserror[1]+=e; sym=getsym(); } //------------------------------------------------------------------------- void D(void) { int e=0; if(sym=='i') { sym=getsym(); if((sym=='p')||(sym=='m')){} else e=1; } else e=1; maserror[1]+=e; } //----------------------------------------------------------------------- char getsym(void) { char sym; fgets(str,200,fr); //chytaem strichku sym=str[0]; //chytaem leksemu if(sym=='e'){fgets(str,200,fr);sym=str[0];}; return sym; } //-------------------------------------------------------------------------- void leksyka (void) { FILE *fr; //vhidny fail FILE *fw; //vyhidny fail char str[200]; //strichka. z vhidnogo faila zchytuem po strichci fr=fopen(path1,"r"); fw=fopen(path2,"w"); while(!feof(fr)) //poky ne kinec vhidnogo faila { fgets(str,200,fr); //chytaem strichku analize(fw,str); //analizuem ii. fw peredaem dlya zapysu v vyhidny fail } fclose(fr); fclose(fw); cout<<"Leksychny analiz vhidnogo faylu ("<<path1<<")uspishno vykonanyy.\nResultat u faili("<<path2<<")\n"; } //---------------------------------------------------------------------- void analize(FILE*fw,char *str) //analiz strichky str. zapys u fail fw leksem { char lekstype; //typ leksemy char leksvalue[20]; int p,q; //pozyciya pochatku i kincya leksemy int clasnum; char sym; //symvol yaky zchytaly p=0; //nomer pozycii - pochatku leksemy int i=0; //lichylnyk - probig po strichci while(str[i]!='\0') //poky ne kinec ryadka { if((str[i]==' ')||(str[i]=='\t')){i++;}; //probil i tab propuskaem getlit(str,&i,&clasnum); //berem i-tyy symvol.daem yomu nomer klasu. i++ switch (clasnum) //cey symvol vyznachae: { case 1: {lekstype='i';p=i;q=i; //identyficator do //poky bukva,cyfra to ce identyf. { getlit(str,&i,&clasnum); q++; //naroschuvannya dovgyny } while((clasnum==1)||(clasnum==2)); i--; write(fw,lekstype,p,q,str);break; //zapys v fw leksemy typu lekstype, }; //dovgynou q-p pochynayuchy z p-yi case 2: {lekstype='c';p=i;q=i+1; //cile chyslo //pozycii strichky str, shco analizuetsya getlit(str,&i,&clasnum); if(clasnum==8){lekstype='d';getlit(str,&i,&clasnum);}; //yakshco . to diysne while(clasnum==2) { getlit(str,&i,&clasnum); if(clasnum==8){lekstype='d';q++;getlit(str,&i,&clasnum);}; //yakshco . to diysne q++; }; i--; write(fw,lekstype,p,q,str);break; //zapys v fw leksemy typu lekstype, }; case 3: {lekstype='o';p=i;q=i+1;write(fw,lekstype,p,q,str);break;}; //odnosymvolni leksemy case 4: { //znak + odnosym leksem abo p-dvosymvolna increment int pr=0; lekstype='+';p=i;q=i+1; getlit(str,&i,&clasnum); if(clasnum==4){lekstype='p';pr=1;q++;write(fw,lekstype,p,q,str);}; if(pr==0){write(fw,lekstype,p,q,str);i--;}; break; }; case 5: { //znak - odnosym leksem abo m-dvosymvolna decrement int pr=0; lekstype='-';p=i;q=i+1; getlit(str,&i,&clasnum); if(clasnum==5){lekstype='m';pr=1;q++;write(fw,lekstype,p,q,str);}; if(pr==0){write(fw,lekstype,p,q,str);i--;}; break; }; case 6: { //znak / odnosym leksem abo propuskaem komentar int pr=0; lekstype='/';p=i;q=i+1; getlit(str,&i,&clasnum); if(clasnum==6) { while(str[i]!='\n'){i++;}; pr=1; }; if(pr==0){write(fw,lekstype,p,q,str);i--;}; break; }; case 7: { //znak <,> strogoi(s) abo <=,>= nestrogoi(n) nerivnosti int pr=0; lekstype='s';p=i;q=i+1; getlit(str,&i,&clasnum); if(clasnum==10){lekstype='n';pr=1;q++;write(fw,lekstype,p,q,str);}; if(pr==0){write(fw,lekstype,p,q,str);i--;}; break; }; case 8: { //krapka ne vvagaem shcho e chysla vydu .4598 i=strlen(str);puts("zustrilas krapka yaka ne ye oznakoyu diysnogo chysla. ignoruem ii");getch(); }; case 9: {break; }; case 10:{//lekstype='=';p=i;q=i+1;write(fw,lekstype,p,q,str);break;}; int pr=0; lekstype='=';p=i;q=i+1; getlit(str,&i,&clasnum); if(clasnum==10){lekstype='t';pr=1;q++;write(fw,lekstype,p,q,str);}; if(pr==0){write(fw,lekstype,p,q,str);i--;}; break; }; } } } //------------------------------------------------------------------------ void getlit(char *str,int* i,int* clasnum) //daem i-tu pozyciyu //i-tomu symvolu strichky str nadaem nomer yog klasu clasnum { char sym=str[*i]; *clasnum=setclas(sym); //vstanovluem klas symvolu sym=str[i] *i=*i+1; //nastupny budem chytaty } int setclas(char sym) //vstanovlennya do yakogo klasu nalegyt sym {int r=9; //inshi symvoly if((sym>='a')&&(sym<='z')||(sym>='A')&&(sym<='Z'))r=1; //bukvy if((sym>='0')&&(sym<='9'))r=2; //cyfry if((sym=='(')||(sym==')')||(sym==';')||(sym==',')||(sym=='{')||(sym=='}')||(sym=='*'))r=3; if(sym=='+')r=4; //odynychni leksemy if(sym=='-')r=5; if(sym=='/')r=6; if((sym=='<')||(sym=='>'))r=7; //znaky porivnyannya if(sym=='.')r=8; //des krapka. dlya float if(sym=='=')r=10; return r; } //-------------------------------------------------------------------- void write(FILE*fw,char lekstype,int p,int q,char*str) //zapys u file fw { //typ leksemy lekstype i ii znachennya yake pochynaetsya v p i mae //dovgynu q-p v strichci str char value[30]=""; //znachennya leksemy int k=q-p-1; //dovgyna leksemy for (int i=0;i<=k;i++,p++){value[i]=str[p-1];}; //formuem znachennya leksemy if(lekstype=='i'){ if(strcmp(value,"for")==0)lekstype='f'; if(strcmp(value,"main")==0)lekstype='z'; if(strcmp(value,"float")==0)lekstype='a'; if(strcmp(value,"int")==0)lekstype='t'; if(strcmp(value,"void")==0)lekstype='z'; } if(lekstype=='i'){ if(k>=9){lekstype='e';maserror[4]+=1;}; }; if(lekstype=='c'){ if(k>=5){lekstype='e';maserror[4]+=1;}; }; fprintf(fw,"%c\t%s\n",lekstype,value); //zapys u fail }
Антиботан аватар за замовчуванням

01.01.1970 03:01-

Коментарі

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

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

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

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

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

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

Admin

26.02.2023 12:38

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