- •Введение
- •Формальные грамматики. Выводы Основные понятия
- •Способы задания языков
- •Операции над языками
- •Формальные грамматики. Выводы
- •Преобразования кс-грамматик Основные понятия
- •Устранение лишних символов
- •Исключение лишних правил
- •Исключение -правил
- •Устранение цепных правил
- •Выделение нетерминала
- •Левая факторизация
- •Устранение левой рекурсии
- •Устранение правой рекурсии
- •Нормальная форма Хомского
- •Нормальная форма Грейбах
- •Операторная кс-грамматика
- •Регулярные языки и конечные распознаватели Правосторонние грамматики
- •Левосторонние грамматики
- •Связь правосторонних и левосторонних грамматик
- •Преобразование кс-грамматики произвольного вида в правостороннюю
- •Конечные распознаватели. Основные понятия
- •Преобразование недетерминированных конечных распознавателей с -переходами в детерминированные
- •Эквивалентность состояний конечных детерминированных распознавателей
- •Эквивалентность конечных детерминированных распознавателей
- •Минимизация конечных детерминированных распознавателей
- •Регулярные множества и регулярные выражения
- •Регулярные выражения и конечные распознаватели
- •Получение регулярного выражения из конечного распознавателя
- •Построение конечного распознавателя по регулярному выражению
- •Конечные распознаватели и регулярные грамматики
- •Получение грамматики из конечного распознавателя
- •Построение конечных распознавателей по регулярным грамматикам
- •Ещё один способ взаимного преобразования право- и левосторонних грамматик
- •Программная реализация конечных детерминированных распознавателей
- •Лексический анализ
- •Принципы построения лексических анализаторов
- •Определение границ лексем
- •Выполнение действий, связанных с лексемами
- •Выделение ключевых слов
- •Программная реализация лексических анализаторов
- •Глава 3. Синтаксический анализ
- •3.1. Автомат с магазинной памятью
- •3.2. Таблично-управляемый предсказывающий разбор
- •3.2.1. Алгоритм разбора сверху-вниз
- •3.2.2. Множества first и follow
- •3.2.3. Конструирование таблиц предсказывающего анализатора
- •3.2.4. Ll(1)-грамматики
- •3.2.7. Рекурсивный спуск
- •3.3. Разбор снизу-вверх типа сдвиг-свертка
- •3.3.1. Основа
- •3.3.2. Lr(k)-анализаторы
- •3.3.4. Конфликты разбора типа сдвиг-свертка
Конечные распознаватели и регулярные грамматики
Любой регулярный язык порождается регулярной грамматикой и может быть распознан конечным распознавателем, следовательно для каждого конечного распознавателя существует регулярная грамматика, порождающая тот язык, который допускается распознавателем, и, обратно, для регулярной грамматики существует конечный распознаватель, который допускает только то множество цепочек, которое порождает регулярная грамматика. Далее рассмотрим алгоритмы получения грамматик, порождающих множество цепочек, допускаемых заданным конечным распознавателем и алгоритмы построения конечного распознавателя, допускающего множество цепочек, порождаемое заданной регулярной грамматикой.
Получение грамматики из конечного распознавателя
Пусть задан конечный распознаватель. Поставим в соответствие множеству входных символов распознавателя множество терминалов, а множеству состояний – множество нетерминалов. Дадим нетерминалу Si, соответствующему состоянию si такую интерпретацию:
<цепочки, допускаемые состоянием si >
Если в распознавателе существует переход из состояния si в sj под действием входного символа x , <цепочки, допускаемые состоянием si > могут начинаться символом (терминалом) x , за которым следуют <цепочки, допускаемые состоянием sj >, т.е. получаем правило: Si x Sj .
Если же в распознавателе есть -переход из состояния si в sj , то <цепочки, допускаемые состоянием si > представляют собой <цепочки, допускаемые состоянием sj > , т.е. получаем правило Si Sj .
Если в распознавателе состояние si допускающее, то <цепочка, допускаемая состоянием si > может быть пустой, т.е. получаем правило: Si .
Если каждому переходу и каждому допускающему состоянию распознавателя сопоставить полученные вше правила, то получим автоматную правостороннюю грамматику (правостороннюю грамматику специального вида), возможно, с цепными правилами.
Алгоритм получения автоматной правосторонней грамматики из конечного распознавателя.
1. Множеством терминалов грамматики сделать множество входных символов распознавателя.
2. Множеством нетерминалов грамматики сделать множество состояний распознавателя, а начальным нетерминалом – его начальное состояние.
3. Если в распознавателе есть переход из состояния si в sj под действием входного символа x , то в грамматику ввести правило: Si x Sj .
4. Если в распознавателе есть -переход из состояния si в sj , то в грамматику нужно ввести правило Si Sj .
5. Если в распознавателе состояние si допускающее, то в грамматику ввести правило: Si .
6. Устранить цепные правила.
Если применять алгоритм к детерминированному или недетерминированному конечному распознавателю без -переходов, то п.4 и п.6 не выполняются.
Пример.
Граф конечного распознавателя.
ц
ц
ц . ц
+
- .
ц
.
Автоматная правосторонняя грамматика.
S0 + S1 S1 ц S2 S3 ц S4
S0 - S1 S1 . S3 S4 ц S4
S0 ц S2 S2 ц S2 S4
S0 . S3 S2 . S4
Нетерминалу Si, соответствующему состоянию si , можно дать другую интерпретацию:
<цепочки, связывающие начальное состояние с состоянием si >
Если в распознавателе существует переход в состояние sj из si под действием входного символа x , то <цепочки, связывающие начальное состояние с состоянием si > могут представлять собой <цепочки, связывающие начальное состояние с состоянием sj >, к которым приписан символ (терминал) x , т.е. получаем правило: Si Sj x .
Если в распознавателе в состояние sj существует -переход из si , то <цепочки, связывающие начальное состояние с состоянием si > представляют собой <цепочки, связывающие начальное состояние с состоянием sj >, т.е. получаем правило: Si Sj .
Если в распознавателе состояние si начальное, то <цепочка, связывающая начальное состояние с состоянием si > представляет собой пустую цепочку, т.е. получаем правило: Si .
Если в распознавателе состояние si допускающее, то <цепочки, связывающие начальное состояние с состоянием si > представляют собой цепочки, допускаемые распознавателем, поэтому Si - начальный нетерминал. Если же в распознавателе n>1 допускающих состояний, то каждому допускающему состоянию должен соответствовать свой начальный нетерминал, но так как в грамматике должен быть только один начальный нетерминал, то необходимо ввести новый начальный нетерминал S и n правил вида S Si для каждого допускающего состояния si .
Сопоставив каждому переходу, начальному и допускающему состоянию распознавателя полученные выше правила, получим автоматную левостороннюю грамматику, возможно, с цепными правилами.
Алгоритм получения автоматной левосторонней грамматики из конечного распознавателя.
1. Множеством терминалов грамматики сделать множество входных символов распознавателя.
2. Множеством нетерминалов грамматики сделать множество состояний распознавателя.
3. Если в распознавателе состояние si начальное, то в грамматику ввести правило: Si .
4. Если в распознавателе есть переход в состояние si из sj под действием входного символа x , то в грамматику ввести правило: Si Sj х.
5. Если в распознавателе есть -переход в состояние si из sj , то в грамматику ввести правило: Si Sj .
6. Если в распознавателе n1 допускающих состояний, то ввести новый начальный нетерминал S и n правил вида S Si для каждого допускающего состояния si .
7. Устранить цепные правила.
Если применять алгоритм к детерминированному или недетерминированному конечному распознавателю без -переходов и с одним допускающим состоянием, то п.5-7 не выполняются и в качестве начального нетерминала нужно принять нетерминал, соответствующий допускающему состоянию.
Пример.
Автоматная левосторонняя грамматика, полученная из распознавателя (см. пример выше).
S4 S4 ц S3 S0 . S1 S0 +
S4 S2 . S2 S0 ц S1 S0 -
S4 S3 ц S2 S1 ц S0
S3 S1 . S2 S2 ц
