Трансляция программ и сопутствующие процессы 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Трансляция программ и сопутствующие процессы



С появления первых компьютеров программисты серьезно задумывались над проблемой кодирования компьютерных программ. Уже с конца 40-х годов стали появляться первые примитивные языки программирования высокого уровня. В них программист записывал решаемую задачу в виде математических формул, а затем, используя специальную таблицу, переводил символ за символом, преобразовывал эти формулы в двухлитерные коды. В дальнейшем специальная программа (впоследствии названная интерпретатором) превращала эти коды в двоичный машинный код. Первый компилятор был разработан Г. Хоппером в начале 50-х годов; он осуществлял функцию объединения команд и в ходе трансляции производил организацию подпрограмм, выделение памяти компьютера, преобразование команд высокого уровня (в то время псевдокодов) в машинные команды. В дальнейшем компиляторы и интерпретаторы для языков Ассемблера стали развиваться и прочно вошли в практику компьютерного дела.

Идеи трансляции (перекодирования) одних символов в другие легли в основу создания различных языков программирования с соответствующими трансляторами – компиляторами и/или интерпретаторами. Отличие компиляторов от интерпретаторов заключается в процедуре трансляции текста в машинный код. Компилятор преобразует весь текст программы в последовательный набор машинных команд, который в дальнейшем отправляется на выполнение. Интерпретатор же осуществляет трансляцию по принципу синхронного перевода. Каждая отдельная строка программного текста транслируется, а затем, после ее интерпретации, команды этой строки выполняются. Современные трансляторы с языков программирования высокого уровня и систем управления базами данных интегрируют в себе возможности и достоинства компиляторов и интерпретаторов, а в системы программирования добавляют различные сервисные утилиты по трансляции и отладке создаваемых программ.

Следующий шаг трансляции – компоновка – заключается в подключении к исходному объектному модулю объектных модулей соответствующих подпрограмм в места ссылок на них (исходные тексты этих подпрограмм в системе вовсе отсутствуют). Другими словами, на место процедуры Write помещается подпрограмма, осуществляющая процедуру вывода данных на экран дисплея. Таким образом, после компоновки (или, иначе, редактирования связей link editor) возникает абсолютный модуль, намного превышающий по объему размер исходного текста программы. Он и исполняется компьютером после его запуска. Расширениями его файлового имени, как правило, являются .com или .ехе.

В силу того, что объектные модули не предназначены для непосредственного исполнения, в них обычно нет привязки составляющих их машинных команд к конкретному месту в ОЗУ. Адреса машинных слов бывают условными, что помогает компоновщику размещать объектные модули в свободныхместах ОЗУ (заменяя условные адреса команд на конкретные).

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

Заметим, что описанный процесс трансляции характерен для компиляции. Последовательно реализованный интерпретатор объектного модуля фактически не создает. В этом заключается и его недостаток, и достоинство (экономия машинной памяти). Впрочем, у современных ЭВМ, в том числе и персональных, проблема малого ОЗУ отходит на второй план, и интерпретация встречается все реже, так как эффективность этого процесса в целом значительно ниже.

На первом этапе транслятор производит синтаксический анализ исходной программы – проверяет, не нарушены ли формальные правила, содержащиеся в данном языке программирования.

Первой фазой синтаксического анализа является анализ лексический. Он заключается в просмотре литер исходной программы и построении из них лексически допустимых единиц – идентификаторов, ключевых слов языка, чисел и т.д. Во второй фазе эти единицы уже рассматриваются как неделимые и проверяется допустимость их сочетания.

Даже если в синтаксическом смысле исходная программа верна, это не означает, что она имеет смысл в рамках данного языка программирования. На следующем этапе семантического анализа транслятор ищет ошибки такого рода: числа употребления скобок не совпадают; переменные не описаны (в языке, требующем обязательного явного описания переменных), т.е. текст программы непонятен (семантика – смысловая сторона языка).

Лишь после того, как в программе все синтаксически правильно и семантически понятно, транслятор переводит операторы программы в машинный код. Это отнюдь не означает, что в программе все благополучно – не исключены ошибки этапа исполнения (деление на ноль, выход за границу массива, переполнение разрядов и т.д.).

Различные фазы компиляции могут быть как последовательными, так и частично перекрывающимися во времени. В зависимости от способа реализации компилятор читает и обрабатывает исходный текст один илинесколько раз, называясь соответственно однопроходным, двухпроходным и т.д.

Все современные операционные системы содержат в себе элементы кросплатформенных технологий, позволяющих использовать один и тот же исполняемый файл или исходный код программы в разных ОС. К таким технологиям относятся:.NET, QT, GTK+. Отдельно стоит выделить технологию Java, которая кроме кроссплатформенной технологии является еще и языком программирования.

К современные интегрированным средам программирования относятся:

– VC++.NET, разработанная для операционных систем семейства Windows и базирующаяся на технологии.NET фирмы Microsoft;

– Glade, разработанная для операционных систем Unix (Linux, FreeBSD), базируется на технологии с открытым кодом GTK++;

– KDeveloper, используется в операционных системах Unix (Linux, FreeBSD), базируется на технологии с открытым кодом QT, поддерживаемой фирмой Trolltech.

Причем интегрированные среды разработки Glade и KDeveloper являются бесплатными и базируются на бесплатных компиляторах, например на наборе компиляторов для ОС Windows, MinGW. Другие составные части бесплатных сред также бесплатны, например, отладчик gdb.

 

 

Эволюция и классификация языков программирования.

Основные понятия языков программирования

В основе компьютерного программирования лежат простые идеи, применявшиеся в технике до появления компьютеров. Одна из них – запись последовательности действий на перфокарты для управления ткацким станком, придуманная и реализованная французом Жозефом Мари-Жаккаром. Однако объединил идеи для решения вычислительных задач Чарльз Бэббидж, дополнив их главной мыслью – о предварительной записи порядка действий с последующим автоматическим воспроизведением. Это произошло в двадцатых годах XIX века. В результате его деятельности появилась первая аналитическая машина, способная выполнять арифметические действия.

Идеи Ч. Бэббиджа поддержала Ада Лавлейс, ставшая впоследствии первым программистом в мире. При работе с аналитической машиной, ею были развиты некоторые базисные конструкции, которые легли затем в основы программирования. Одной из них является «цикл».

Следующий большой шаг вперед языки программирования сделали с появлением системы кодирования машинных команд с помощью специальных символов, предложенной Джоном Моучли (Пенсильванский университет).

Позже Моучли создал собственную компанию, получавшую финансирование от министерства обороны США. Работы, проводимые в этой компании, дали миру множество основополагающих концепций программирования. В ней же был создан первый в мире язык высокого уровня, позволявший записывать программы с помощью математических формул. В дальнейшем был разработан и первый интерпретатор, позволявший использовать вычислительную машину для преобразования исходного кода программы и машинные коды. Другим ярким результатом работы этой компании является труд Грейс Мюррей Хоппер, которая вместе со своей группой придумала такие термины как «подпрограммы», «отладка» и «компилятор».

Первые термины возникали спонтанно и имели обычно интересные истории своего происхождения. Например, появление термина «отладка» связано с мотыльком, залетевшим в помещение вычислительного центра и заблокировавшим работу одного из реле. С тех пор технический процесс тестирования неисправностей в компьютере и в программировании называют «debuging».

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

Первым языком программирования для математических расчетов стал Фортран (компания IBM, 1954 г.), а первым популярным языком для коммерческих приложений – КОБОЛ. Его предшественник, FLOW-MATIC, не имел широкого распространения. В середине 1960-х годов Томас Курц и Джон Кемени создали язык программирования, который состоял из простых слов английского языка и был назван «универсальным символическим кодом для начинающих» BASIC (Beginners All-Purpose Symbolic Instruction Code). Широкому распространению языка BASIC способствовала его поставка как встроенного языка программирования в современных, для того времени, ЭВМ.

Первыми универсальными языками программирования стали: PL/I (Programm Language One), 1967 г., а затем АЛГОЛ-68 (1968 г.). Эти языки не получили широкого распространения из-за своей неоправданной, с точки зрения программиста, сложности конструкций и неэффективности компиляторов.

Первым языком программирования для создания систем искусственного интеллекта стал Пролог (Prolog-PROgramming in LOGic). В конце 50-х годов прошлого века плодом международного сотрудничества в области программирования явился Алгол (ALGOL, от ALGOrithmic Language – алгоритмический язык).

В СССРв те годы под руководством Сергея Петровича Ершова был создан транслятор Альфа, который представлял собою довольно удачную русифицированную версию Алгола. Впоследствии академик Ершов сыграл важнейшую роль в становлении в нашей стране школьной информатики. Развитие идеи Алгола о структуризации разработки алгоритмов нашло важнейшее применение при создании в начале 70-х годов языка Паскаль швейцарским ученым Никлаусом Виртом.

Период с конца 60-х и до начала 80-х годов 20-го века характеризуется бурным ростом числа различных языков программирования, сопровождавшим кризис программного обеспечения. Этот кризис особо остро переживало военное ведомство США. В январе 1975 г. Пентагон учредил комитет, которому было предписано разработать один универсальный язык. На конкурсной основе комитетом были проработаны сотни проектов, и когда стало ясно, что ни один из существующих языков не может их удовлетворить, комитет принял два проекта для окончательного рассмотрения. В мае 1979 г. был объявлен победитeль – группа ученых во главе с Жаном Ихбиа. Победивший язык окрестили АДА, в честь Огасты Ады Лавлейс. Язык АДА – прямой наследник языка Паскаль –предназначен для создания и длительного (многолетнего) сопровождения больших программных систем, он допускает возможность параллельной обработки, управления процессами в реальном времени и многое другое, чего трудноилиневозможно достичь средствами более простых языков.

Значительный отпечаток на современное программирование наложил язык Си (первая версия – 1972 г.), являющийся очень популярным в среде разработчиков систем программного обеспечения (включая операционные системы). Си сочетает в себе черты как языка высокого уровня, так и машинно-ориентированного языка, допуская программиста ко всем машинным ресурсам, чего не обеспечивают такие языки, как Бейсик и Паскаль.

Следует отметить, что многие языки, первоначально разработанные для больших и малых ЭВМ, в дальнейшем были приспособлены к персональным компьютерам. Хорошо вписались в «персоналки» не только Паскаль, Бейсик, Си, Лого, но и ЛИСП, ПРОЛОГ – языки искусственного интеллекта.

В течение многих лет программное обеспечение строилось на основе операциональных и процедурных языков, таких, как Фортран, Бейсик, Паскаль, Ада, Си. И сегодня современные версии этих и им подобных языков (Модула, Форт и др.) доминируют при разработке прикладных программных средств. Однако по мере эволюции языков программирования получили широкое распространение и другие, принципиально иные подходы к созданию программ.

Классическое операциональное и/или процедурное программирование требует от программиста детального описания того, как решать задачу, т.е. формулировки алгоритма и его специальной записи. При этом ожидаемые свойства результата обычно не указываются. Основные понятия языков этих групп – оператор и данные. При процедурном подходе операторы объединяются в группы – процедуры. Структурное программирование в целом не выходит за рамки этого направления, оно лишь дополнительно фиксирует некоторые полезные приемы технологии программирования.

Принципиально иное направление в программировании связано с методологиями (парадигмами) непроцедурного программирования. К ним можно отнести объектно-ориентированное и декларативное программирование. Объектно-ориентированный язык создает окружение в виде множества независимых объектов. Из языков объектного программирования, популярных среди профессио-налов, следует назвать прежде всего Си++.

 

 

Рис. 7. Классификация языков программирования

При использовании декларативного языка программист указывает исходные информационные структуры, взаимосвязи между ними и то, какими свойствами должен обладать результат. При этом процедуру его получения («алгоритм») программист не строит (по крайней мере, в идеале). В этих языках отсутствует понятие «оператор» («команда»). Декларативные языки можно подразделить на два семейства – логические (типичный представитель – Пролог) и функциональные (Лисп). По всей видимости, непроцедурные языки имеют большое будущее. Крупноструктурную классификацию языков программирования, в которой указаны основные методологии программирования; в нижнем ряду, в скобках – типичные языки соответствующих групп иллюстрирует рис. 7.

Языки программирования – это формальные языки, специально созданные для общения человека с компьютером. Каждый язык программирования, равно как и «естественный» язык (русский, английский и т.д.), имеет свой алфавит, словарный запас, грамматику и синтаксис, а также семантику.

Алфавит – фиксированный для данного языка набор основных символов, допускаемых для составления текста программы на этом языке.

Синтаксис – система правил, определяющих допустимые конструкции языка программирования из букв алфавита.

Семантика – это система правил однозначного толкования отдельных языковыхконструкций, позволяющая воспроизвести процесс обработки данных.

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

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

Языки программирования, имитирующие естественные языки и обладающие укрупненными командами, ориентированными на решение прикладных содержательных задач, называют языками высокого уровня. В настоящее время насчитывается несколько сотен таких языков, а если считать и их диалекты, то это число возрастает до нескольких тысяч. Языки программирования высокого уровня существенно отличаются от машинно-ориентированных (низкого уровня) языков. Во-первых, машинная программа, в конечном счете, записывается с помощью лишь двух символов 0 и 1. Во-вторых, каждая ЭВМ имеет ограниченный набор машинных операций, ориентированных на структуру процессора. Как правило, этот набор состоит из сравнительно небольшого числа простейших операций, типа: переслать число в ячейку; считать число из ячейки; увеличить содержимое ячейки на +1 и т.п. Команда на машинном языке содержит очень ограниченный объем информации, поэтому она обычно определяет простейший обмен содержимого ячеек памяти, элементарные арифметические и логические операции. Команда содержит код и адреса ячеек, с содержимым которой выполняется закодированное действие.

Языки программирования высокого уровня имеют следующие достоинства:

• алфавит языка значительно шире машинного, что делает его гораздо более выразительным и при этом существенно повышает наглядность и понятность текста;

• набор операций, допустимых для использования, не зависит от набора машинных операций, а выбирается из соображений удобства формулирования алгоритмов решения задач определенного класса;

• конструкции команд (операторов) отражают содержательные виды обработки данных и задаются в удобном для пользователя виде;

• используется аппарат переменных и действий сними;

• поддерживается широкий набор типов данных.

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

Языки программирования позволяют работать со структурированными и неструктурированными величинами. Важнейшие характеристики структурированной величины таковы: упорядоченность (да или нет), однородность (да или нет), способ доступа к элементам, фиксированность числа элементов (да или нет). Так, массив является упорядоченной однородной структурой с прямым доступом к элементам и фиксированным их количеством.

Всем программным объектам в языках даются индивидуальные имена. Имя программного объекта называют идентификатором (от слова «идентифицировать»). Чаще всего идентификатором является любая конечная последовательность букв и цифр, начинающаяся с буквы.

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

Многим термин «идентификатор» не нравится, и в настоящее время чаще употребляют слово «имя».

Описания или объявления программных объектов связаны с правилами обработки данных. Данные бывают разные и для каждого из них необходимо определить его свойства. Например, если в качестве данных выступает массив, то необходимо задать его размерность, границы индексов, тип элементов массива. Описательная часть языка программирования является необходимой как для системных программистов – разработчиков трансляторов, которые должны, в частности, проводить синтаксическую и семантическую диагностику программ, так и для «прикладного» программиста, которому объявления программныхобъектов частооблегчают процесс разработки и отладки программ.

Переменные играют важнейшую роль в системах программирования. Понятие «переменная» в языках программиро-вания отличается от общепринятого в математике. Переменная – это программный объект, способный принимать некоторое значение с помощью оператора присваивания. В ходе выполнения программы значения переменной могут неоднократно изменяться. Каждая переменная после ее описания отождествляется с какой-либо ячейкой памяти, содержимое которой является ее значением.

Семантический смысл переменной заключается в хранении некоторого значения, соответствующего ее типу (например, переменная целого типа может принимать значение произвольного целого числа), а также в выполнениис ней операций пересылки в нее и извлечения из нее этого значения.

Функция – это программный объект, задающий вычислительную процедуру определения значения, зависимую от некоторых аргументов. Вводится в языки программирования для задания программистом необходимых ему функциональных зависимостей. В каждом языке высокого уровня имеется в наличии библиотека стандартных функций: арифметических, логических, символьных, файловых и т.п. Функции – как стандартные, так и задаваемые программистом – используются в программе в выражениях.

Выражения строятся из величин – постоянных и переменных, функций, скобок, знаков операций и т.д. Выражение имеет конкретный тип, определяемый типом принимаемых в его итоге вычисления значений. Возможны выражения арифметические, принимающие числовые значения, а также логические, символьные, строковые и т. д. Выражение «5 + 7» является, несомненно, арифметическим, а выражение «А + В» может иметь самый разный смысл – в зависимости от того, что стоит за идентификаторами А и В.

Процедура – это программный объект, представляющий некоторый самостоятельный этап обработки данных. По сути, процедуры явились преемниками подпрограмм, которые были введены для облегчения разработки программ еще на самых ранних стадиях формирования алгоритмических языков. Процедура имеет входные и выходные параметры, называемые формальными. При использовании процедуры формальные параметры заменяются на фактические.

Модуль –это специальная программная единица, предназначенная для создания библиотек и разделения больших программ на логически связанные блоки.

По сути, модуль – это набор констант, типов данных, переменных, процедур и функций. В состав модуля входят разделы: заголовок, интерфейс, реализация, инициализация.

Заголовок необходим для ссылок на модуль.

Интерфейс содержит объявления, включая процедуры и функции.

Раздел «реализация» содержит тела процедур и функций, перечисленных в интерфейсной части.

Раздел «инициализация» содержит операторы, необходимые для инициализации модуля.

Каждый модуль компилируется отдельно, и каждый элемент модуля можно использовать в программе без дополнительного объявления.

 

 



Поделиться:


Последнее изменение этой страницы: 2016-08-16; просмотров: 404; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.139.81.58 (0.039 с.)