Конспект лекции
доцента кафедры ИВТ Гродненского госуниверситета
канд. техн. наук Ливак Елены Николаевны
Системой программирования будем называть комплекс программных средств, предназначенных для кодирования, тестирования и отладки программного обеспечения.
Другими словами, это набор специализированных программных продуктов, которые являются инструментальными средствами разработчика.
Система программирования, как правило, включает следующие программные компоненты:
· редактор текста;
· транслятор с соответствующего языка;
· компоновщик (редактор связей);
· отладчик;
· библиотеки подпрограмм.
Заметим, что любая система программирования может работать только в соответствующей ОС, под которую она и создана, однако при этом она может позволять разрабатывать программное обеспечение и под другие ОС.
Редактор текста - это программа для ввода и модификации текста.
Программа, подготовленная на каком-либо языке программирования, называется исходным модулем и представляет собой текстовый файл с соответствующим расширением.
Например, в системе программирования Borland Pascal редактор сохраняет тексты программ в файлах с расширением pas.
Трансляторы предназначены для преобразования программ, написанных на языках программирования, в программы на машинном языке.
В качестве входной информации трансляторы применяют исходные модули и формируют в результате своей работы объектные модули, являющиеся входной информацией для редактора связей.
Объектный модуль содержит текст программы на машинном языке и дополнительную информацию, обеспечивающую как настройку модуля по месту его загрузки в оперативную память, так и объединение этого модуля с другими независимо оттранслированными модулями в единую программу.
Объектный модуль, как правило, имеет расширение obj.
Трансляторы делятся на два класса: компиляторы и интерпретаторы.
Компилятор переводит весь исходный модуль на машинный язык.
При компиляции одна и та же программа имеет несколько представлений - в виде текста и в виде выполняемого файла.
Интерпретатор последовательно переводит на машинный язык каждый оператор исходного модуля и сразу же выполняет его.
Основной недостаток интерпретатора - низкая скорость работы интерпретируемых программ (во время выполнения программы необходим перевод каждого оператора на машинный язык). Преимущество интерпретатора перед компилятором состоит в том, что программа пользователя имеет одно представление - в виде текста.
Соответственно говорят о компилируемых и интерпретируемых языках программирования.
Языки программирования Pascal, Object Pascal и С-подобные языки (С, С++, С#) являются компилируемыми.
Язык Java - ; пример интерпретируемого языка программирования.
Компоновщик, или редактор связей - системная обрабатывающая программа, редактирующая и объединяющая объектные (ранее оттраслированные) модули в единые загрузочные, готовые к выполнению программные модули.
Загрузочный модуль может быть помещен операционной системой в оперативную память и выполнен.
Загрузочный модуль, подготовленный системой программирования Borland Pascal, имеет расширение exe.
Отладчик - системная программа, которая позволяет управлять процессом исполнения пользовательской программы, является инструментом для поиска и исправления ошибок в программе.
Базовый набор функций отладчика включает:
· пошаговое выполнение программы (режим трассировки) с отображением результатов,
· остановка в заранее определенных точках,
· возможность остановки в некотором месте программы при выполнении некоторого условия;
· изображение и изменение значений переменных.
В системе программирования Borland Pascal отладчик запускается с помощью режима меню Debug.
Загрузчик - системная обрабатывающая программа.
Загрузчик помещает находящиеся в его входном наборе данных объектные и загрузочные модули в оперативную память, объединяет их в единую программу, корректирует перемещаемые адресные константы с учетом фактического адреса загрузки и передает управление в точку входа созданной программы.
В системе программирования Borland Pascal загрузчик начинает свою работу после выполнения команды Run. Эта команда объединяет функции редактора связей и загрузчика.
Примерами современных систем программирования являются системы программирования
Turbo Pascal,
Borland Pascal,
Borland Delphi,
Borland C++ Builder,
Microsoft Visual Basic,
Microsoft Visual C++
и многие-многие другие.
Современными системами программирования являются система, построенная на базе языка С# и системы, ориентированные на концепцию .NET.
Основным модулем системы программирования всегда является компилятор.
Именно характеристики компилятора, прежде всего, влияют на эффективность результирующих программ, порождаемых системой программирования.
Кроме основного компилятора, большинство систем программирования могут содержать в своем составе целый ряд других компиляторов. Так, большинство систем содержат компилятор с языка Assembler и компилятор с входного языка описания ресурсов. Но они редко непосредственно взаимодействуют с пользователем.
Основные термины и понятия.
Транслятор – это программа, которая переводит входную программу на исходном (входном) языке в эквивалентную ей выходную программу на результирующем (выходном) языке.
Близко по смыслу к этому понятию понятие компилятор.
Компилятор – это транслятор, который осуществляет перевод исходной программы в эквивалентную ей объектную программу на языке машинных команд или языке ассемблера.
Таким образом, компилятор отличается от транслятора тем, что его результирующая программа написана обязательно на языке машинных команд или языке ассемблера. Результирующая программа транслятора в общем случае может быть написана на любом языке (например, транслятор с языка Pascal на язык С).
Таким образом, компиляторы – это вид трансляторов.
Повторим еще раз принципиально отличное понятие «интерпретатор».
Интерпретатор – это программа, которая воспринимает входную программу на исходном языке и выполняет ее. (Интерпретатор не порождает результирующую программу и никакого результирующего кода.)
Основные блоки (фазы) компилятора, их функции
Исходная программа, написанная на некотором языке программирования, есть цепочка знаков. Компилятор в конечном итоге превращает эту цепочку знаков в цепочку битов – объектный код.
В процессе компиляции обычно выделяют следующие подпроцессы (блоки, этапы).
1. Лексический анализ.
2. Работа с таблицами.
3. Синтаксический анализ, или разбор.
4. Генерация кода, или трансляция в промежуточный код (например, языка ассемблер).
5. Оптимизация кода.
6. Генерация объектного кода.
Замечание. В конкретных компиляторах порядок может несколько отличаться, а некоторые блоки могут объединяться в один. В реальном компиляторе блоки не обязательно разделены.
Входом является цепочка символов некоторого алфавита.
Некоторые комбинации символов в программе рассматриваются как единые объекты – лексемы (например, зарезервированные слова, идентификаторы, числовые константы).
Работа лексического анализатора состоит в том, чтобы сгруппировать определенные символы в единые синтаксические объекты – лексемы.
Выходом является последовательность лексем.
Например, в результате лексического анализа следующей цепочки символов
сost:= (price + tax) * 0.98
будет обнаружено, что
cost, price, tax являются лексемами типа идентификатор;
0.98 - лексема типа константа;
:=, +, * - являются лексемами.
Информация о лексемах собирается и записывается в одну или несколько таблиц, например, в виде списка лексем и соответствующей информации о них.
Вход – цепочка лексем.
На этом этапе исследуется цепочка лексем и устанавливается, удовлетворяет ли она структурным условиям, явно сформулированным в определении синтаксиса языка.
Выходом анализатора является дерево, которое представляет синтаксическую структуру, присущую исходной программе.
Полученное дерево используется для перевода входной программы в программу на машинном языке, но чаще осуществляется перевод на промежуточный язык (ассемблер).
Замечание. На практике чаще одновременно строится и дерево, и код.
Существует несколько методов построения промежуточного кода по синтаксическому дереву. Основным из них является синтаксически управляемый перевод (трансляция).
На двух этапах – синтаксического анализа и в начале этапа подготовки к генерации кода – выполняется семантический анализ. Семантический анализатор проверяет семантические соглашения входного языка, проверяет элементарные семантические (смысловые) нормы языков программирования, напрямую не связанных с входным языком; дополняет внутреннее представление программы в компиляторе операторами и действиями, неявно предусмотренными семантикой входного языка.
На этом этапе производится попытка сделать объектные программы более эффективными (т.е. быстрее работающими или более компактными).
ДОПОЛНИТЕЛЬНЫЙ МАТЕРИАЛ
Так, для операций, составляющих линейный участок программы, может применяться удаление бесполезных присваиваний, исключение лишних операций, перестановка операций, арифметические преобразования.
Еще одним методом оптимизации кода является оптимизация вычисления логических выражений (не всегда полностью надо выполнять вычисление всего выражения, чтобы знать его результат, иногда по значению одного операнда можно определить значение всего выражения).
Оптимизация передачи параметров в процедуры и функции через стек не является эффективным, если выполняются несложные вычисления над небольшим количеством параметров (всякий раз при вызове процедуры компилятор создает объектный код для размещения фактических параметров в стеке, а при выходе – код для освобождения ячеек). Эффективность результирующей программы повышается при передаче параметров через регистры либо подстановкой кода функции в вызывающий объектный код.
Для оптимизации циклов используются следующие методы: вынесение инвариантных вычислений из циклов (вынесение тех операций, операнды которых не изменяются); замена операций с индуктивными переменными (изменение сложных операций с переменными, значения которых в процессе выполнения цикла образуют арифметическую прогрессию, на более простые операции); слияние и развертывание циклов (слияние двух вложенных циклов в один и замена цикла на линейную последовательность операций).
Последний заключительный этап. Происходит порождение команд, составляющих предложения выходного языка и в целом текст результирующей программы.
В системе программирования Borland Pascal компиляция запускается с помощью режима меню Compile.
В случае отсутствия синтаксических ошибок (перевод осуществлен успешно) система программирования сообщает об этом пользователю и предлагает нажать любую клавишу для продолжения работы:
Compile successful. Press any key.
Если ошибка обнаружена, система сообщает пользователю название ошибки и указывает курсором ту строку, в которой обнаружена ошибка (иногда следующую строку после ошибочной). В этом случае пользователю необходимо исправить ошибку и снова запустить режим компиляции.