Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Распознающие процедуры




Begin

Else begin

Repeat

Begin

Begin

Var

Const

EOT = chr(0); { Признак "конец текста" }

Ch: char; { Очередной символ }

Pos: integer; { Номер символа }

Взаимодействие с входным текстом будут выполнять процедуры ResetText — готовит входную цепочку к считыванию распознавателем, и NextCh — читает очередной символ входной цепочки, помещая его в переменную Ch.

Использование глобальных переменных в процедурах, вообще-то, плохая

практика. Хотя мы еще не начали обращаться к ch и Pos в процедурах распознавателя, но вот-вот сделаем это. Оправданием служит специфика задачи.

Синтаксический анализатор и компилятор — своеобразные программы, в которых используется не слишком много переменных. А в нашем анализаторе переменных будет и вовсе две — только что определенные Ch и Pos.

Их передача в процедуры через параметры загромоздила бы программу, в то время как обращение за очередным символом, например к процедуре Nextch, все равно выглядело бы всегда одинаково:

NextCh(Ch, Pos).

Предусмотрим чтение исходных данных (записи многочлена) из стандартного входного файла.

Сообщения распознавателя будут выводиться в стандартный выходной файл (т. е. на экран). В этом случае процедура, подготавливающая текст, запишется так:


 

{ Подготовить текст }

procedure ResetText;

WriteLn ('Введите многочлен от х с целыми коэфф-тами');

Pos:= 0;

NextCh; { Чтение первого символа }

end;

При чтении очередного символа будем игнорировать пробелы, считая их незначащими. Это позволит при записи исходного многочлена применять пробелы, например, для отделения одного слагаемого от другого.


procedure NextCh;

{ Читать следующий символ }

Pos:= Pos+1;

if not eoln then

Read(Ch)

ReadLn;

Ch:= EOT;

end;

until Ch <> ' ';

end;

Такой пропуск пробелов делает их допустимыми в любом месте записи многочлена. К примеру, такая строка должна теперь считаться правильной:

123х^4 + 567х + 89

Это не соответствует соглашениям современных языков программирования.

Более совершенное решение вопроса о пробелах будет рассмотрено в следующей главе, пока же примем простейший подход, который все же предпочтительней полного запрета пробелов.

Процедура, реагирующая на ошибку, тоже зависит от соглашений по вводу и выводу. Как мы уже условились, она будет выдавать сообщение на экран:

 

procedure Error(Message: string); { Ошибка }

{ Message - сообщение об ошибке }

WriteLn (' ^': Pos);

WriteLn('Синтаксическая ошибка: ', Message);

Halt; { Прекращение работы анализатора }

end;

Вывод знака ' ^' в позиции Pos позволяет указать стрелкой на символ, вызвавший ошибку. Диалог с анализатором может быть таким:

Введите многочлен от X с целыми коэфф-тами

2х + 1.2

^

Синтаксическая ошибка: Ожидается конец текста

Реакция программы в этом примере может показаться непонятной, хотя она совершенно корректна. Получение такого сообщения означает: «Если бы на этом месте запись многочлена закончилась, было бы синтаксически правильно. Но в указанном месте стоит неподходящий символ».

Понятно, что распознаватель не может знать наших желаний и содержательно реагировать на попытку записать вещественное число вместо целого.

 

 

Для каждого нетерминала грамматики многочленов, то есть для каждой синтаксической диаграммы (рис. 17-19) записываем одну распознающую процедуру.

Первой — процедуру для нетерминала «Многочлен» — начального нетерминала грамматики (рис. 17). Трудность, однако, состоит в том, что диаграмма на рис. 17 неудобна для программирования — она содержит цикл с выходом из середины, в то время как в Паскале такого цикла нет.

Заменим диаграмму эквивалентной, содержащей цикл с предусловием (с выходом в начале).

Рис.21 Преобразованная диаграмма «Многочлен»

Теперь не составляет труда записать распознающую процедуру, структура которой в точности повторяет структуру диаграммы: на диаграмме три последовательно соединенных участка — в процедуре три оператора, выполняемых один за другим: if, вызов процедуры Addend, цикл while.

procedure Polynom; { Многочлен }




Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 313; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.011 сек.