![](/user_photo/1549_7W_y5.jpg)
- •1 Общая модель компилятора. Блоки компилятора и их функции
- •2 Общее понятие синтаксиса и семантики языка. Бнф и др. Методы описания синтаксиса и семантики языка.
- •3 Понятие языка. Способы задания языка. Операции над языком
- •4 Регулярные выражения. Способы задания регулярных выражений. Операции над регулярными выражениями.
- •5.Конечные автоматы. Способы задания. Методы построения конечных автоматов. Преобразование конечных автоматов.
- •6 Лексический анализ. Методы и средства построения лексического анализатора.
- •7 Распознавание цепочек символов с помощью конечных автоматов.
- •8 Распознавание цепочек символов с помощью автоматов с магазинной памятью.
- •9 Грамматики языков. Классификация языков по Хомскому.
- •11 Методы представления грамматики в памяти.
- •12 Нисходящий синтаксический анализ. Метод рекурсивного разбора.
- •14 Нисходящий синтаксический анализ. Методы восстановления после ошибок.
- •16 Синтаксический анализ приоритета операторов. Функция приоритета
- •18 Slr-анализаторы. Построение таблиц для slr-анализатора.
- •19 Методы анализа ошибок. Восстановление после ошибок.
- •20 Семантика языка, методы описания и анализа.
- •21 Понятие атрибутивные грамматики
- •22 Синтаксически управляемая трансляция.
- •23 Таблица символов, таблица меток и др. Методы построения, доступа и анализа.
- •24 Генерация промежуточного кода.
- •25 Методы оптимизация промежуточного кода.
- •29 Имена, связывание, проверка типов.
- •30 Область видимости имен. Способы реализации.
- •31 Типы данных. Способы реализации.
- •32 Выражения и операторы присваивания. Способы реализации.
- •36. Абстрактные типы данных. Способы реализации.
- •37 Объектно-ориентированные языки программирования. Способы реализации.
- •38 Обработка исключительных ситуаций. Способы реализации.
- •39 Языки параллельного программирования. Способы реализации.
- •40 Императивные языки программирования. Способы реализации.
- •41 Функциональные языки программирования. Способы реализации.
- •42 Языки логического программирования. Способы реализации.
- •43 Графовые грамматики. Назначение и основные понятия.
- •44 Antlr. Tree grammars.
- •46 Case-средства. Назначение, классификация и основные понятия.
- •47 Case-средства. Направления интеллектуализации.
32 Выражения и операторы присваивания. Способы реализации.
Большинство свойств арифметических выражений в языках программирования произошли от условностей, принятых в математике. В языках программирования арифметические выражения состоят из операторов, операндов, круглых скобок и вызовов функций. Оператор может быть унарным (unary), что означает наличие у него одного операнда, бинарным (binary), имеющим два операнда, и тернарным (ternary), у которого есть три операнда.
В большинстве императивных языков программирования бинарные операторы являются инфиксными, т.е. они появляются между операндами. Одним из исключений является язык Perl, в котором есть префиксные операторы, т.е. предшествующие своим операндам.
Цель арифметических выражений - указать арифметическое вычисление. Реализация такого вычисления должна выполнять два действия: выбирать операнды (обычно из памяти) и выполнять над ними арифметические действия.
Ассоциативность
Порядок вычисления операндов
Преобразование типов :сужающие,расширяющие
Явное преобразование типов
Выражения отношения
Оператор отношений (relational operator) сравнивает значения двух своих операндов. Выражение отношений (relational expression) состоит из двух операндов и одного оператора отношений. Значение выражения отношений принадлежит к булевскому типу, за исключением случая, когда в языке нет булевского типа. Операторы отношений обычно перегружаются для большого числа типов. Операция, определяющая истинность или ложность выражения отношений, зависит от типов операндов. Она может быть простой (для целых операндов) или сложной (для операндов, являющихся символьными строками). Обычными типами операндов, которые могут использоваться в выражениях отношений, являются числовые типы, строки и порядковые типы.
Булевские выражения
Операторы присваивания.Присваивание является одной из центральных конструкций в императивных языках программирования. Оно обеспечивает механизм, с помощью которого пользователь может динамически изменять связи значений с переменными. В следующем разделе рассмотрена простейшая форма присваивания, а далее следует описание различных альтернатив.
Простые присваивания
Множественные целевые объекты
Условные целевые объекты
Составной оператор присваивания позволяет сокращенно задавать часто используемую форму присваивания. С помощью этого метода можно сократить запись присваивания, при котором целевая переменная используется в качестве первого операнда в правой части выражения, например: а = а + b. Синтаксис составного оператора присваивания языка С представляет собой объединение нужного бинарного оператора и оператора =. Например, выражение
Унарные операторы присваивания
Постфиксный оператор sum = count ++; вначале присваивает значение переменной count переменной sum, после чего переменная count увеличит свое значение на 1. То же действие можно задать следующими операторами: sum = count; count = count + 1;
33.Структуры управления на уровне операторов. Способы реализации.
Составной оператор позволяет создавать набор операторов, рассматриваемый как отдельный оператор. В некоторых языках в начало составного оператора можно добавлять объявления данных, превращая его в блок. Язык Pascal не позволяет использовать блоки. Некоторые языки не нуждаются в специальном разграничении составных операторов, интегрируя их в свои управляющие структуры.
Существует один вопрос, связанный с разработкой управляющих структур: может ли управляющая структура иметь несколько входов. Наличие нескольких входов возможно только в языках, которые содержат операторы goto и метки операторов.
Операторы ветвления.
Оператор ветвления (selection statement) предоставляет программисту средства выбора между несколькими путями выполнения программы. Такие операторы являются основными и существенными частями всех языков программирования.
Операторы ветвления разделяются на две основные категории: двухвариантные и n - вариантные, или многовариантные операторы ветвления. В категории двухвариантных операторов ветвления существует вырожденный вид оператора, называемый одновариантным оператором ветвления. Существует также вырожденный многовариантный оператор ветвления, арифметический оператор IF в языке FORTRAN, являющийся трехвариантным оператором ветвления.
Двухвариантные операторы ветвления
Несмотря на то что двухвариантные операторы ветвления в современных императивных языках совершенно одинаковы, вариации в их оценках основываются на совокупности соображений, связанных с разработкой языка.
Вложенные операторы ветвления
Интересная проблема возникает, если допускается вложение двухвариантных конструкций ветвления. Рассмотрим следующий фрагмент кода, напоминающего программу на языке Pascal:
Специальные слова и замыкание оператора ветвления
Операторы цикла (iterative statements) — это операторы, вынуждающие оператор или набор операторов выполняться один и сколько угодно раз, или не выполняться ни разу. Каждый язык программирования содержал некоторый метод для повторения выполнения сегмента кода.
Логически управляемые циклы
Во многих случаях наборы операторов должны выполняться повторно, но управление повторениями основывается на булевских выражениях, а не на счетчике. В этих ситуациях удобно использовать логически управляемые циклы. Действительно, такие циклы представляют собой более общий случай, чем циклы со счетчиком. Каждый цикл со счетчиком можно создать с помощью логически управляемого цикла, но не наоборот. Кроме того, напомним, что только ветвление и логически управляемые циклы играют существенную роль при выражении управляющей структуры в любой блок-схеме
Некоторые императивные языки (например, Pascal, С, C++ и Java) имеют логически управляемые циклы как с предварительной, так и последующей проверкой условий, которые не являются особым видом циклов со счетчиком. В языке C++ циклы с предварительной и последующей проверкой условий имеют следующий вид: while (выражение) тело цикла
34. 35 Подпрограммы. Способы реализации.
Общие свойства подпрограмм
Каждая подпрограмма имеет один вход.
На время выполнения вызываемой подпрограммы выполнение вызывающего ее модуля откладывается. В каждый момент времени выполняется только одна подпрограмма.
Управление после выполнения подпрограммы всегда возвращается в вызывающий модуль.
Подпрограммы разделяются на две различные категории: процедуры и функции, каждая из этих разновидностей может рассматриваться как способ расширения языка. Процедуры представляют собой наборы операторов, определяющих параметризованные вычисления. В действительности процедуры определяют новые операторы. Например, поскольку в языке Pascal нет оператора сортировки, пользователь может создать процедуру для сортировки массива данных и использовать вызов этой процедуры вместо отсутствующего в языке оператора сортировки.
Процедуры могут вырабатывать результаты в вызывающем программном модуле двумя способами. Во-первых, если существуют переменные, не являющиеся формальными параметрами, но остающиеся видимыми и в процедуре и в вызывающем модуле, то процедура может изменять их значения. Во-вторых, если подпрограмма имеет формальные параметры, позволяющие передавать данные в вызывающий модуль, то эти параметры можно изменять.
Функции по своей структуре напоминают процедуры, но они семантически моделируют математические функции. Если функция является точной моделью, то она не имеет побочных эффектов. Это значит, что она не изменяет ни свои параметры, ни какие-либо другие переменные, определенные вне функции.
Методы передачи параметров :
по значению
Когда параметр передается по значению (passed by value), значение фактического параметра используется для инициализации соответствующего формального параметра, который в дальнейшем действует как локальная переменная в подпрограмме, реализуя таким образом семантику режима ввода.
по результату
Передача по результату (pass-by-value) представляет собой модель реализации режима вывода. Когда параметр передается по результату, никакое значение в подпрограмму не передается. Соответствующий параметр действует как локальная переменная, но непосредственно перед возвращением управления обратно в вызывающий модуль его значение передается фактическому параметру, который должен представлять собой переменную. Если возвращается значение (а не путь доступа к нему), как это обычно происходит, передача по результату также требует дополнительной памяти и операций копирования, необходимых для передачи по значению. Как и при передаче по значению, трудности реализации передачи по результату с помощью передачи пути доступа к данным обычно приводят к тому, что она реализуется на основе физического перемещения данных. В этом случае необходимо гарантировать, что первоначальное значение фактического параметра не используется в вызывающем модуле.
комбинационный (при входе в подпрограмму копируется из фактических в формальные, при выходе наоборот)
Передача по значению и результату (pass-by-value-result) представляет собой модель реализации режима ввода-вывода, в котором фактические значения физически перемещаются. Эта модель представляет собой комбинацию передачи по значению и передачи по результату. Значение параметра используется для инициализации соответствующего параметра, который затем действует как локальная переменная.
по ссылке :
Передача по ссылке (pass-by-reference) — это вторая модель реализации режима ввода-вывода. Вместо того, чтобы передавать данные туда и обратно, как при передаче по значению и результату, метод передачи по ссылке передает путь доступа к данным (обычно — просто адрес) в вызываемую подпрограмму. Преимущество передачи по ссылке состоит в том, что процесс передачи эффективен сам по себе с точки зрения как времени, так и пространства. Не требуется ни тиражировать память, ни копировать что-либо.
по имени
Передача по имени (pass-by-name) — это метод передачи параметров в режиме ввода-вывода, не соответствующий какой-то отдельной модели реализации. Когда параметры передаются по имени, фактический параметр в действительности буквально заменяется соответствующим формальным параметром во всех местах подпрограммы, где он появляется. При передаче по имени формальный параметр также связывается с методом доступа во время вызова программы, однако фактическое связывание с некоторым значением или адресом откладывается, пока формальному параметру не будет присвоено какое-нибудь значение, либо на него не будет сделана ссылка. Целью такого позднего связывания в методе передаче параметров по имени является гибкость.
Параметризованные подпрограммы.
Перегруженные подпрограммы.
Доступ к локальным переменным.
Перегруженный оператор имеет несколько значений. Значение конкретного экземпляра перегруженного оператора определяется типами его операндов. Если оператор * имеет два операнда с плавающей точкой в программе на языке С, он означает умножение чисел с плавающей точкой. Однако, если тот же оператор имеет два целочисленных операнда, он означает целочисленное умножение.
Перегруженная подпрограмма (overloaded subprogram) — это подпрограмма, имя которой совпадает с именем другой подпрограммы в той же среде ссылок. Каждая версия перегруженной подпрограммы должна иметь свой уникальный протокол, т.е. она должна отличаться от других версий количеством, порядком, типами своих параметров или типом возвращаемого значения, если она является функцией. Значение вызова перегруженной подпрограммы определяется списком фактических параметров (и/или, возможно, типом возвращаемого значения при использовании функции).
Описание переменной вне подпрограммы.
Блоки глобальных данных.
Реализация подпрограмм
Общая семантика вызовов и возвратов
Вызов подпрограммы и операции возврата управления, взятые вместе, называются связыванием подпрограмм (subprogram linkage). Любой метод реализации подпрограмм должен основываться на семантике связывания подпрограмм.
Вызов подпрограммы содержит механизм передачи параметров. Если локальные переменные не являются статическими, вызов приводит к выделению памяти для локальных переменных, объявленных в вызываемой подпрограмме, и связывает их с этими ячейками памяти. Он должен сохранять текущее состояние выполняемого модуля, вызвавшего подпрограмму; передавать управление коду подпрограммы и гарантировать, что оно будет возвращено в нужное место после выполнения подпрограммы. В заключение вызов должен обеспечить доступ к нелокальным переменным, видимым в вызываемой подпрограмме.
Если параметры подпрограммы передаются в режиме вывода и по копии, при возврате управления вначале следует присвоить фактическим параметрам локальные значения соответствующих формальных параметров. Затем должна быть освобождена память, использованная для хранения локальных переменных, и восстановлено текущее положение вызывающего программного модуля. Для возврата механизма доступа к нелокальным переменным в состояние, в котором он пребывал до вызова подпрограммы, также требуется выполнить несколько действий. Управление должно быть возвращено вызывающему программному модулю.
Реализация подпрограмм
Семантика вызова подпрограмм требует выполнения следующих действий.
Сохранить текущее состояние выполняемого программного модуля.
Передать параметры.
Передать адрес возврата вызываемой подпрограмме.
Передать управление вызываемой подпрограмме.
При возврате из подпрограмм в языке выполняются следующие действия.
Если использовался метод передачи параметров по значению и результату, текущие значения этих параметров присваиваются соответствующим фактическим параметрам.
Если подпрограмма представляет собой функцию, то значение функции перемещается в место, доступное вызывающему модулю.
Восстанавливается первоначальное текущее состояние вызывающего модуля.
Управление передается назад вызывающему модулю.
Действия, связанные с вызовом и возвратом, требуют выделения памяти для следующих данных.
Информация о состоянии вызывающего модуля.
Параметры.
Адрес возврата.
Возвращаемое значение функции.
Подпрограмма состоит из двух отдельных частей: кода подпрограммы (являющегося неизменным), локальных переменных и данных (которые могут изменяться при выполнении подпрограммы). Формат, или структура, части подпрограммы, не являющейся кодом, называется записью активации (activation record), или активационной записью, поскольку данные, которые она описывает, относятся только к активации подпрограммы. Форма записи активации является статичной. Экземпляр записи активации (activation record instance) — это конкретный образец записи активации, или набор данных в форме активационной записи.
Рекурсивный вызов