Файл: Конспект лекций введение.doc

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 07.11.2023

Просмотров: 78

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
сканировать входной текст до тех пор, пока следующая пара лексем не совпадёт с запятой и ид. Такая запись устраняет проблему рекурсии, а также решает вопрос выбора из двух альтернатив.

Грамматика языка, к которому принадлежит предложение, представленное на рис. 1, имеет вид, представленный на рис. 6.

<программа>  <имя программы> var <раздел переменных> begin <раздел операторов> end.

<имя программы>  ид

<раздел переменных>  <список переменных>:<тип>

<список переменных>  ид {, ид }

<тип>  integer

<раздел операторов> <оператор> {;<оператор>}

<оператор>  <присваивание>/<ввод>/<вывод>/<цикл>

<присваивание>  ид := <арифметическое выражение>

<арифметическое выражение>  <слагаемое> {+<слагаемое>}{-<слагаемое>}

<слагаемое>  <значение> {*<значение>} {div <значение>}

<значение>  ид/ конст/(<арифметическое выражение>)

<ввод>  read (<список переменных>)

<вывод>  write (<список переменных>)

<цикл>  for <выражение цикла> to <тело цикла>

<выражение цикла>  ид :=<арифметическое выражение> do <арифметическое выражение>

<тело цикла>  <оператор>/ begin <раздел операторов> end


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

Имеем предложение исходной программы: READ (a).

Тогда процедура разбора этого предложения может иметь вид:
procedure <ввод>;

begin

BP := false;

if t = read then

begin

перейти к следующей лексеме;

if t = ( then

begin

перейти к следующей лексеме;

if <список переменных> закончилась успешно then

if t = ) then


begin

BP := true;

перейти к следующей лексеме;

end; {if )}

end; {if (}

end; {if read}

if BP = true then успешное завершение

else неудачное завершение;

end;
В приведенной процедуре BP – вспомогательная переменная, а t- переменная, определяющая тип лексемы. Процедура, соответствующая нетерминальному символу <ввод> вызывает процедуру <список переменных>:
procedure <список переменных>;

begin

BP := false;

if t=ид then

begin

BP := true;

перейти к следующей лексеме;

while ( t = , ) and ( BP = true ) do

begin

перейти к следующей лексеме;

if t = ид then перейти к следующей лексеме

else BP := false;

end; {while}

if BP = true then успешное завершение

else неудачное завершение;

end;
На рис. 7 графически представлен процесс грамматического разбора методом рекурсивного спуска для предложения READ. На фрагменте а) изображен вызов процедуры <ввод>, которая обнаружила лексемы READ и ) во входном потоке (штриховая линия). На фрагменте б) процедура <ввод> вызывает процедуру <список переменных> (сплошная линия), которая обработала лексему ид. На фрагменте в) процедура <список переменных> закончила работу, передала управление процедуре <ввод> с признаком успешного завершения; процедура <ввод> обработала входную лексему ). На этом анализ входного предложения завершён.



Рис. 7
Приведём ещё один пример. Имеем предложение из исходной программы:



REZ := SUM DIV 100 – A * A

Представим алгоритмы разбора этого предложения методом рекурсивного спуска:
procedure <присваивание>

begin

BP := false;

if t = ид then

begin

перейти к следующей лексеме;

if t = := then

begin

перейти к следующей лексеме;

if <арифметическое выражение> завершилось

успешно then

BP := true;

end; {if :=}

end; {if ид.}

if BP = true then успешное завершение

else неудачное завершение;

end;

Процедура присваивание в процессе работы вызывает процедуру <арифметическое выражение>:
procedure арифметическое выражение;

begin

BP:=false;

if <слагаемое> завершилось успешно then

begin

BP:=true;

while (t = + или t = - ) and ( BP=true ) do

begin

Перейти к следующей лексеме;

if <слагаемое> завершилось неудачно then

BP:=false;

end; {while}

end; {if слагаемое}

if BP = true then успешное завершение

else неудачное завершение;

end;
Процедура <арифметическое выражение>, в соответствии с грамматикой вызывает процедуру <слагаемое>:

procedure <слагаемое> ;


begin

BP:=false;

if <значение> завершилось успешно then

begin

BP:=true;

while (t = * или t = div ) and ( BP=true ) do

begin

Перейти к следующей лексеме;

if <значение> завершилось неудачно then

BP:=false;

end; {while}

end; {if значение}

if BP=true then успешное завершение

else неудачное завершение;

end;
И, наконец, процедура <слагаемое> вызывает процедуру <значение>, которая распознает переменные, константы или вызывает процедуру <арифметическое выражение>. Алгоритм процедуры <значение> имеет вид:

procedure значение;

begin

BP:=false;

if t = ид или t = конст then

begin

BP:=true;

Перейти к следующей лексеме;

end {if ид или конст}

else

if t = ( then

begin

Перейти к следующей лексеме;

if <арифметическое выражение> завершилось

успешно then

if t = ) then

begin

BP:=true;

Перейти к следующей лексеме;

end; {if )}

end; {if (}

if BP = true then успешное завершение

else неудачное завершение;


end;
Графически разбор этого предложения методом рекурсивного спуска выглядит так:

  1. Вызывается процедура присваивание, которая обнаружила лексемы ид и := во входном потоке (рис. 8, а).

  2. Процедура <присв> вызывает процедуру <арифметическое выражение> (рис. 8. б)




Рис. 8



Рис. 9


  1. Процедура <арифметическое выражение> вызывает процедуру <слагаемое> (рис. 9, а).

  2. Процедура <слагаемое>. вызывает процедуру <значение>, которая обнаруживает лексему ид. Управление возвращается в процедуру <слагаемое> (рис. 9, б).

  3. Процедура <слагаемое> обнаруживает лексему div и вызывает процедуру <значение>, которая обнаруживает лексему конст. и передаёт управление в процедуру <слагаемое>, которая передаёт управление в процедуру <арифметическое выражение> (рис. 10, a).

  4. Процедура <арифметическое выражение> распознаёт лексему – , затем вызывает процедуру <слагаемое>, которая вызывает процедуру <значение>, которая распознаёт лексему ид и передаёт управление в процедуру <слагаемое> (рис. 10, б).

  5. Процедура <слагаемое> распознаёт лексему * , затем вызывает процедуру <значение>, которая распознаёт лексему ид. Следующая лексема читается в процедуре <значение>. Эта лексема не относится к данному предложению. Управление передаётся в процедуру <слагаемое>, которая формирует признак успешного завершения и передаёт управление в процедуру <арифметическое выражение>. Эта процедура, в свою очередь, успешно заканчивается и передаёт управление в процедуру <присваивание>, которая формирует признак успешного завершения. На этом разбор этого предложения заканчивается (рис. 11).