Язык оператора Язык оператора присваивания FORTRAN Идентификатор = арифметическое выражение Арифметическое выражение – выражение, содержащее в себе операции *, /, +, **, а также () . ** – возведение в степень. Грамматика языка G[<ОПЕРАТОР>]: 1. <ОПЕРАТОР> ® <ИДЕНТИФИКАТОР> = <ВЫРАЖЕНИЕ> 2. <ВЫРАЖЕНИЕ> ®
Тз <ВЫРАЖЕНИЕ>+Т з <ВЫРАЖЕНИЕ>- Т 3. Т ® О з Т* О з Т/О к Т* * О 4. О ® (<ВЫРАЖЕНИЕ>) з <ИДЕНТИФИКАТОР> з <ДБЗ> 5. <ИДЕНТИФИКАТОР> ® Б{Б з Ц}[L ] 6. <ДБЗ> ® Ц{Ц}[. Ц{Ц}][L ] Т – ТЕРМ О – ОПЕРАНД Б – БУКВА Ц – ЦИФРА ДБЗ – ДРОБНОЕ
БЕЗ ЗНАКА L – КОНЕЦ СТРОКИ (пусто) ** – ВОЗВЕДЕНИЕ В СТЕПЕНЬ Классификация грамматики Данная грамматика G[<ОПЕРАТОР>], согласно классификации Хомского, является контекстно-свободной, так как правая часть каждой редукции начинается либо с терминального символа, либо с нетерминального, принадлежащего объединённому словарю. A ® a, AО V n , aО V*. Грамматика
G[<ОПЕРАТОР>] не является автоматной, так как не все её редукции начинаются с терминального символа. По этой же причине данная грамматика не является S - грамматикой. Метод анализа Для данной грамматики реализован разбор методом рекурсивного спуска, поскольку она относится к классу контекстно-свободных. Идея метода состоит в том, что каждому нетерминальному символу ставится в соответствие определённая программная единица (функция) , которая распознаёт цепочку, порождаемую
этим нетерминалом. Эти процедуры и функции вызываются в соответствии с правилами грамматики и иногда вызывают сами себя. Данный метод реализован на языке C++, поскольку он обладает рекурсивными возможностями. Диагностика и нейтрализация ошибок Для данной грамматики производится только диагностика и нейтрализация ошибок. Исправление ошибок не производится. Нейтрализация ошибок осуществляется по методу
Айронса, то есть, спускаясь по синтаксическому дереву без возврата по контексту, при обнаружении тупиковой ситуации отбрасываются те литеры (символы) , которые привели в тупиковую ситуацию и разбор продолжается. Тестирование 12=1 Имя идентификатора должно начинаться с буквы. s223=(s) +(((d) ) ) ОШИБОК НЕТ sdsds=skshj**mxnx dc Пропущена операция или неправильное имя идентификатора. ;;=0 Имя идентификатора должно начинаться с буквы. Идентификатор состоит только из букв или цифр. as=115/3
ОШИБОК НЕТ 32=-*= Имя идентификатора должно начинаться с буквы. Пропущен идентификатор или число. Пропущен идентификатор или число. Неизвестная операция или неправильное имя идентификатора. Пропущен идентификатор или число. sdvsf+gsdf=0 Слевa от '='операций быть не может. jhg=321+321/54*4(s+25) Пропущена операция или неправильное имя идентификатора. d56gfsdfg=(ld+5
Длина имени идентификатора не должна быть больше 6. Отсутствует ') Листинг программы. // SP_KURS. CPP: КУРСОВАЯ РАБОТА ПО СИСТЕМНОМУ ПРОГРАММИРОВАНИЮ.// // ОПЕРАТОР ПРИСВАИВАНИЯ ЯЗЫКА "ФОРТРАН" // // имя файла test #include<process. h> #include<stdio. h> #include<string. h> #include<ctype. h> #include<stdlib. h> #include<
conio. h> #include<io. h> #defineUP 72/* стрелка вверх */ #define DOWN80/* стрелка вниз */ #defineEXIT'33'/* Esc */ #define END 100 enum LEX{ERROR, CBZ, ID, PLUS, MIN, DIV, MUL, STEP, SKL, SKR, RAV, _EOLN _EOF_}; int next, number=0, num=0, temp, line=1, err[80], sum; int mistake[15][80], ofset=0; char cordinat[80][80], filename[80]; char* type_mis[]={"
ОШИБОК НЕТ ", "Имя идентификатора должно начинаться с буквы. ", "Идентификатор состоит только из букв или цифр. ", "Слевa от '='операций быть не может. ", "Неизвестная конструкция (нет '=') . ", "Длина имени идентификатора не должна быть больше 6. ", "Отсутствует ') ", "Неизвестная операция или неправильное имя идентификатора. ", "
Пропущен идентификатор или число. ", "Отсутствует '( ", "Пропущена операция или неправильное имя идентификатора. ", "Отсутствует выражение (А=?) . ", "Отсутствует идентификатор(? =B) . ", " ", }; const int X1=2, Y1=20, X2=80, Y2=25; const int YWINDOW=Y2-Y1+1; void viewwin(int, int) ; void putmistake(int) ; intMENU(char *) ; void identif() ;
void ravno() ; void expr(void) ; void term(void) ; void operand(void) ; int scaner(void) ; void error(int) ; void makefile(void) ; FILE *in, *out; void main(void) {strcpy(cordinat[0], " ") ; mistake[0][0]=13;mistake[0][1]=END; clrscr() ; printf("Введите имя обрабатываемого файла: ") ; gets(filename) ; if((in=fopen(filename, "r") ) ==NULL) {printf(" ОШИБКА ФАЙЛ С ТАКИМ ИМЕНЕМ НЕ СУЩЕСТВУЕТ ") ; exit(-1) ; } while(! feof(in) ) {ravno() ; mistake[line][ofset]=END;
line++; ofset=0; } fcloseall() ; makefile() ; num=0; window(1,1,80,25) ; clrscr() ; gotoxy(1,1) ; MENU(" ОПЕРАТОР ПРИСВАИВАНИЯ ЯЗЫКА /""ФОРТРАН/"" ") ; clrscr() ; window(1,1,80,25) ; clrscr() ; printf(" ВСЕ ОШИБКИ ХРАНЯТЬСЯ В ФАЙЛЕ /""ERRORS. TXT/"" ") ; printf(" НАЖМИТЕ ЛЮБУЮ
КЛАВИШУ ") ; fcloseall() ; exit(1) ; } void ravno() {temp=0; num=0; sum=0; next=scaner() ; if((next! =_EOLN_) &&(next! =_EOF_) ) {if(next==RAV) {error(12) ; err[0]=END; } else identif() ; if(next! =RAV) error(4) ; else {temp=1; if(err[0]! =END) {if(err[0]! =ID) error(1) ; for(int i=1;i<sum;i++) {next=err[i]; identif() ; } } temp=2; next=scaner() ; if((next==_EOF_) ||(next==_EOLN_) ) error(11) ; else {while(1) {expr() ; if(next==SKL) error(10) ; else {if(next==SKR) {error(9) ; next=scaner() ;
} if(next==ID) {error(10) ; next=scaner() ; } if(next==ERROR) error(7) ; if((next==_EOF_) ||(next==_EOLN_) ) break; next=scaner() ; }//else } //while } //else }//else }//if else mistake[line][ofset++]=13; } int scaner(void) {int liter; liter=fgetc(in) ; num++; if((isspace(liter) ) ||(liter==' ') ) {while((isspace(liter) ) ||(liter==' ') ) {if(liter==' ') return(11) ; liter=fgetc(in) ; } } if(isdigit(liter) ) {while(isdigit(liter) ) {liter=fgetc(in) ; num++; } if(liter== ') {liter=fgetc(in) ; while(isdigit(liter) ) {liter=fgetc(in)
; num++; } ungetc(liter, in) ; num ; return(1) ; } else {if(isalpha(liter) ) {number=0; while(isalnum(liter) ) {number++; num++; liter=fgetc(in) ; } ungetc(liter, in) ; num ; return(2) ; } else switch(liter) {case '+': num=0;return(3) ; case : num=0;return(4) ; case '/': num=0;return(5) ; case '*': num=0; if((liter=fgetc(in) ) =='*') return(7) ; else {ungetc(liter, in) ; return(6) ; } case '(': return(8) ; case ') ': return(9) ; case '=': return(10) ; case ' ': return(11) ; case
EOF: return(12) ; default: return(0) ; } }//else } // РАСПОЗНАЕТ ОШИБКИ В ИДЕНТИФИКАТОРЕ. void identif(void) {if(temp==0) {while((next! =RAV) &&(next! =_EOLN_) &&(next! =_EOF_) ) {err[sum]=next; sum++; next=scaner() ; } } if(temp==1) {if((next! =CBZ) &&(next! =ID) ) {if(next==ERROR) error(2) ; else error(3) ; } number=num-1; num=0; } if(number>6) error(5) ; } // НЕТЕРМИНАЛ "O" <
Операнд> void operand() {if(next==SKL) {next=scaner() ; expr() ; if(next! =SKR) error(6) ; else next=scaner() ; } else {if(next==ID) {identif() ;next=scaner() ;} else {if(next! =CBZ) {if((next! =_EOLN_) &&(next! =_EOF_) ) {if(next==ERROR) {error(7) ; next=scaner() ; operand() ; } else {if(next==RAV) error(7) ; else error(8) ; } } else error(8) ; } else next=scaner() ; }//else }//else } // НЕТEРМИНАЛ "Е" <Выражение> void expr(void) {term() ; while((next==PLUS) ||(next==MIN)
) {next=scaner() ; expr() ; } } // НЕТЕРМИНАЛ "T" <Терм> void term(void) {operand() ; while((next==DIV) ||(next==MUL) ||(next==STEP) ) {next=scaner() ; term() ; } } void error(int choice) {switch(choice) {case 1: mistake[line][ofset++]=1; break; case 2: mistake[line][ofset++]=2; break; case 3: mistake[line][ofset++]=3; break; case 4: mistake[line][ofset++]=4; break; case 5: mistake[line][ofset++]=5; break; case 6: mistake[line][ofset++]=6; break; case 7: mistake[line][ofset++]=7;
break; case 8: mistake[line][ofset++]=8; break; case 9: mistake[line][ofset++]=9; break; case 10: mistake[line][ofset++]=10; break; case 12: mistake[line][ofset++]=12; break; case 11: mistake[line][ofset++]=11; break; default: break; } } void makefile(void) {char *s; int num_str=0, oftemp, rep; if((out=fopen("errors. txt", "w") ) ==NULL) {printf(" ОШИБКА ФАЙЛ С ТАКИМ ИМЕНЕМ НЕ СУЩЕСТВУЕТ ") ; exit(-1) ; } if((in=fopen(filename, "r") ) ==NULL)
{printf(" ОШИБКА ФАЙЛ НЕЛЬЗЯ ОТКРЫТЬ ДЛЯ ЗАПИСИ ") ; exit(-1) ; } while(num_str++, fgets(s, 80, in) ! =NULL) {fputs("\ \", out) ; fputc(' out) ; fputs(s, out) ; fputc(' out) ; rep=strlen(s) ; s[rep-1]= ; strcpy(cordinat[num_str], s) ; if((oftemp=mistake[num_str][0]) ==END) {fputs(type_mis[0], out) ; fputc(' out) ; } else {for(int k=0;mistake[num_str][k]! =END;k++) {oftemp=mistake[num_str][k]; fputs(type_mis[oftemp], out) ; fputc(' out) ; } } } fputs("\ \", out) ; fputc(' out) ; fcloseall()
; } // MENU intMENU(char *s) {intdy, n; dy=line-1; textbackground(WHITE) ; textcolor(YELLOW) ; window(1,1,80,25) ; clrscr() ; gotoxy(2,1) ; cprintf(" SDenis ") ; gotoxy(2,2) ; cputs(s) ; gotoxy(2,3) ; cprintf("Используйте курсор вверх/вниз для выбора просматриваемой строки. ") ; gotoxy(2,4) ; cprintf("<ENTER> - для просмотра ошибок в строке(строка выделяется) . ") ; gotoxy(2,5) ; cprintf("<ESC> - выход. ") ; gotoxy(2,6) ; textbackground(WHITE) ; textcolor(RED) ; cprintf("
* ОШИБКИ В СТРОКАХ * ") ; textbackground(WHITE) ; textcolor(YELLOW) ; gotoxy(2,19) ; cprintf("* СТРОКИ ВАШЕГО ФАЙЛА * ") ; window(X1, Y1, X2, Y2) ; textcolor(BLACK) ; viewwin(0, YWINDOW) ; n = 0; int Y=1; while(1) {char c; gotoxy(1, Y) ; textbackground(GREEN) ; cprintf("%s", cordinat[n]) ; textbackground(WHITE) ; c=(c=getch() ) ==0? c=getch() : c; gotoxy(1,
Y) ; cprintf("%s", cordinat[n]) ; switch (c) {caseEXIT: return(-1) ; case' ': /*enter*/ window(2,7,80,18) ; clrscr() ; putmistake(n) ; window(X1, Y1, X2, Y2) ; break; caseUP: if (Y==1) viewwin(n>0? n-1: n, YWINDOW) ; else Y ; if(n>0) n ; break; caseDOWN: if(Y==YWINDOW) viewwin((n==dy? n: n+1) -YWINDOW+1, YWINDOW) ; else Y++; if(n+1==dy) {n=0; Y=1; viewwin(n, YWINDOW) ; } else n++; break; } } } void viewwin(int num, int numline) {clrscr() ; for(int a=0;a<
numline;a++) {gotoxy(1, a+1) ; cprintf("%s", cordinat[num++]) ; } } void putmistake(int n) {int offtemp, x=1, y=1; if((offtemp=mistake[n][0]) ==END) {cprintf("%s", type_mis[0]) ; } else {for(int k=0;mistake[n][k]! =END;k++) {offtemp=mistake[n][k]; if(offtemp==13) cprintf("%s ", type_mis[offtemp]) ; else {cprintf("%d. %s ", k+1, type_mis[offtemp]) ; x++; y++; gotoxy(x, y) ; } } } } Литература. 1. Курс лекций по системному программированию.
2. Герберт Шилдт “C для профессиональных программистов” . 3. В. Н. Лебедев “Введение в системы программирования”
! |
Как писать рефераты Практические рекомендации по написанию студенческих рефератов. |
! | План реферата Краткий список разделов, отражающий структура и порядок работы над будующим рефератом. |
! | Введение реферата Вводная часть работы, в которой отражается цель и обозначается список задач. |
! | Заключение реферата В заключении подводятся итоги, описывается была ли достигнута поставленная цель, каковы результаты. |
! | Оформление рефератов Методические рекомендации по грамотному оформлению работы по ГОСТ. |
→ | Виды рефератов Какими бывают рефераты по своему назначению и структуре. |