
- •Вопрос 1
- •Определение 1.3. Цепочка, которая не содержит ни одного символа, называется пустой цепочкой и обозначается .
- •Определение 1.13. Цепочка , для которой существует вывод s*, называется сентенциальной формой или сентенцией в грамматике .
- •Вопрос 2
- •Вопрос 3
- •Расширение допускает единственное -правило вида s, но в этом случае начальный символ грамматики s не должен встречаться в правых частях правил.
- •Вопрос 4
- •3.1.2 Дерево разбора
- •Вопрос 5
- •Вопрос 6
- •Вопрос 7
- •Вопрос 8
- •Существуют следующие три способа представления функции переходов.
- •Вопрос 9 Алгоритм 2.4. Построение ка по регулярной грамматике.
- •Выход: ка .
- •Вопрос 10
- •Алгоритм 2.1. Преобразование нка в дка.
- •Вопрос 11
- •Алгоритм 2.2. Устранение недостижимых состояний ка.
- •Алгоритм 2.3. Объединение эквивалентных состояний ка.
- •Вопрос12
- •3.2.1 Проверка существования языка грамматики
- •3.2.2 Удаление бесполезных символов грамматики
- •Алгоритм 3.2. Устранение нетерминалов, не порождающих терминальных строк. Вход: кс-грамматика .
- •Алгоритм 3.3. Устранение недостижимых символов грамматики. Вход: кс-грамматика .
- •Определим множество достижимых символов z грамматики g, т.Е. Множество:
- •Вопрос13
- •3.2.3 Устранение -правил грамматики Алгоритм 3.4. Устранение -правил. Вход: кс-грамматика .
- •3.2.4 Устранение цепных правил Алгоритм 3.5. Устранение цепных правил. Вход: кс-грамматика .
- •Вопрос 14 Алгоритм 3.6. Устранение левой факторизации правил. Вход: кс-грамматика .
- •Алгоритм 3.7. Устранение прямой левой рекурсии. Вход: кс-грамматика .
- •Вопрос 15
- •Вопрос 16 Алгоритм 3.9. Построение мп-автомата по кс-грамматике.
- •Вопрос 17
- •Вопрос 18
- •18. 3.4.1 Рекурсивный спуск
- •Теорема 3.1. Достаточные условия применимости метода рекурсивного спуска.
- •Вопрос 19
- •Вопрос 20
- •Вопрос 21
- •21. Функционирование распознавателя цепочек для ll(1)-грамматик.
- •Вопрос 22
- •Вопрос 23 Алгоритм 3.16. Построение множеств l(a) и r(a).
- •Вопрос 24
- •Вопрос 26
- •Вопрос 27
- •Вопрос28
- •Вопрос 29
- •Вопрос 30
- •Вопрос 31
- •Вопрос 32. Определение 4.1. Транслятор – это программа, которая переводит входную программу на исходном (входном) языке в эквивалентную ей выходную программу на результирующем (выходном) языке.
- •Вопрос 33 Общая схема работы компилятора
- •Вопрос 34 ЛекАнализ программы
- •Вопрос 35
- •Вопрос 36
- •Вопрос 37
- •Вопрос 38
- •Вопрос 39
- •Вопрос 40
- •Вопрос 41 Свертка объектного кода программы.
- •Вопрос 42
- •Вопрос 43
- •Вопрос 44
- •Вопрос 45 Схемы компиляции
- •Вопрос 46
- •Вопрос 47
- •Вопрос 48
- •Вопрос 49
- •Вопрос 50
Вопрос 43
Оптимизация логических выражений
Компиляторы строят объектный код вычисления логических выражений таким образом, что вычисление выражения прекращается сразу же, как только его значение становится предопределенным. В сочетании с преобразованиями логических выражений на основе тождеств булевой алгебры и перестановкой операций эффективность данного метода может быть несколько увеличена.
Определение 4.19. Операция называется предопределенной для некоторого значения операнда, если ее результат зависит только от этого операнда и остается неизменным (инвариантным) относительно значений других операндов.
Пример 4.17. Операция логического сложения (or) является предопределенной для логического значения «истина» (true), а операция логического умножения (and) предопределена для логического значения «ложь» (false).
Поэтому, например, выражение А and В and С and D не имеет смысла вычислять, если известно, что значение переменной А есть false.
Оптимизация циклов
Для оптимизации циклов используются следующие методы:
- вынесение инвариантных вычислений из циклов;
- замена операций с индуктивными переменными;
- слияние и развертывание циклов.
Вынесение инвариантных вычислений из циклов заключается в вынесении за пределы циклов тех операций, операнды которых не изменяются в процессе выполнения цикла. Такие операции могут быть выполнены один раз до начала цикла, а полученные результаты потом могут использоваться в теле цикла.
Пример 4.18. Рассмотрим цикл for i:=l to 100 do K[i]:= K[i]/(A*B).
После применения оптимизирующего преобразования цикл будет иметь вид:
C:= A*B;
for i:=l to 100 do K[i]:= K[i]/C.
Замена операций с индуктивными переменными заключается в изменении сложных операций с индуктивными переменными в теле цикла более простыми операциями. Как правило, выполняется замена умножения на сложение.
Определение 4.20. Переменная называется индуктивной в цикле, если ее значения в процессе выполнения цикла образуют арифметическую прогрессию.
Если индуктивных переменных в цикле несколько, то в теле цикла их можно заменить на одну, а реальные значения для каждой переменной будут вычисляться с помощью соответствующих коэффициентов соотношения. Простейшей индуктивной переменной является переменная-счетчик цикла.
Пример 4.18. Рассмотрим цикл for i:=l to N do K[i]:=i*100.
После применения оптимизирующего преобразования, цикл будет иметь вид:
T:= 100; i:= 1;
while i<=N do
begin
K[i]:= T;
T:= T+100;
i:= i +1;
end;
Слияние циклов предусматривает замену двух вложенных циклов одним.
Пример 4.19. Рассмотрим фрагмент программы, инициализирующий двумерный массив:
for i:=l to N do
for j:=l to M do A[i, j]:=0.
С точки зрения объектного кода (но не с позиции семантики исходного языка) двумерный массив - это область памяти размером N*M, поэтому данную операцию можно представить так:
К:= N*M;
for i:=1 to К do A[i]:= 0.
Развертывание циклов – это замена цикла линейной последовательностью операций. Данную замену можно выполнить для циклов, кратность выполнения которых известна уже на этапе компиляции. Тогда цикл, кратностью N, можно заменить линейной последовательность N операций, содержащих тело цикла.
Пример 4.20. Цикл for i:=1 to 3 do A[i]:= i* i можно заменить операциями:
A[1] := 1; A[2] := 4; A[3] := 9.