Читаем Редкая профессия полностью

Синтаксис языка Си++ неудобен еще и в другом отношении. Если говорить коротко, то прямое использование в формальном описании одного из базовых синтаксических понятий — идентификатора — приводит к тому, что YACC расценивает грамматику языка как некорректную и на ее основе не может построить синтаксический анализатор. Для традиционных языков синтаксическому анализатору для разбора конструкции достаточно информации о том, что в данной позиции этой конструкции может (или должен) находиться идентификатор. Более простые языки сконструированы так, что семантика идентификатора не влияет на корректность синтаксического разбора. Вид программной сущности, обозначаемой этим идентификатором (подпрограмма, переменная, имя типа, исключение, метка и т.п.), смысл данного конкретного вхождения (объявление или использование) — все это выявляется далее, как правило, являясь предметом следующей фазы компиляции — семантического анализа.

Для языка Си++ такая схема не проходит. Чтобы быть в состоянии синтаксически распознать многие конструкции, требовалась семантическая интерпретация имени. Иными словами, на вход синтаксическому анализатору следовало поставлять не абстрактную лексему "идентификатор", а результат анализа того, что именно представляет собой этот идентификатор: "имя типа", "новое имя в объявлении", "имя не-типа в выражении" и т.д. Заметим, что синтаксическому анализатору для Java — непосредственного потомка Си++ — вполне хватает понятия идентификатора без каких-либо уточнений.

Всего для Си++ получилось около десятка таких "суперлексем", а лексема "идентификатор" вообще исчезла из синтаксиса. Понятно, что лексический анализатор, который и поставляет лексемы, пришлось наделить дополнительным "интеллектом". Теперь он должен был не просто выделять из текста программы очередную лексему, но и обращаться в таблицы трансляции за информацией о том, что за идентификатор он выловил. Реально эти действия выполняет отдельный модуль, названный "расширенным лексическим анализатором". Введение дополнительного модуля не привело к усложнению компилятора в целом, так как идентификация имен так или иначе должна производиться; мы просто перенесли ее на более ранний этап компиляции. А синтаксис заметно упростился, стал более наглядным, информативным и в конечном счете более эффективным.

Компилятор как таковой: таблицы и деревья

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

Есть два основных вида семантической информации, которые компилятор извлекает из текста исходной программы. Во-первых, это информация о различных объектах, которые используются в программе (переменные, типы, функции и т.д.), причем не только об объектах как таковых, но и об областях действия, в которых эти объекты существуют (имеют смысл), а также об отношениях этих областей между собой (контекстах). Чем сложнее устроен язык, тем больше в нем правил, связанных с объектами, и тем более изощренной должна быть та структура в компиляторе, которая описанную информацию содержит. Такая структура обычно называется семантическими таблицами.

Во-вторых, компилятор должен формировать некоторый образ исходной программы — внутреннее представление программы в целом или ее некоторой части, которая в данный момент обрабатывается. Именно на основе такой структуры обычно выполняется семантический анализ программы, производятся различные оптимизации и осуществляется генерация результирующего кода. Как правило, такое внутреннее представление строится в виде дерева и потому называется деревом программы.

Эта пара — таблицы и деревья, вместе с различными алгоритмами, работающими над ними, без преувеличения составляет две трети текста компилятора. Почти вся наша работа на протяжении всех этих лет так или иначе была связана с ними.

Структура таблиц была придумана в целом по образцам из книг по теории и практике компиляции, которые в изобилии выходили у нас в 70-80-х годах и описывали, как правило, языки с относительно простой и, самое главное, регулярной структурой и несложной семантикой,-- такие как Алгол-60, Паскаль, Модула-2. Многое из того, что есть в Си++, с трудом "втискивалось" в академические построения, и приходилось дополнять и развивать их. В результате таблицы представляют собой причудливую смесь классической стековой модели с дисплеем для отображения текущего контекста и наворотов вроде средств динамического перестроения контекста для обработки функций-членов классов, нетривиальной поддержки областей действия имен (namespaces), буферов для отложенной компиляции и т.д. К тому же таблицы должны быть динамически расширяемыми, чтобы быть в состоянии вобрать в себя очень большое количество имен, типичное для программ на Си++. Помучиться пришлось изрядно, и далеко не сразу таблицы заработали стабильно и надежно.

Перейти на страницу:

Похожие книги

Киберкрепость: всестороннее руководство по компьютерной безопасности
Киберкрепость: всестороннее руководство по компьютерной безопасности

Как обеспечить надежную защиту в эпоху, когда кибератаки становятся все более продвинутыми? Каковы последствия уязвимости цифровых систем? Петр Левашов, экс-хакер с богатым бэкграундом, рассматривает все грани кибербезопасности, начиная с базовых принципов и заканчивая новейшими технологиями.Читатели познакомятся с:• основами компьютерной безопасности и актуальными методами защиты;• современными методами шифрования данных и криптографии;• процедурами ответа на инциденты и восстановления после катастроф;• юридическими и регуляторными требованиями к компьютерной безопасности.Автор использует свой уникальный опыт, чтобы предоставить читателям углубленное понимание кибербезопасности. Его подход охватывает теоретические знания и практическую подготовку, делая этот материал доступным для профессионалов и новичков.

Пётр Юрьевич Левашов

Зарубежная компьютерная, околокомпьютерная литература
Информатика: аппаратные средства персонального компьютера
Информатика: аппаратные средства персонального компьютера

Рассмотрены основы информатики и описаны современные аппаратные средства персонального компьютера. Сформулированы подходы к определению основных понятий в области информатики и раскрыто их содержание. Дана классификация современных аппаратных средств персонального компьютера и приведены их основные характеристики. Все основные положения иллюстрированы примерами, в которых при решении конкретных задач используются соответствующие программные средства.Рекомендуется для подготовки по дисциплине «Информатика». Для студентов, аспирантов, преподавателей вузов и всех интересующихся вопросами современных информационных технологий.

Владимир Николаевич Яшин

Зарубежная компьютерная, околокомпьютерная литература / Прочая компьютерная литература / Книги по IT