Израилов К.Е. Введение Принцип действия компилятора Компилируемый язык Структура компилятора Пример работы Создание компиляторов Полезные применения Безопасность кода Заключение P.S. Вопросы на смекалку Компилятор (compiler) – программа, выполняющая компиляцию Компиляция – трансляция программы из высокоуровневого языка в низкоуровневый Высокоуровневый язык – абстрактный, удобный, понятный человеку (C, Pascal, C#) Низкоуровневый язык – близкий к машинному коду (ASM, CIL) Создание выполняемого кода (основное) Разбор конфигурационных файлов Генерация промежуточного кода Поддержка предметно-ориентированных языков, нацеленных на конкретную область ◦ C++ -> ASM ◦ my.cfg -> (binary data) ◦ (language + code) -> my.cpp ◦ DSL (Domain Specific Language) Конвертация кода Декомпиляция ◦ C -> C++ ◦ ASM -> C Компилятор Исходный код программы Синтаксис входного язык Синтаксис выходного языка Выполняемый код программы Сущность, идея, мысль (содержание) Компьютер (объект) Человек (субъект) Компилятор Исходный код программы Внутреннее представление программы Выполняемый код программы Дружелюбный Русский Алгоритмический язык, Который Обеспечивает Наглядность Учитывает потребности двух аудиторий: • Дракон-схемы для не-программистов • Язык разработки для программистов Токен (лексема) – последовательность символов, имеющих смысл Лексика – определяет последовательность «правильных» символов для программы Синтаксис – определяет структуру программы Семантика – определяет смысл программы Формальная грамматика – способ описания формального языка с помощью Правил (Лексика + Синтаксис) Правило – описывает «правильную» последовательность токенов и др. правил Лексика ◦ Определяет преобразование символов в токены [ма]: ‘м’ + ‘а’ + ‘м’ + ‘а’ -> “мама” Грамматика ◦ Определяет правильность расположения токенов “мама” + “моет” + “раму” Семантика ◦ Определяет смысл структур токенов Подлежащее: “мама” Сказуемое: “моет” Дополнение: “раму” Компилятор Фаза FrontEnd Фаза MiddleEnd Фаза BackEnd Лексический анализ Семантический анализ Генерация Синтаксический анализ Преобразования Оптимизация Языковая специфика: C, C++, Pascal, C# Полная независимость: обобщенные алг. • Платформенная специфика: PowerPC, MIPS Преобразовывает символы в токены ◦ “мама мыла раму” -> [“мама”, “мыла”, “раму”] Разбирает токены согласно синтаксису ◦ (T_word)+ => T_мама T_мыла T_раму Строит абстрактное дерево синтаксиса ◦ T_мама T_мыла T_раму = T_word (мама) T_word (мыла) T_word (раму) Диагностирует ошибки ◦ Syntax Error: “Мама пишется с большой буквы” Определение семантики кода ◦ Подлежащее-сказуемое-дополнение => (T_мама)-(T_мыла)-(T_раму)-(.) Преобразование ◦ (IR_человек)-(IR_действие)-(IR_предмет) => (T_мама)-(T_мыла)-(T_раму) -> (IR_мама)-(IR_мыла)-(IR_раму) Оптимизация Диагностика ошибок ◦ (IR_мама)-(IR_мыла)-(IR_раму)-(IR_пылесосом) ◦ Semantic error: “Рамы моют Папы вместо Мам” Генерирует выходной код ◦ (IR_мама)-(IR_мыла)-(IR_раму)-(IR_пылесосом) => ◦ Заказ-наряд: Заказчик: Папа Работник: Мама Операция: Мытье Предмет: Рама Комментарий: Пылесосом и быстро! Типы ошибок: ◦ Лексическая, синтаксическая, семантическая, др. Пример 1. ◦ X=10 +-20 Пример 2. ◦ 10+20=X Семантическая ошибка Пример 3. ◦ X+++++Y -> Internal Error Синтаксическая ошибка Пример 4. ◦ X=1’0 + 20 Другая ошибка Лексическая ошибка 1+2*3 Формальная грамматика: ◦ Expression: Operand | Operand Operator Expression ; ◦ Operator: 1+ 2 * 3 ‘+’ | ‘-’ | ‘*’ | ‘/’ ; ◦ Operand: [‘0’-’9’]+ Expression Operator : Operand + - * / Operator Operand Operand 0 … 9 + BackEnd MiddleEnd FrontEnd “1+2*3” [‘1’, ‘+’, ‘2’, ‘*’, ‘3] List of Tokens Input Text OPR (+) OPN (1) Intermediate Repres. Tree OPR (*) OPN (2) Output Text OPN (3) “7” 1 Abstract Syntax Tree Intermediate Repres. Tree (optimized) * 2 3 OPR (7) Компилятор Лексический анализатор (ЛА) Генераторы ЛА: LEX (FLEX, JLEX) “папа” “мама” “мыла” “рыла” “ра”[“му”|”ну”] { return T_ПАПА; } { return T_МАМА; } { return T_МЫЛА; } { return T_РЫЛА; } { return T_ЧТОТО; } Синтаксический анализатор (ЛА) Генератор СА: YACC (BISON, ANTLR+GUI) Предложение: Подлежащее Сказуемое Дополнение ; Подлежащее: T_МАМА | T_ПАПА ; Сказуемое: T_МЫЛА | T_РЫЛА ; Дополнение: T_ЧТОТО ; Подсказка: ◦ GNU = GNU’s Not UNIX (рекурсивный акроним) Акроним: Yet - еще Another - один Compiler - компилятор Compiler - компиляторов А если компилятор злоумышленника? Компилятор Уязвимости Программа Машинный код Наличие открытого исходного кода ◦ Анализ алгоритмов работы компилятора Специализированное тестирование ◦ Тесты для выявления в работе компилятора небезопасных действий Тестирование машинного кода ◦ Фаза проверки кода после компиляции Топологическое сравнение машинного кода проверяемого компилятора и шаблонного ◦ Наличие безопасного компилятора и алгоритмов сравнения кода Компиляторы ◦ ◦ ◦ ◦ ◦ Используются повсеместно Делаются не только богами Удобны для формализации и обработки данных Основа для любых конвертеров кода Будут жить вечно Уязвимости ◦ Могут внедрятся на этапе компиляции %% Questions: ◦ /* empty */ { printf(“Thanks for attention!”); } | ◦ Question | ◦ Question Questions ; Question: ◦ (‘ ‘ | Letter)+ ‘?’ { printf(“%s?\n”, $1); printf(“%s!\n”, theAnswers.find($1)->text); } %%