Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конпект лекций по ТЯПиМТ.docx
Скачиваний:
207
Добавлен:
27.01.2015
Размер:
329.63 Кб
Скачать

13. Алгоритм синтаксического анализа по методу рекурсивного спуска.

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

Рассмотрим на примере грамматики упрощенного Паскаля. Грамматика упрощенного Паскаля имеет вид (продукции пронумерованы для справки):

1. <PROG>→program<PROGRAM-NAME>var<DEC-LIST>begin<STMT-

LIST>END.

2. <PROG-NAME> →id

3. <DEC-LIST>→ <DEC>|<DEC-LIST>;<DEC>

4. <DEC> →<ID-LIST>:<TYPE>

5. <TYPE> → integer

6. <ID-LIST> →id|<ID-LIST>, id

7. <STMT-LIST>→<STMT>|<STMT-LIST>;<STMT>

8. <STMT>→<ASSIGN>|<READ>|<WRITE>|<FOR>

9. <ASSIGN> →id:=<EXP>

10. <EXP> →<TERM>|<EXP>+<TERM>|<EXP> - <TERM>

11. <TERM>→ <FACTOR>|<TERM>*<FACTOR>|<TERM> div <FACTOR>

12. <FACTOR> →id|int|(EXP)

13. <READ> →read(<ID-LIST>)

14. <WRITE> →write(<ID-LIST>)

15. <FOR>→ for<INDEX-EXP> do <BODY>

16. INDEX-EXP>→ id:=<EXP> to <EXP>

17. <BODY>→ <STMT>|begin<STMT-LIST> end

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

1. <PROG>→program<PROGRAM-NAME>var<DEC-LIST>begin<STMT-

LIST>END.

2. <PROG-NAME> →id

3. <DEC-LIST>→ <DEC>|{;<DEC>}

4. <DEC> →<ID-LIST>:<TYPE>

5. <TYPE> → integer

6. <ID-LIST> →id|{, id}

7. <STMT-LIST>→<STMT>|{;<STMT>}

8. <STMT>→<ASSIGN>|<READ>|<WRITE>|<FOR>

9. <ASSIGN> →id:=<EXP>

10. <EXP> →<TERM>|{+<TERM>| - <TERM>}

11. <TERM>→ <FACTOR>|{*<FACTOR>| div <FACTOR>}

12. <FACTOR> →id|int|(EXP)

13. <READ> →read(<ID-LIST>)

14. <WRITE> →write(<ID-LIST>)

15. <FOR>→ for<INDEX-EXP> do <BODY>

16. INDEX-EXP>→ id:=<EXP> to <EXP>

17. <BODY>→ <STMT>|begin<STMT-LIST> end

Нотация в фигурных скобках означает, что конструкция в фигурных скобках может или быть пропущена или повторяться несколько раз.

Синтаксический разбор. Синтаксический разбор в этом случае состоит из отдельных процедур, которые должны быть заранее запрограммированы для каждого нетерминального символа определённого в грамматике. В данном случае их будет 17. Каждая процедура ищет в входном потоке лексем подстроку, которая начинается с текущей лексемы интерпретируемой данной процедурой. В процессе своей работы процедура может вызывать другие подобные процедуры или рекурсивно обращаться сама к себе для поиска других нетерминальных символов.

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

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

Пример рекурсивного спуска. Рассмотрим строку, начинающуюся с ключевого слова read, использую метод рекурсивного спуска. Обратимся к примеру программы, составленной на упрощенном Паскале. Строка номер 8:

read(value);

В этой строке 5 лексем : read, ( , value, ), ;

Первая лексема read. Поэтому должна быть процедура или функция с именем read. В качестве языка программирования программы синтаксического анализатора выберем С++.