
- •Содержание
- •1.Рабочая программа
- •2.Модуль Вводный
- •3.Модуль Формальные грамматики и языки
- •3.1.Языки и цепочки символов. Способы задания языков
- •3.1.1.Цепочки символов. Операции над цепочками символов
- •3.1.2.Понятие языка. Формальное определение языка
- •3.1.3.Способы задания языков
- •3.1.4.Синтаксис и семантика языка
- •3.2.Определение грамматики
- •3.2.1.Особенности языков программирования
- •3.2.2.Определение грамматики. Форма Бэкуса—Наура
- •3.2.3.Принцип рекурсии в правилах грамматики
- •3.2.4.Другие способы задания грамматик
- •3.3.Классификация языков и грамматик
- •3.3.1.Классификация грамматик
- •3.3.2.Классификация языков
- •3.4.Контроль
- •4.Модуль Распознаватели, механизм вывода цепочек символов
- •4.1.Цепочки вывода. Сентенциальная форма.
- •4.1.1.Сентенциальная форма грамматики. Язык, заданный грамматикой
- •4.1.2.Левосторонний и правосторонний выводы
- •4.1.3.Однозначные и неоднозначные грамматики
- •4.1.4.Эквивалентность и преобразование грамматик
- •4.2.Распознаватели. Задача разбора
- •4.2.1.Общая схема распознавателя
- •4.2.2.Виды распознавателей
- •4.2.3.Классификация распознавателей по типам языков
- •4.3.Контроль
- •5.Модуль Регулярные грамматики и языки
- •5.1.Регулярные языки и грамматики
- •5.2.Леволинейные и праволинейные грамматики. Автоматные грамматики
- •5.3.Алгоритм преобразования регулярной грамматики к автоматному виду
- •5.4.Конечные автоматы
- •5.4.1.Определение конечного автомата
- •5.4.2.Детерминированные и недетерминированные конечные автоматы
- •5.4.3.Преобразование конечного автомата к детерминированному виду
- •5.5.Контроль
- •6.Модуль Контекстно-свободные грамматики и языки
- •6.1.Контекстно-свободные языки
- •6.1.1.Распознаватели кс-языков. Автоматы с магазинной памятью. Определение мп-автомата
- •6.2.Классы кс-языков и грамматик. Класс ll(k) грамматик.
- •6.3.Принципы построения распознавателей для ll(k)-грамматик
- •6.4.Левая факторизация
- •6.5.Удаление левой рекурсии
- •6.6.Алгоритм разбора для ll(1)-грамматик
- •6.7.Алгоритм построения множества first(1,a)
- •6.8.Алгоритм построения множества follow(1,a)
- •6.9.Восходящие распознаватели кс-языков без возвратов
- •6.9.1.Определение lr(k)-грамматики
- •6.10.Принципы построения распознавателей для lr(k)-грамматик
- •6.10.1.Грамматики простого предшествования
- •6.11.Распознаватели для lr(0) и lr(1) грамматик
- •6.11.1.Распознаватель для lr(0)-грамматики
- •6.11.2.Распознаватель для lr(1) грамматики
- •6.12.Контроль
- •7.Модуль Инструментальные средства для построения трансляторов
- •7.1.Инструментальные средства для построения компиляторов
- •7.1.1.Построитель лексических анализаторов Lex
- •7.2.Контроль
- •8.Модуль Особенности программирование трансляторов
- •8.1.Использование значений произвольных типов, алгоритм разбора
- •8.1.1.Алгоритм синтаксического разбора
- •8.1.2.Семантический стек
- •8.2.Неоднозначности и конфликты
- •8.3.Старшинство операций
- •8.4.Дополнительные возможности программ yacc и lex
- •8.4.1.Обработка ошибок
- •8.5.Совместное использование lex и yacc
- •8.5.1.Кодировка лексем и интерфейс
- •8.5.2.Сборка yacc-программ
- •8.6.Советы по подготовке спецификаций
- •8.6.1.Стиль
- •8.6.2.Использование левой рекурсии
- •8.6.3.Уловки анализа лексики
- •8.6.4.Входной синтаксис yacc'а
- •8.7.Контроль
- •9.Модуль Заключение
- •10.Обеспечение лабораторного практикума
- •11.Дополнительная информация. Примеры
- •11.4.Пример простейшего интерпретатора формул
- •11.5.Простой пример
- •11.6.Более сложный пример
- •11.7.Генераторы лексических и синтаксических анализаторов
- •11.8.Генераторы лексических и синтаксических анализаторов на java
- •11.9.Пакеты для разработки компиляторов
- •Список сокращений
- •Литература
- •Приложения Приложение 1. Учебно–методическая карта дисциплины “Системное программное обеспечение. Синтаксические анализаторы”
- •Приложение 2. Вопросы для зачета по дисциплине “Системное программное обеспечение. Синтаксические анализаторы”
- •Приложение 3. Методические указания к лабораторным работам по дисциплине «Системное программное обеспечение. Синтаксические анализаторы»
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Лексический анализатор lex. Анализ структуры программ
- •Краткая теория:
- •Рассмотрим примеры:
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Лексический анализатор lex, синтаксический анализатор yacc. Алгебраические вычисления
- •Краткая теория:
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Лексический анализатор lex и синтаксический анализатор yacc. Изображение геометрических фигур
- •Краткая теория:
- •Создание метафайла и работа сним
- •Порядок выполнения работы:
- •Контрольные вопросы
- •Приложение 4. Организация рейтингового контроля по дисциплине «Системное программное обеспечение. Синтаксические анализаторы»
6.10.1.Грамматики простого предшествования
Грамматикой простого предшествования называют такую приведенную КС-грамматику (она не содержит циклов, бесплодных и недостижимых символов и λ-правил) G(VN, VT, P, S), V=VTVN, в которой:
Для каждой упорядоченной пары терминальных и нетерминальных символов выполняется не более чем одно из трех отношений предшествования:
Bi =. Bj ( Bi, BjV), если и только если правило AxBiBjy P, где AVN, x,yV*;
Bi . Bj ( Bi, BjV), если и только если правило AxBiDy P и вывод D* Sjz, где A,DVN, x,y,zV*;
Bi . Bj ( Bi, BjV), если и только если правило AxCBjy P и вывод C* zBi или правило AxCDy P и вывод C* zBi и D* Bjw, где A,C,DVN, x,y,z,wV*;
Различные правила в грамматике имеют разные правые части (то есть в грамматике не должно быть двух различных правил с одной и той же правой частью).
Отношения =., <., >. называют отношениями предшествования для символов. Отношение предшествования единственно для каждой упорядоченной пары символов. При этом между какими-либо двумя символами может и не быть отношения предшествования – это значит, что они не могут находится рядом ни в одном элементе разбора синтаксически правильной цепочки. Отношения предшествования зависят от порядка, в котором стоят символы, и в этом смысле их нельзя путать со знаками математических операций – они не обладают ни свойством коммутативности, ни свойством ассоциативности. Например, если известно, что Bi .> Bj, то не обязательно ывполняется Bj <. Bi (поэтому знаки предшествования иногда помечают специально точкой).
Для грамматик простого предшествования известны следующие полезные свойства:
вся грамматика простого предшествования является однозначной;
легко проверить, является или нет произвольная КС-грамматика грамматикой простого предшествования (для этого достаточно проверить рассмотренные выше свойства грамматик простого предшествования или воспользоваться алгоритмом построения матрицы предшествования, который рассмотрен далее).
Как и для многих других классов грамматик, для грамматик простого предшествования не существует алгоритма, который бы мог преобразовать произвольную КС-грамматику в грамматику простого предшествования (или доказать, что преобразование невозможно).
Метод предшествования основан на том факте, что отношения предшествования между двумя соседними символами распознаваемой строки соответствуют трем следующим вариантам:
Bi <. Bi+1, если символ Bi+1 – крайний левый символ некоторой основы (отношение можно назвать «предшествует основе» или просто «предшествует»);
Bi .> Bi+1, если символ Bi – крайний правый символ некоторой основы («следует за основой» или просто «следует»);
Bi =. Bi+1, если символы Bi и Bi+1 принадлежат одной основе («составляют основу»).
Исходя из выше сказанного, выполняет разбор строки для грамматики предшествования.
Рассмотрим цепочку символов в тот момент, когда выполняется свертка цепочки . Символ а является последним символом подцепочки , а символ b – первым символом подцепочки . Тогда, если в грамматике удастся установить непротиворечивые отношения предшествования, то в процессе выполнения разбора по алгоритму «сдвиг-свертка» можно всегда выполнять сдвиг до тех пор, пока между символом на верхушке стека и текущим символом входной цепочки существует отношение <. или =.. А как только между этими символами будет обнаружено отношение .>, так сразу надо выполнять свертку. Причем для выполнения свертки из стека надо выбирать все символы, связанные отношением =.. То, что все различные правила в грамматике предшествования имеют различные правые части, гарантирует непротиворечивость выбора правила при выполнении свертки.
Установление непротиворечивых отношений предшествования между символами грамматики вместе с несовпадающими правыми частями различных правил дает возможность организовать алгоритм «сдвиг-свертка» без возвратов.
На основании отношений предшествования строят матрицу предшествования грамматики. Строки матрицы предшествования – первые (левые) символы, а столбцы – вторые (правые) символы отношений предшествования. В ячейки матрицы помещаются соответствующие знаки отношений. При этом пустые клетки говорят о том, что между данными символами нет ни одного отношения предшествования.
Для построения матрицы предшествования грамматики удобнее воспользоваться двумя дополнительными множествами, так как ее построение на основе непосредственно определения отношений предшествования достаточно сложно. Такие множества – множества крайних левых и множества крайних правых символов относительно нетерминальных символов грамматики G(VN, VT, P, S), V=VTVN, которые определяются следующим образом:
L(A)={XA*Xz}, AVN, XV, zV* - множество крайних левых символов относительно нетерминального символа A (цепочка z может быть и пустой цепочкой);
R(A)= {XA*zX}, AVN, XV, zV* - множество крайних правых символов относительно нетерминального символа A.
Т.е. множество L(A) и R(A) – множества крайних левых и правых символов соответственно, которые могут быть выведены из символа А.
В этом случае отношения предшествования можно определить как:
Bi =. Bj ( Bi, Bj V), если правило AxBiBjyP, где AVN, x,yV*;
Bi <. Bj ( Bi, Bj V), если правило AxBiDyP и BjL(D), где A,DVN, x,yV*;
Bi .> Bj ( Bi, Bj V), если правило AxCBjyP и BiR(C) или правило AxCВyP и BiR(C), BjL(D), где A,C,DVN, x,yV*.
Такое определение отношений удобнее на практике, так как не требует построения выводов, а множества L(A) и R(A) могут быть построены для каждого нетерминального символа AVN грамматики G(VN, VT, P, S), V=VTVN по очень простому алгоритму.
Шаг 1.
AVN:
R0(A)= {XAyX, XV, yV*}, L0(A)= {XAXy, XV, yV*}, i:=1.
Для каждого нетерминального символа А ищем все правила, содержащие А в левой части. Во множество L(A) включаем самый левый символ из правой части правил, а во множество R(A) – самый правый символ из правой части. Переходим к шагу 2.
Шаг 2.
AVN:
Ri(A)=Ri-1(A) Ri-1(B), B(Ri-1(A)VN),
Li(A)=Li-1(A) Li-1(B), B(Li-1(A)VN).
Для каждого нетерминального символа А: если множество L(A) содержит нетерминальные символы грамматики А’, A’’,…, то его надо дополнить символами, входящими в соответствующие множества L(A’), L(A’’), … и не входящими в L(A). Ту же операцию надо выполнить для R(A).
Шаг 3.
Если AVN: Ri(A)Ri-1(A) или Li(A)Li-1(A), то i:=i+1 и вернуться к шагу 2, иначе построение закончено: R(A)=Ri(A) и L(A)=Li(A).
Если на предыдущем шаге хотя бы одно множество L(A) или R(A) для некоторого символа грамматики изменилось, то надо вернуться к шагу 2, иначе построение закончено.
Для построения множеств L(A) и R(A) по правилам грамматики создается матрица предшествования. Матрицу предшествования дополняют символами н и к (начало и конец цепочки). Для них определены следующие отношения предшествования:
н <. X, aV, если S*Xy, где SVN, yV* или (с другой стороны) если XL(S);
к .> X, aV, если S*yX, где SVN, yV* или (с другой стороны) если XR(S).
Здесь S – целевой символ грамматики.
Матрица предшествования служит основой для работы распознавателя языка, заданного грамматикой простого предшествования.