Автор работы: Пользователь скрыл имя, 17 Апреля 2013 в 10:55, курсовая работа
Прогресс компьютерных технологий определил процесс появления новых разнообразных знаковых систем для записи алгоритмов – языков программирования. Смысл появления такого языка – оснащенный набор вычислительных формул дополнительной информации, превращает данный набор в алгоритм. Язык программирования служит двум связанным между собой целям: он дает программисту аппарат для задания действий, которые должны быть выполнены, и формирует концепции, которыми пользуется программист, размышляя о том, что делать. Первой цели идеально отвечает язык, который настолько "близок к машине", что всеми основными машинными аспектами можно легко и просто оперировать достаточно очевидным для программиста образом. Второй цели идеально отвечает язык, который настолько "близок к решаемой задаче", чтобы концепции ее решения можно было выражать прямо и коротко.
Введение. 2
Особенности языков программирования. 4
Понятие грамматики и формальное определение. Формула Бэкуса-Наура. 6
Общая схема распознавателя. 9
Основные компоненты распознавателя. 11
Классификация распознавателей по виду их компонентов. 12
Задача разбора 16
Теоретическая справка. 17
Составление формальной грамматики. 18
Построение конечного распознавателя. 19
Программное моделирование работы конечного распознавателя 20
Реализация алгоритма средствами ООП. 23
Список используемой литературы 38
Конфигурация называется заключительной, если УУ находится в одном из множества заключительных состояний, а входная головка обозревает правый концевой маркер или сошла с ленты.
Распознаватель допускает входную цепочку символов, если, находясь в начальной конфигурации, в которой данная цепочка записана на входной ленте, он может проделать конечную последовательность шагов, заканчивающуюся одной из его заключительных конфигураций.
Некоторые виды распознавателей
могут из начальной конфигурации
проделать различные
Язык, определяемый распознавателем – это множество всех цепочек, которые допускает этот распознаватель.
Основные компоненты распознавателя.
Работа распознавателя состоит
из последовательности тактов. В начале
каждого такта состояние
Конфигурация распознавателя определяется следующими параметрами:
· содержимое входной цепочки символов и положение считывающей головки в ней;
· состояние УУ;
· содержимое внешней памяти.
Для распознавателя всегда задается определенная конфигурация, которая считается начальной конфигурацией. В начальной конфигурации считывающая головка обозревает первый символ входной цепочки, УУ находится в заданном начальном состоянии, а внешняя память либо пуста, либо содержит строго определенную информацию.
Кроме начального состояния для распознавателя задается одна или несколько конечных конфигураций. В конечной конфигурации считывающая головка, как правило, находится за концом исходной цепочки (часто для распознавателей вводят специальный символ, обозначающий конец входной цепочки).
Распознаватель допускает
входную цепочку символов, если,
находясь в начальной конфигурации
и получив на вход эту цепочку,
он может проделать
Классификация распознавателей по виду их компонентов.
Распознаватели можно классифицировать в зависимости от вида составляющих их компонентов: считывающего устройства, устройства управления (УУ) и внешней памяти.
По видам считывающего устройства распознаватели могут быть двусторонние и односторонние.
Односторонние распознаватели
допускают перемещение
Двусторонние распознаватели допускают, что считывающая головка может перемещаться относительно ленты входных символов в обоих направлениях: как вперед, от начала ленты к концу, так и назад, возвращаясь к уже прочитанным символам.
По видам устройства управления распознаватели бывают детерминированные и недетерминированные.
Распознаватель называется
детерминированным в том
· распознаватели без внешней памяти;
· распознаватели с ограниченной внешней памятью;
· распознаватели с неограниченной внешней памятью.
У распознавателей без
внешней памяти эта память полностью
отсутствует. В процессе их работы используется
только конечная память устройства управления,
доступ к внешней памяти не выполняется.
Для распознавателей с
Для контекстно-свободных
языков (тип 2) распознавателями являются
односторонние
Для регулярных языков (тип 3) распознавателями являются детерминированные автоматы без внешней памяти — конечные автоматы (КА). Это очень простой тип распознавателя, который всегда предполагает линейную зависимость времени на разбор входной цепочки от ее длины. Кроме того, конечные автоматы имеют важную особенность: любой недетерминированный КА всегда может быть преобразован в детерминированный. Простота и высокая скорость работы распознавателей определяют широкую область применения регулярных языков.
Задача разбора
Грамматики и распознаватели – два независимых метода, которые реально могут быть использованы для определения языка. Однако при разработке компилятора для некоторого языка программирования возникает задача, которая требует связать между собой эти два метода.
Разработчики компилятора имеют дело с конкретным языком программирования, т.е. грамматика языка уже известна. Задача разработчиков состоит в построении распознавателя данного языка, который явится основой синтаксического анализатора в компиляторе.
Итак, задача разбора формулируется следующим образом: на основе имеющейся грамматики некоторого языка необходимо построить распознаватель для этого языка. Заданная грамматика и распознаватель должны быть эквивалентны, т.е. определять один и тот же язык.
В общем виде эта задача может быть решена не для всех типов языков, хотя для КС и регулярных языков задача разбора разрешима и существуют некоторые формальные методы ее решения.
Компилятор должен не просто
дать ответ, принадлежит ли входная
цепочка данному языку, но и определить
ее смысл. Фактически работа распознавателя
в составе компилятора
Теоретическая справка.
Недетерминированный конечный автомат (НКА) - это пятерка M = (Q, T, D, q0, F), где
Работа конечного автомата представляет
собой некоторую
|
Недетерминизм автомата
Важным частным случаем
Конечный автомат – это модель устройства с конечным числом состояний, которое отличает правильно образованные, или «допустимые» цепочки, от «недопустимых».
Составление формальной грамматики.
Фраза языка представляет собой список, поэтому из начального символа грамматики должен выводиться список:
R0: <предложение> ::==< фраза>#
R1: <фраза> ::==< фраза>/< составное имя> | <идентификатор>
R2: <составное имя> ::==<составное
имя>.<идентификатор>|<
R3: <идентификатор>::==<
R4: <начальный символ>::==<буква>|<знак подчёркивания>
R5: <допустимый символ> :=:=<буква>|<цифра>|<знак подчёркивания>
R6:<буква>::==a|b|c|d|e|f|g|h|
R7: <цифра>::==0|1|2|3|4|5|6|7|8|
R8:<знак подчёркивания>::==_
Таким образом, требуемую грамматику можно описать следующей структурой:
Построение конечного распознавателя.
Между конечными
автоматами и автоматными грамматиками
существует тесная связь: класс языков,
допускаемых конечными
Для построения конечного
автомата составленную грамматику путем
введения дополнительных состояний
надо преобразовать к автоматному
виду, в результате получится следующая
таблица переходов:
Программное моделирование работы конечного распознавателя.
#include "iostream.h"
#include "stdio.h"
#include "conio.h"
int main()
{ int i,j,kol,tsost,slsost,tsymb;
int tabl[9][40]={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};printf("matrica\n");
for (i=0;i<9;i++) {for (j=0;j<40;j++) printf("%4d",tabl[i][j]); printf("\n");};
char ch, inpstr[80] ;
printf("\n ENTER STRING ");
i=0;
while ((ch=getch()) !=13 && i<80)
{putch(ch);
inpstr[i++]=ch;}
inpstr[i]='\0';
kol=i-1;
printf("\n input string:");
printf(inpstr);
printf("\n");
tsost=2;
for (i=0;i<=kol;i=i+1)
{ tsymb=inpstr[i];
switch (tsymb)
{ case '0': slsost=tabl[tsost][0]; break;
case '1': slsost=tabl[tsost][1]; break;
case '2': slsost=tabl[tsost][2]; break;
case '3': slsost=tabl[tsost][3]; break;