Главная страница

Курсовая Лексический анализатор. Краткий курс лекций. Курс лекций по спецкурсу Методы трансляции


Скачать 0.64 Mb.
НазваниеКурс лекций по спецкурсу Методы трансляции
АнкорКурсовая Лексический анализатор
Дата29.12.2019
Размер0.64 Mb.
Формат файлаdoc
Имя файлаКраткий курс лекций.doc
ТипКурс лекций
#102547
страница9 из 19
1   ...   5   6   7   8   9   10   11   12   ...   19
Алгоритм грамматического разбора в грамматиках с простым предшествованием


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

Пусть необходимо выполнить грамматический разбор для некоторой входной строки терминальных символов t1...tn. Строка ограничивается с двух сторон терминальным символом ┴, при этом считается, что для любого символа p: ┴ < p и p > ┴.

Формируется стек S, элементы которого si – терминальные и нетерминальные символы. В стек заносится символ левый ограничитель строки – ┴ (s1=┴). Далее, на каждом промежуточном этапе действия определяются состоянием стека – s1...sk и остатком входного предложения – tj...tn┴. Проверяется отношение между верхним элементом стека sk и очередным символом строки tj. Если отношения нет, то входная строка некорректна. Если skj или sk=tj, то tj заносится в стек. Если sk>tj, то отыскивается множество символов в вершине стека, удовлетворяющих отношению: si-1i=si+1=...=sk>tj. Элементы si...sk принадлежат одной основе и могут быть свернуты по некоторому правилу грамматики: U → si...sk. Выполняется свертка: отыскивается это правило, символы si...sk удаляются из стека, а U – заносится. Процесс повторяется: символ U, как верхний элемент стека, сравнивается с tj и т.д.

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

Пример разбора предложения ┴b((aa)a)b┴ :

Стек │ Остаток │ Отношение │ Основа │ Правило

--------│------------│-----------│---------------│---------

┴ │ b((aa)a)b┴ │ ┴ < b │ │

┴b │ ((aa)a)b┴ │ b < ( │ │

┴b( │ (aa)a)b┴ │ ( < ( │ │

┴b(( │ aa)a)b┴ │ ( < a │ │

┴b((a │ a)a)b┴ │ a > a │ ( < a > a │ M → a

┴b((M │ a)a)b┴ │ M = a │ └─┘ │

┴b((Ma │ )a)b┴ │ a = ) │ ┌─────┐ │

┴b((Ma) │ a)b┴ │ ) > a │ ( < M=a=) > a │ N → Ma)

┴b((N │ a)b┴ │ N > a │ ( < (=N > a │ M → (N

┴b(M │ a)b┴ │ M = a │ └───┘ │

┴b(Ma │ )b┴ │ a = ) │ ┌─────┐ │

┴b(Ma) │ b┴ │ ) > b │ ( < M=a=) > b │ N → Ma)

┴b(N │ b┴ │ N > b │ b < (=N > b │ M → (N

┴bM │ b┴ │ M = b │ └───┘ │

┴bMb │ ┴ │ b > ┴ │ ┴ < b=M=b > ┴ │ Z → bMb

┴Z │ ┴ │ конец │ └─────┘ │

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

Рассмотрим пример:

S → T | S+T

T → ид | T*ид

Так как существует правило S→S+T, то + = T. Но, исходя из того же правила и вывода TT*ид, имеем + < T.

Как правило, неоднозначные предшествования можно ликвидировать путем модификации грамматики:

S → T | S+T Здесь + = T, + < U

T → U

U → ид | U*ид

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

Другой способ – использование контекста при разборе. Например, пусть между Si, Si+1 существуют отношения Si < Si+1, Si = Si+1 и нужно определить, какое именно отношение нужно взять в контексте Si Si+1 Si+2. Если существует правило, правая часть которого начинается с Si+1Si+2, значит надо взять отношение Si < Si+1. Иначе Si = Si+1.

Для приведенного примера:

+T* - здесь + < T, есть правило T → T*ид

+T+ - здесь + = T, нет правила → T+

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

Например:

S → T | S+T Имеются два правила с

T → ид | T*P одинаковыми правыми частями

P → ид

Тогда для входного предложения a*b+c идентификаторы a, c могут быть заменены только на T, b – только на P:

a*b+c T*b+c T*P+c T+c S+c S+T S

Задача выбора правила также решается путем дополнительного анализа контекста. Для заданного примера замена ид P должна проводиться только в контексте *ид *P.

  1. 1   ...   5   6   7   8   9   10   11   12   ...   19


написать администратору сайта