лекция 16 (Языки программирования (лекции) (2008))

2019-09-19СтудИзба

Описание файла

Файл "лекция 16" внутри архива находится в папке "Языки программирования (лекции) (2008)". Документ из архива "Языки программирования (лекции) (2008)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "лекция 16"

Текст из документа "лекция 16"

Языки программирования.

Лекция 16.

Глава 6: Раздельная трансляция

Вопрос тесно связан с понятием физического модуля.

Виды трансляций:

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

2. Инкрементная трансляция (сам компилятор без вмешательства программиста определяет, что за кусочки нужны и без передаёт их транслятору)- современные отладчики, при незначительных изменениях в коде. ;

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

компилируемые ЯП: программа из одного языка Л1 переводится в язык Л2(объектный язык), который уже интерпретируется ( язык JVM).

Цельные компилируемые языки (языки, созданные не для индустриального программирования)- Алгол-60(для обмена алгоритмами), стандартный Паскаль(для обучения программирования).

4. Языки с раздельной трансляцией - программа разбивается на модули, возникает понятие физического модуля (ФМ) или единицы компиляции, т.е. при раздельной трансляции используются компилируемые яп.

В компилируемых яп чётко разделяются 2 фазы: трансляция и сборка программы (после которой образуется исполняемый код).

Уже в Фортране была реализована возможность раздельной трансляции (РТ). Все процедуры и ф-ии- единицы компиляции. Но там она была хороша только тем, что она там есть. Она никак не была поддержана средствами защиты.

-->РТ - одно из самых критичных свойств яп, которые ориентированны на индустриальное программирование.

Рассмотрим понятия:

Контекст трансляции(КТ) - совокупность имен и их атрибутов, необходимых для трансляции модуля:

- В контекст входят имена, которые не определяются в самом модуле, но используются в нём;

- Всегда не пуст;

Даже при цельной трансляции существуют имена, которые не определены:

для стандартного Паскаля в контекст входят стандартные идентификаторы (их смысл определяется транслятором, но они не входят в стандартные служебные слова)--> в КТ определяют имена стандартного окружения и только они.

Раздельная трансляция:

Из единиц компиляции (ЕК) есть понятие экспорта и всё, что экспортируется, образует контекст трансляции (КТ),

было реализовано уже в Assembler--> C

Очередная ЕК подаётся на вход транслятору, который затем формирует объектный файл. Это присуще любой системе с раздельной трансляцией. Различия в том, что возникает два понятия - трансляционная библиотека(ТБ)

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

Пример:

статическая функция, которая необходима только в этом файле--> необходима в программной библиотеке, но информация о ней не попадает в контекст трансляции.

Простейший вариант раздельной трансляции:

ЕК поступает на вход транслятору, который формирует некоторую часть программной библиотеки (объектный модуль). Откуда в такой схеме берётся контекст трансляции?

Если транслятор видит только ЕК, то весь контекст трансляции должен быть в ЕК. В языке должны быть конструкции, описывающие этот контекст:

В ассемблере - это конструкции:

PUBLIC имя

EXTRN W: WORD - конструкция импорта, находится в другом файле.

В языке Си подобного рода объявления - это ключевое слово extern.

4.1. Языки с такой схемой - языки с раздельной независимой трансляции (компилятор в один момент видит только одну единицу компиляции).

Очевидной недостаток таких языков - каждая ЕК должна заново описывать свой контекст. И если две ЕК используют один контекст, то появляется некоторая избыточность. Если мы перепутаем, укажем неверный спецификатор, то никто никакой ошибки не найдёт - язык объектных файлов не содержит такой возможности.

Максимум- предупреждение.

ЕК0

int a;

ЕК1

extern int a;

ЕК2

extern int a;

И на помощь приходит технология - если мы описываем какой-то контекст, экспортируем, то мы должны интерфейс (всю совокупность экспортированных имён) выносить в специальный header-файл.

Если нужно имя переменной, типа,..., то вместо объявления extern надо целиком включить контекст трансляции - нужный header-файл при помощи #include.

Если надо включить в программу M2.h и M3.h, а М2 содержит в себе объявления из М3, то с точки зрения компилятора Си при объявлении нескольких extern-переменных ничего страшного не возникнет. Но беда может возникнуть если мы объявляем типы:

например, если в М3 содержится описание структуры:

struct c {

}

--> двойное объявление

Выход - проверка на объявление специального символа, например для модуля MyModule.h это может быть __MYMODULE_H__(уникальный для данной единицы трансляции)

И проверка будет иметь вид:

#ifndef __MYMODULE_H__// определен модуль или нет?

#define __MYMODULE_H__// описание, если не было ранее.

...сам модуль MyModule.h....

#endif

И при такой технике гарантируется, что каждое имя описано только один раз.

НО(для С и С++):

1. При изменении одного header-модуля нужно перетранслировать все модули, которые его включают.

2. У нас только единое пространство имён.

Все header-файлы образуют трансляционную библиотеку.

#include <stdio.h>

#include <io.h>

#include <net\inet.h>// необходимо подключить еще библиотеку

lseek()-достаточно include

Но для использования gethostname() компилятору уже надо подключать специальную библиотеку при помощи следующих команд линковщика:

-l inet

-L build_path // путь к этой библиотеке

причем в разных средах- будет воспринято по-разному, к тому же путь к библиотеке не будет одинаковым.

Язык С++ использует независимую трансляцию, чтобы облегчить распространение этого языка.

4.2. Раздельная зависимая трансляция.

Транслятор когда читает ЕК, то он черпает информацию из нее и из ТБ (трансляционной библиотеки) - и на выходе будет не только ПБ, но и обновление трансляционной библиотеки. Директивы описания контекста ориентированы на имена модулей.

Языки 70-х, 80-х, 90-х гг.

В этой трансляции физический модуль (ФМ) аналогичен логическому модулю (ЛМ).

Такое наблюдается, например, в языке Дельфи.

Юнит(ЕК) в Дельфи транслируется в DFU, который содержит объектные модули и таблицу символов(ПБ и ТБ).

В Модуле-2 есть понятие библиотечного модуля, который делится на definition mudle и implementation module. На уровне исходного текста разделены ПБ и ТБ.

Та же самая идея и в Обероне - у нас существует единая ЕК - модуль. Реально оттранслированный код модулей выглядит как DFU - оттранслированный текст начинается с таблицы символов(все, что помечено *), а далее объектные модули.

Ключевые слова в этих языках:

IMPORT модуль -список имен модулей (компилятор подгружает их)

USES модуль- для delphi;

Но здесь структура всё равно очень проста за счёт того, что ЛМ совпадает с ФМ.

Наиболее мощно это реализовано в языке Ада.

Восходящий подход (bottom-up) - сначала компилируются модули нижнего уровня, потом выше(модули, основанные на предыдущих) и т.д. Сервисные модули ничего не знают о своих клиентах - типичный случай одностороннего связывания.

Модули, которые экспортируют ничего не знают о модулях, которые их импортируют.

М1 импортирует М2, а М2 импортирует М1 (зацикливание) - разрешение такой ситуации невозможно.

Си и Модула-2 находят эту ошибку на этапе трансляции(препроцессор):

Си : Будет попытка открыть файл на чтение, который уже открыт на запись.

Модула-2: М2 откомпилирован? он может быть откомпилирован только после компиляции М1, который сейчас компилируется.

Решение проблемы - переделка одного или нескольких модулей.

Ключевое отличие языка Ада - он поддерживает и восходящее, и нисходящее программирования(вложенные пакеты).

Там есть понятие пакетов.

Внутри какого-то пакета М могут быть вложенные пакеты М_inner, M1_inner:

package M is

package M_inner is

package M1_inner is

end M1_inner;

end M_inner;

end M;

Соответствующие тела вложены:

pakage body M

body M_inner

body M1_inner

end M;

если мы можем отдельно транслировать пакеты, то мы должны транслировать и вложенные пакеты.

Ситуация со вложенностью отличается зависимостью пакетов, М от М1, т.к. он может использовать имена М1, и М1 зависит от М --> В результате, у нас возникают двусторонние связи.

И Ада поддерживает и односторонние связи.

Основной принцип языка Ада - раздельно транслируемая программа не должна отличаться от цельно транслируемой - чтобы можно было программу транслировать единым куском, а не несколькими единицами компиляции.

можно программу разбивать на:

  • совокупность одноуровневых единиц компиляции( модула-2, оберон, delphi);

  • тела пакетов;

У нас возникает понятие первичных модулей и вторичных модулей.

Первичные модули(спецификация пакета) - это библиотечные модули в таких языках как Модула-2.

Тело пакета - вторичный модуль. Вторичный модуль - раздельно транслируемая процедура или функция.

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

WITH список пакетов- подгружает контекст трансляции.

текст ЕК

Здесь единицей контекста является только пакет.

Это один в один соответствует конструкциям import и uses в Обероне и Дельфи соответственно.

WITH M1 is

package M2 is

X:T; // ERROR, т.к. Т видно только потенциально.

X:M1.T; // OK - видимость только через имя соответствующего модуля

Но есть модификация:

WITH список_пакетов;

USE список_пакетов2; // этот список - подмножество первого списка

Это напоминает конструкцию USES из Дельфи - там она подгружает список имен из соответствующего юнита и делает их непосредственно видимыми .

Это аналог конструкции одностороннего связывания модулей типа языков Оберон и Дельфи.

Но поддерживается ещё и двустороннее связывание - можно раздельно транслировать тело и спецификацию пакета М, но и тело пакета M_inner.

для with, нет обратной конструкции, т.к. это одностороннее связывание.

Для этого нам нужна пара конструкций:

Вместо спецификации пакета M_inner, мы пишем:

package M_inner is separate;- говорит компилятору поискать таблицу имен M_inner где-то еще.

Это в одну сторону, а в другую сторону -

package M is stub

...

package M_inner is separate // stub - заглушка, при трансляции увидев заглушку, компилятор полезет в ТБ и загрузить таблицу имен для М_inner, не зная таблицы имен транслировать дальше нельзя

...

end M;

Что будет, если мы хотим оттранслировать отдельно тело пакета M_inner:

package body M_inner is

end M_inner

нельзя, т.к. М_inner внутри пакета М

separate (M) package body M_inner is

...

end M_inner;-двустороннее связывание

(М)-имя объемлющего пакета.

Когда компилятор транслирует, какую таблицу имён он должен подключить в этой точке (точке, где стоит (М))? Рассмотрим 2 возможности - эту и ещё:

WITH M;

package MM is

...

end MM; - это одностороннее связывание, надо подключить все имена из спецификации пакета М.

Для двустороннего связывания где-то должна стоять заглушка (в теле пакета М):

package body M_inner is separate

К моменту точки, где (М) должны быть оттранслированы все имена пакета М , совокупность имён из начала пакета М (до заглушки).

Mы вынесли М_inner и физически оно находится вне пакета М(транслируется как отдельная единица), но мы хотим, чтобы сохранялась вложенность этого пакета в М(доступ к именам). Т.о. тело пакета М должно быть оттранслировано раньше.

Это существенно усложняет процесс трансляции.

Сохранить всю таблицу имён - сохранить то, что было объявлено в М до заглушки M_inner.

Заглушки говорят, что в этой точке надо сохранить всю таблицу имен, потом при трансляции в этой точке она понадобится.

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

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5224
Авторов
на СтудИзбе
426
Средний доход
с одного платного файла
Обучение Подробнее