
- •Компиляция. Основные понятия. Контекст компилятора
- •Этапы, фазы и проходы
- •Фаза анализа. Основные понятия.
- •Фаза синтеза. Основные понятия.
- •Методы определения языка
- •Понятие регулярных выражений
- •Понятие грамматики
- •8.Иерархия грамматик по Хомскому
- •9 . Порождения синтаксические деревья
- •Неоднозначность
- •11.Понятие лексического анализа
- •12.Лексический анализ с помощью регулярных выражений
- •Лексический анализ с помощью конечных автоматов
- •14. Лексический анализ с помощью Lex
- •15. Нисходящий анализ. Критерии принятия решений.
- •16. Понятие ll(1)-грамматики
- •17. Рекурсивный спуск. Расширенная форма записи правил для исключения рекурсивных вызовов.
- •18. Рекурсивный спуск. Комбинирование рекурсии и итерации.
- •19. Преобразование грамматик. Удаление левой рекурсии
- •20. Преобразование грамматик. Факторизация
- •21. Введение действий в грамматику
- •22. Восходящий синтаксический анализ. Основные понятия. Критерий принятия решений
- •Восходящий синтаксический анализ. Таблица синтаксического анализа.
- •25. Характеристический конечный автомат.
- •Восходящий синтаксический анализ. Slr(1), lalr(1), общий алгоритм формирования таблицы lr(1)-анализа.
- •Восходящий синтаксический анализ. Генератор восходящих анализаторов yacc. Основные понятия.
- •Семантический анализ. Не-контекстно-свободные характеристики языков.
- •Семантический анализ. Таблица символов.
- •Семантический анализ. Таблица типов.
- •31.Семантический анализ. Таблицы функций. Таблицы меток
- •32. Распределение памяти. Классификация памяти
- •33. Распределение памяти. Стек времени выполнения. Определение области видимости.
- •34. Распределение памяти. Стековый фрейм.
- •35. Распределение памяти. Дисплей.
- •35. Адреса времени компиляции. Простые адреса. Адресация элементов статического массива.
- •37. Распределение памяти. Адреса времени компиляции. Адреса динамического массива
- •38. Куча. Основные понятия. Методы автоматического освобождения памяти.
32. Распределение памяти. Классификация памяти
Переменная х является объектом, который в данное время может иметь соотнесенное с ним значение, занимающее определенный объем памяти. Память, выделенная значению х, имеет адрес, который позволяет обращаться к х, причем адрес должен иметь следующие свойства.
Быть достаточно большим (максимально необходимым), чтобы вместить любое из значений, которое может принимать х.
Быть доступным в течение всего времени существования х.
Должна существовать возможность его выражения в такой форме, чтобы генератор кода мог пользоваться адресом для получения доступа к значению х во время выполнения программы.
Относительно первого требования нужно отметить, что целые значения обычно занимают меньше памяти, чем действительные, а символьные значения могут занимать меньше памяти, чем целые. Для обеспечения эффективного доступа не всегда имеет смысл уплотнять в памяти значения до максимально возможной степени.
Память требуется для значений записей, массивов и указателей. Память, требуемая для записей, обычно равна сумме объемов памяти, требуемых для каждого поля записи. Для массивов требуется больше памяти, чем для составляющих их элементов; избыток зависит от способа хранения массива. Кроме того, некоторые языки допускают наличие у массивов динамических границ, следовательно, в процессе компиляции размер массива неизвестен и будет определен уже во время выполнения программы. Объем памяти, необходимой для указателей, зависит от реализации.
В связи с тем, что память выделяется на все время жизни переменной, возможны следующие ситуации.
Время жизни переменной равно времени жизни программы. В этом случае выделенная для переменной область памяти уже не может быть освобождена. Такую память называют статической.
Переменная объявляется в каком-то конкретном блоке, функции или процедуре. В этом случае после завершения выполнения блока, функции или процедуры выделенную для переменной память можно освободить. Такую память называют динамической.
Память может выделяться значениям в определенный момент выполнения программы, не обязательно совпадающий с началом блока или входом процедуры. Память выделяется в этот момент времени и существует до тех пор, пока не будет освобождена – либо посредством соответствующего механизма языка, либо после того, как просто станет недоступной для программы. Сам момент освобождения памяти, в общем случае, может не определяться при компиляции, а станет известным только во время выполнения программы. Такую память называют глобальной.
Требования к статической памяти полностью определяются во время компиляции, так что необходимый объем может быть выделен. Поскольку выделенную статическую память освободить невозможно, общий объем такой памяти является суммой ее частных составляющих, при этом какое-либо “совместное использование” этой памяти невозможно.
Требования к динамической памяти программы сложнее, поскольку память распределяется на входе функции (подпрограммы), а освобождается после выполнения функции (подпрограммы). В этом случае существует возможность совместного использования этой памяти значениями, относящимися к различным функциям и т.д. Оказывается, что управление этим типом памяти не настолько сложно, как может показаться на первый взгляд, и его легко осуществить посредством механизма стека, который увеличивается и уменьшается при выделении и освобождении памяти.