
- •Содержание
- •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. Организация рейтингового контроля по дисциплине «Системное программное обеспечение. Синтаксические анализаторы»
Рассмотрим примеры:
1.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0047)http://yacc.chat.ru/lex_demos/lex_demos_07.html -->
<HTML lang=ru>
<HEAD>
<TITLE>Yacc Lex </TITLE>
<META content="Yacc, Lex, Bison, Flex " name=keywords>
</HEAD>
<BODY bgColor=#eeff99>
<TABLE align=center border=0 cellPadding=0 cellSpacing=0 class=invsbl width=750>
<TBODY>
<TR>
<TD><IMG alt="" src="Yacc Lex/1.gif"></TD>
<TD ><IMG alt=Lex src="Yacc Lex/lex.gif"></TD>
</TR>
<TR>
<TD><IMG src="Yacc Lex /10x1.gif" width=10></TD>
</TR>
</TBODY></TABLE></BODY></HTML>
2.
<html>
<frameset cols="128,13,*,13" border=0>
<frame name="menu" src="menu.html" frameborder=0 scrolling=no>
<frame name="left" src="v.html" frameborder=0 scrolling=no>
<frameset rows="13,*,13" border=0>
<frame name="top" src="h.html" noresize frameborder=0 scrolling=no>
<frame name="body" src="index.html" frameborder=0 scrolling=yes>
</frameset>
<frame name="right" src="v.html" frameborder=0 scrolling=no>
</frameset>
</html>
Реализация компилятора для настоящего языка программирования всегда является весьма трудоемкой задачей, и поэтому давно предпринимались попытки автоматизировать этот процесс. Чаще всего объектом приложения таких усилий служили лучше всего изученные (и наиболее простые) части компилятора - сканер и парсер. Рассмотрим два инструментальных средства: Lex - предназначен для реализации сканера, Yacc - для построения парсера.
Вся необходимая дополнительная информация приводится в пунктах 11.1, 11.2, 11.3 настоящего УМК.
Рассмотрим пример выполнения лабораторной:
%{
#include <stdlib.h>
#include "Exampl.cpp.h"
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
{ \
int c = getc(Examplin); \
result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
}
%}
MAIN main
%START AA MM
%%
^# {BEGIN AA;}
^[ \t]*{MAIN} {BEGIN MM;}
^[ \t]*"{" {printf("begin.");}
^[ \t]*"}" {printf("end.\n\n");}
<AA>define {printf("define.");}
<AA>include {printf("include.");}
<AA>ifdef {printf("ifdef.");}
<MM>"(" {printf("main.");}
[\n]+ {printf("\n"); BEGIN 0;}
. ;
%%
Программа содержит активные и неактивные правила. Все неактивные правила помечены, перед ними указана метка начального условия. Lex-программа управляет двумя начальными условиями, в соответствии с которыми активируются помеченные правила.
В результате работы lex мы получим лексический анализатор, который будет распознавать в Си-программе строки препроцессора Cи-компилятора, выделять функцию main, распознавать начало и конец main или других блоков {}. Лексический анализатор не выводит ничего, кроме сообщений о выделенных лексемах, при этом YACC не выполняет никакой работы.
При этом main.cpp вызывает парсер, который ничего не делает кроме вызова лексического анализатора:
#include "ExamplParser.h"
int
main(int argc, char** argv)
{
ExamplParser parser("main_example.txt");
parser.Parse();
return 0;
}
А в файле Exampl.y дожны быть помещена строчки:
rule1: {}
;
Обратите внимание, что при создании парсера ему в параметрах передается входной файл, он и определяет входной поток в lex-файле (Examplin).
В процессе распознавания символов входного потока может оказаться так, что одна цепочка символов будет удовлетворять нескольким правилам и, следовательно, возникает проблема: действие какого правила должно выполняться?
Для разрешения этого противоречия можно использовать квантование (разбиение) регулярных выражений этих правил Lex-программы на такие новые регулярные выражения, которые дадут, по возможности, однозначное распознавание лексемы. Однако, когда это не сделано, lex использует определенный детерминированный механизм разрешения такого противоречия:
выбирается действие того правила, которое распознает наиболее длинную последовательность символов из входного потока;
если несколько правил распознают последовательности символов одной длины, то выполняется действие того правила, которое записано первым в списке раздела правил Lex-программы.
Дополнительная информация по использованию лексического анализатора находится в лекциях по данному курсу и документации по Lex и Yacc.
Задания:
Требуется создать лексический анализатор для выполнения задания, который прочитает данные из входного файла, а результат работы выведет на экран.
Задание заключается в разборе текста, представленном в некотором языке. Требуется разбить его на блоки с учетом вложенности и представить в упорядоченном виде. Каждый блок выделяется на основании правил оформления текстов на соответствующем языке. Входным является файл, написанный на этом языке. Выходные данные только являются визуально более читаемы и дают ясное представление о структуре текста (программе).