Rus Eng
О компании  
Новости компании
Лицензии и сертификаты
Вакансии
Контакты
Публикации
White Paper
Продукты
Технологии
Разработчикам ПО
Производителям микроконтроллеров
Партнеры / Клиенты
Перспективные проекты
| | | |
Главная страница    О компании    Публикации    Принципы и методы создания компилятора переднего плана Стандарта Си++
Принципы и методы создания компилятора переднего плана Стандарта Си++

Московский Государственный Университет

им. М.В.Ломоносова

Факультет Вычислительной математики и кибернетики

На правах рукописи
УДК 000.0.000

ЗУЕВ ЕВГЕНИЙ АЛЕКСАНДРОВИЧ

Принципы и методы создания компилятора переднего плана Стандарта Си++

05.13.11 - математическое и программное обеспечение вычислительных машин, комплексов, систем и сетей

Автореферат
диссертации на соискание ученой степени
кандидата физико-математических наук



Москва 1999

Работа выполнена в Научно-исследовательском вычислительном центре Московского государственного университета им. М.В. Ломоносова.

Научный руководитель: доктор технических наук, профессор

Сухомлин Владимир Александрович

Официальные опоненты: доктор физико-математических наук,

профессор

Томилин Александр Николаевич,

кандидат технических наук

Волконский Владимир Юрьевич

Ведущая организация:

Институт прикладной математики РАН

Защита состоится 15 октября 1999 г. в _____ часов на заседании специализированного совета К.053.05.84 в МГУ по адресу: 119899, Москва, ГСП, Ленинские горы, Научно-исследовательский вычислительный центр, конференц-зал.

С диссертацией можно ознакомиться в библиотеке Научно-исследовательского центра МГУ.

Автореферат разослан 15 сентября 1999 г.

Ученый секретарь специализированного совета кандидат физико-математических наук В.А.Суворов


Общая характеристика работы
Актуальность работы

Развитие языков программирования (ЯП) и соответствующих инструментальных средств разработки представляет собой одно из основополагающих направлений современной информатики, технологии и практики индустриального программирования. Потребность в мощных, гибких и надежных языковых инструментах, адекватных предельному уровню сложности и ответственности задач, решаемых программным обеспечением (ПО), определяет высокую активность исследований и разработок в данной области.

В настоящее время наиболее актуальными в данном направлении информатики представляются две тенденции, связанные с проектированием и реализацией ЯП.

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

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

Цель исследования

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

В соответствии с этой целью были определены следующие задачи:

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

В процессе проведения исследований автором получены следующие результаты:

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

Результаты, полученные в работе, изложены в ряде печатных публикаций, докладывались на научных конференциях и семинарах, в частности:

    • на Первой российской конференции "Индустрия программирования'96", Москва, 3-4 октября 1996 г.;
    • на IV Международной конференции "Развитие и применение открытых систем", Н.Новгород, 27-31 октября 1997 г.;
    • на Интернет-форуме компании Инфоарт "Языки программирования и Интернет", июль 1998;
    • на Ломоносовских чтениях в МГУ им. Ломоносова в 1993-1999 гг.
Научная новизна работы

Научная новизна представляемой работы может быть охарактеризована следующими тезисами:

1. Исследованы современные тенденции создания средств и систем программирования, ориентированных на промышленное использование.

2. На основе выполненных исследований разработаны архитектура и принципы построения компилятора переднего плана языка Си++ как системообразующего ядра многоцелевой системы программирования, включающей набор компонент для выполнения различных операций над текстами программ.

3. На основе анализа синтаксиса Си++ разработан и реализован подход к построению лексического и синтаксического анализаторов Си++, названный непрерывной компиляцией, который обеспечивает высокую эффективность анализаторов. В частности, предложен и обоснован перенос алгоритмов идентификации имен (в том числе составных имен) на фазу лексического анализа.

4. Проведен подробный анализ понятия области действия Си++, предложена и реализована модель семантических таблиц компилятора, адекватно отражающая это понятие.

5. Исследована семантика параметризуемых типов и алгоритмов Си++, предложены и реализованы принципы реализации механизма шаблонов в компиляторе переднего плана. Показана адекватность модели семантических таблиц семантике шаблонов классов и функций.

Практическая ценность

На основе исследований, выполненных по теме диссертации, разработаны следующие программные системы:

    • Компилятор переднего плана языка Си++, соответствующий версии предварительного стандарта Си++ от октября 1994 г., вошел в состав многоязыковй системы программирования компании ACE (Голландия) для компьютеров Sun и Sparc.
    • Компилятор переднего плана, соответствующий предварительному стандарту Си++ от декабря 1996 г., является ядром кросс-системы программирования для цифрового нейронного процессора NM6401, разработанного НТЦ "Модуль" (Москва).
    • Компилятор переднего плана, соответствующий окончательной версии международного стандарта Си++ ISO/IEC 14882:1998, передан компании МедиаЛингва:Компиляторы (Москва) для включения в создаваемую систему программирования Си++, ориентированную на цели обучения.
Структура и объем работы

Диссертация состоит из введения, четырех глав, заключения и списка литературы из 126 наименований. Объем диссертации составляет 160 страниц текста. Диссертация содержит 12 рисунков и 3 таблицы.

Содержание работы
Введение

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

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

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

Тенденция стандартизации ЯП рассмотрена на примере двух языков промышленного назначения - Си++ и Ада. Кратко излагаются обстоятельства их разработки, обсуждаются предпосылки и требования к стандартам, прослеживается процесс стандартизации этих языков.

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

Приведенные соображения одновременно могут служить аргументами для выбора Си++ как предмета исследований и объекта компиляции.

Далее во введении обсуждается вторая тенденция, связанная с изменением взглядов на задачу компиляции. Долгое время основным инструментарием разработчика ПО служил традиционный компилятор некоторого языка программирования, генерирующий объектный код для конкретной аппаратной платформы.

Возрастающая сложность программных систем, индустриализация процесса их создания, повышенные требования к их надежности и необходимость увеличения производительности труда разработчиков ПО привели к необходимости "некомпилирующих" системных средств. Примерами служат символьные отладчики, системы анализа программ, в частности, инструменты обратной инженерии (reverse engineering). Требования расширения арсенала разработчиков привели к частичному переосмыслению задачи компиляции. Теперь результирующий код, сформированный компилятором, трактуется не только как объект, подлежащий выполнению, но и как исходная информация для проведения ряда качественно иных работ. Кратко обсуждается спектр операций с программными текстами, являющихся в настоящее время наиболее актуальными. К их числу относятся:

    • Компиляция программ в собственном смысле;
    • Средства анализа структурных, информационных и динамических свойств свойств программ, в частности, поддержка методик графического представления программ;
    • Верификация программ, в том числе, проверка правил и стиля программирования;
    • Статический анализ программ, вычисление и интерпретация формальных метрических характеристик;
    • Интерпретация программ в целях отладки, динамического анализа (профилирования) и тестирования.

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

Таким образом, утверждается, что традиционная модель "компилятор - генератор - объектный код - дополнительные инструменты" вытесняется более универсальной, мощной и гибкой моделью "компилятор переднего плана - промежуточное представление - набор инструментов разработки". Это положение является одним из центральных тезисов диссертационной работы. Оно схематически иллюстрируется следующим рисунком:



В дополнение к проведенному рассмотрению обсуждаются три весьма важных и характерных подхода к созданию систем программирования, в которых модель "компилятор переднего плана - промежуточное представление программы" играет центральную роль. Речь идет следующих актуальных направлениях:

    • многоязыковые и многоплатформенные системы программирования;
    • продвинутые схемы комплексирования программ;
    • концепция семантического интерфейса.
Основной идеей, лежащей в основе многоязыковых и многоплатформенных систем, является сокращение общего числа компонент за счет выделения общей для всех компонент функциональности. Следствием этого является введение универсального интерфейса компонент переднего плана и "конечных" компонент (back-ends), в роли которого выступает промежуточное представление.

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

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

Необходимость преодоления указанных недостатков традиционной схемы комплексирования привела к появлению альтернативной схемы, которая состоит в следующем. Компилятор преобразует текст единицы трансляции не в ассемблерный код конкретного процессора, а в некоторое промежуточное представление. Образы модулей программы комплексируются, в результате чего формируется промежуточное представление всей программы в целом. Далее этот программный образ обрабатывается оптимизатором и генератором кода. Таким образом, на завершающих этапах - при формировании результирующего кода - имеется полная информация обо всей программе, что позволяет выполнять обширный комплекс локальных, глобальных и межпроцедурных оптимизаций. Далее, такой подход позволяет значительно усовершенствовать методы разработки программ и стиль программирования, отказавшись от архаичного механизма межмодульного взаимодействия языков Си и Си++, специфицируемого посредством include-файлов. Продвинутая схема комплексирования позволяет решить проблемы контроля межмодульных связей, используя единый репозиторий программного проекта, представленный в виде промежуточного представления.

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

К настоящему времени потребность стандартизованного семантического интерфейса к программам на том или ином языке программирования осознана в достаточной степени, чтобы учитывать ее при рассмотрении вопросов компиляции. Дело в том, что для реализации практически полезного интерфейса доступа к программам в большинстве случаев недостаточно простого синтаксического анализа. Значительная часть сведений, которые необходимо получать посредством подобного интерфейса, носит существенно семантический характер. Очевидным примером служит задача получения любой информации, связанной с типами объектов и с отношениями между этими типами. Дополнительную нетривиальность добавляет этой задаче развитая система типов современных ЯП и, в частности, объектная ориентация промышленных языков (в частности, множественное и виртуальное наследование), а также наличие механизма настраиваемых типов; благодаря этой нетривиальности извлечение знания об иерархии и свойствах типов возможно только на основе алгоритмов семантического анализа, характерных для компиляторов.

Заметный толчок концепция семантического интерфейса получила в связи с процессом разработки и принятия в 1998 году Международного Стандарта ASIS (Ada Semantic Interface Specification). Тесную связь между задачей компиляции и реализацией семантического интерфейса можно проиллюстрировать подходом, принятым при реализации этого стандарта для Ада-компилятора GNAT. Интерфейсные запросы, входящие в состав ASIS, реализуются на основе доступа к промежуточному представлению (аннотированному дереву программы и таблице символов), формируемому компилятором GNAT и доступному его клиентам. Таким образом, компилятор переднего плана берет на себя всю работу по синтаксическому и семантическому анализу входной программы, а интерфейс ASIS выступает в качестве стандартной "прослойки" между промежуточным представлением и специализированными конечными процессорами ("back-ends").

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

На основании проведенных рассмотрений во Введении предлагается следующая принципиальная модель ядра системы программирования для языка Си++. Модель (см. рис.) включает две сущности: компилятор переднего плана Си++ и промежуточное представление программы на Си++.



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

В заключение автором обосновывается выбор языка Си++ как основного предмета исследований и формулируются цели и задачи диссертации.

Глава 1

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

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

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

Раздел 1.2 посвящен двум начальным фазам компиляции. Оригинальные формулировки стандарта, определяющие эти фазы, сводятся к следующим четырем операциям:

    1. Преобразование символов исходного текста в базовое множество исходных символов.
    2. Замена триграфов на эквивалентные односимвольные представления.
    3. Замена "расширенных" символов соответствующими универсальными-именами-символов.
    4. "Склеивание" строк исходного текста.

Далее подробно обсуждается семантика этих операций и на основе проведенных рассмотрений выдвигаются требования к реализации важнейших операций - 1 и 3.

Раздел 1.3 содержит подробное рассмотрение фаз 3-4, основным содержанием которых является препроцессорная обработка исходного текста. Обсуждается существо этих фаз, традиционные подходы к их реализации и историческая обусловленность введения средств препроцессирования в Стандарт Си++. Резюмируются достоинства и недостатки препроцесорной схемы и делается вывод об отсутствии принципиальной необходимости реализовывать этап препроцессирования в виде отдельной компоненты системы программирования (СП). Обосновываются выгоды интеграции этих фаз в традиционный этап лексического анализа.

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

Раздел 1.4 завершает рассмотрение фаз трансляции. Кратко рассматривается существо и методы реализации промежуточных пятой и шестой фаз. Основное внимание уделяется завершающему этапу лексического анализа (фаза 7.1) - преобразованию лексем препроцессора в лексемы, поступающие на вход синтаксическому анализатору. Подробно рассматриваются семантические различия понятий лексемы (token) и лексемы препроцессора (pp-token) и соответствующие операции преобразования.

В заключение данного раздела формулируются общие выводы относительно реализации лексического разбора.

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

2. Вместо последовательности операций, преобразующих исходный текст (и, далее, единицу трансляции) из одного представления в другое, лексический разбор рассматривается как единый неразрывный процесс, определенный над общей структурой лексемы. Этот процесс реализуется одной компонентой компилятора - лексическим анализатором. Различные варианты последовательностей преобразований (например, с препроцессированием или без него) задаются в виде режимов такого анализатора.

3. Наиболее удобной и простой схемой взаимодействия лексического анализатора с другими компонентами компилятора (прежде всего, с синтаксическим анализатором) представляется обычная подпрограммная связь.

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

В разделе 1.5, завершающем первую главу, рассматривается лексическая структура языка Си++ как таковая, абстрагируясь от способов конкретной реализации лексического анализа и рассматривая фазы 1-6 и начало фазы 7 как единый процесс.

В данном разделе обсуждается внутреннее представление лексемы в компиляторе; структура этого представления должна обеспечить сохранение всей необходимой информации как собственно о лексеме, так и о контексте ее вхождения в исходный текст. Далее проводится классификация множества лексем Си++ согласно Стандарту.

Основным содержанием раздела является описание принципов модификции множества лексем, которая, не нарушая семантики языка, должна обеспечить повышение эффективности синтаксического анализатора. В результате модификации базового множества лексем его объем сокращается; наряду с этим в итоговое множество вводятся дополнительные сущности, получившие название суперлексем. Определяются и подробно обсуждаются три операции модификации: агрегация нескольких лексем в единую суперлексему, сепарация лексемы "идентификатор" на различные суперлексемы и динамическое расширение суперлексем в зависимости от текущего синтаксического контекста компиляции.

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

Глава 2

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

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

На основе принципа однопроходной компиляции, которая является предпочтительной для языка Си++, в данном разделе предлагается компонентная схема организации компилятора и описывается порядок взимодействия компонент. Отмечается, что необходимость вынесения некоторых действий, связанных с семантическим анализом, в отдельный проход, принципиально не противоречит однопроходной схеме и обусловливается удобством реализации и лучшей обозримостью системы.

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

Раздел 2.3 содержит обоснование одного из основных проектных решений, принятых при реализации синтаксического анализатора,- использование метасинтаксических средств. Кратко описываются генератор синтаксических распознавателей Bison и построение формального описания синтаксиса Си++, подаваемого на вход генератору.

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

Показано, что перенос идентификации имен на этап лексического анализа (сепарация идентификаторов) и операция динамического расширения суперлексем требуют более тесной интеграции этапов лексического и синтаксического анализа. Удобным и эффективным средством такой интеграции является механизм состояний. В разделе описывается техника состояний, принятая в реализации компилятора.

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

В обоснование принятых решений в разделе приводятся результаты сравнения объемов и структуры формального описания синтаксиса Си++ в компиляторе переднего плана и аналогичного описания, используемого в свободно-распространяемом компиляторе GNU.

Раздел 2.5 содержит ряд рассмотрений дополнительного характера. В частности, в интересах повышения эффективности анализатора предлагается частичное отступление от принципа соответствия синтаксиса виду, определенному в стандарте языка. Речь идет о синтаксисе выражений. Излагается подход, принятый в стандарте для описания выражений, и анализируется неэффективность прямого переноса такого подхода в реализацию. Предлагается альтернативный подход, несколько усложняющий обозримость синтаксиса, однако заметно (примерно на 20%) повышающий эффективность анализатора.

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

Глава 3

Данная глава является центральной в диссертационной работе. Первая часть главы содержит подробное обсуждение особенностей фундаментального для Си++ понятия области действия (scope). Рассматривается эволюция данного понятия от языка Си к языку Си++ и обсуждаются основные составляющие области действия, как они определены в Стандарте. На основе этого рассмотрения предлагается и обосновывается модель контекста компиляции, положенная в основу реализации компилятора переднего плана Си++.

В разделе 3.1 описываются правила видимости в Си. Язык Си как объект анализа выбран по двум причинам: во-первых, он практически полностью сохраняет структурные принципы, характерные для предшествующего поколения языков программирования, во-вторых, он послужил непосредственной основой для языка Си++ (вплоть до совместимости снизу вверх). В то же время, правила видимости имен в Си++ претерпели существенные изменения по сравнению с Си. Совместное существование в одном языке двух во многом противоречивых множеств правил обусловливает сложности выбора проектных решений по организации таблиц трансляции.

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

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

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

Такая организация таблиц исторически возникла для простых семантических отношений между областями действия, характерных для языков класса Algol-60, Pascal и Си; по существу, единственное существенное отношение заключается в доминировании сущностей текущего блока над одноименными сущностями объемлющих блоков. Отмечается, что особенности структурной семантики языка Си++, рассмотренные в предыдущих разделах, делают невозможным использование подхода, связанного с единой семантической таблицей.

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

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

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

Раздел 3.5 полностью посвящен описанию децентрализованной модели семантических таблиц компилятора Си++. Согласно предлагаемой модели, каждая область действия отображается в виде отдельной структуры, называемой семантической таблицей. В этом смысле семантическая таблица представляет собой некоторую формализацию понятия области действия. Каждая семантическая таблица создается динамически компилятором в момент начала обработки соответствующей области действия в тексте единицы компиляции. Каждая семантическая таблица существует независимо от подобных таблиц для других областей действия. Семантическая таблица содержит информацию обо всех (именованных и/или неименованных) сущностях, явно или неявно объявленных в соответствующей области действия.

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

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

Вводятся следующие семантические отношения:

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

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

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

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

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

Операции сгруппированы в соответствии с теми семантическими отношениями, с которыми эти операции работают. Подробно описывается содержание каждой операции, ее действие иллюстрируется примерами программ на Си++ и наглядными схемами.

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

Основные виды семантических отношений - вложенность, наследование и использование - прямо соответствуют базовым контекстным механизмам Си++. Фундаментальное свойство современных языков, которое заключается в двойственности их сущностей (в частности, класс Си++ является одновременно типом и областью действия), естественно отображается посредством отношения владения между семантическим словом сущности и ее семантической таблицей.

Предложенная модель семантических таблиц компилятора совмещает обычную блочную иерархию, характерную для традиционных языков программирования, начиная с Algol-60, и продвинутые средства организации программ, присущие таким современным языкам, как Си++ и Ада 95.

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

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

Дополнительным доводом в пользу выбранной модели служит ее успешное расширение, направленное на поддержку в значительной степени ортогонального прочим механизма языка - аппарата шаблонов (настраиваемых алгоритмов и типов). Обсуждение вопросов, связанных с таким расширением модели, содержится в главе 4.

Глава 4

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

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

Раздел 4.1 посвящен обсуждению концепции параметризуемых типов и ее реализации в современных языках программирования. Проводится рассмотрение и краткий сравнительный анализ средств параметризации периода компиляции в двух общецелевых промышленных языках - Ада (редакция 1995 года) и Си++.

Отмечается, что для разработчиков компиляторов Си++ реализация шаблонов представляет собой наиболее трудную и тяжелую задачу. Это подтверждается тем фактом, что к настоящему времени ни один известный компилятор ведущих мировых компаний-производителей не поддерживает шаблоны в полном объеме Стандарта. Причина такого состояния дел заключается прежде всего в том, что язык Си++ в целом и его механизм шаблонов в частности крайне нетехнологичны для реализации.

В разделе 4.2 формулируются основные требования к реализации шаблонов. Существенный момент заключается в невозможности упрощенной трактовки шаблонов как макросов и необходимости чисто компиляционного подхода к реализации. Это требование обосновывается ссылками на стандарт Си++ и иллюстрируется примерами.

В разделе 4.3 на основе требований, определенных в предыдущем разделе, постулируется основной принцип реализации шаблонов в компиляторе переднего плана: реализация шаблонов выполняется на основе использования тех же понятий (прежде всего, семантических таблиц), что и другие механизмы языка. Модель семантических таблиц, введенная в предыдущей главе, должна быть расширена введением понятий, свойственных и адекватных семантике шаблонов. При этом необходимо проверить и показать пригодность этой модели для всех базисных концепций, составляющих существо иного понятия языка, каким является механизм шаблонов.

Основное содержание главы сосредоточено в разделах 4.4 и 4.5, где описывается представление описаний "шаблонных" сущностей языка в семантических таблицах.

Раздел 4.4 содержит обсуждение способов представления в таблицах параметров шаблона. Раздел 4.5 вводит в модель новые семантические отношения, отображающие семантику шаблонов языка. Определяются, подробно обсуждаются и иллюстрируются примерами два основных отношения - отношение настройки и отношение специализации. Предлагаются возможные способы реализации описанных отношений.

Раздел 4.6 завершает описание расширений модели семантических таблиц. В данном разделе вводится множество операций над описанными отношениями.

Вторая часть данной главы (разделы 4.7 - 4.12) посвящена рассмотрению вопросов системной поддержки создания программ на Си++, активно использующих механизм шаблонов. Основная проблема, обсуждаемая в этой части, касается таких фундаментальных понятий ЯП, как раздельная компиляция и модульность. Она заключается в том, что структура Си++-программ вместе с исторически сложившимися правилами программирования, берущими свое начало с языка Си, входят в определенное противоречие с новыми возможностями языка, что приводит к значительным трудностям при разработке больших программ. Такое противоречие носит общий характер, однако особенно ярко проявляется для механизма шаблонов.

Основная проблема и одновременно принципиальная слабость языков Си и Си++ заключается в том, что, во-первых, их понятие раздельной компиляции практически не поддерживает естественное, надежное и безопасное взаимодействие единиц трансляции. Это относится как к информационному, так и к логическому взаимодействию. Во-вторых, Стандарт допускает отсутствие контроля за нарушениями правил межмодульного взаимодействия. Эти обстоятельства подробно обсуждаются в разделе 4.7 с привлечением соответствующих положений стандарта Си++.

Раздел 4.8 продолжает начатое выше обсуждение, распространяя его на механизм шаблонов. Показывается, что природа типовой параметризации привносит в проблему межмодульных связей дополнительные трудности, которые проистекают от наличия, помимо описаний шаблонов как таковых, еще и неявных сущностей, присутствующих в программе (классов- и функций-по-шаблону, статических членов классов-по-шаблону), автоматически генерируемых компилятором.

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

В конце раздела формулируется следующий вывод: наряду со сравнительно приемлемым механизмом экспортирования шаблонов в языке, фактически, в полном объеме сохраняется "включающий" подход, практически не контролируемый компилятором, приводящий к увеличению результирующего кода и к появлению трудноуловимых ошибок.

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

Некоторые пути решения описанных проблем, реализованные в известных системах компиляции, рассматриваются в разделе 4.9. В качестве примеров выбраны следующие системы: компилятор cfront фирм AT&T/USL/Novell/SCO, компилятор Си++ фирмы Borland и компилятор переднего плана Си++ компании Edison Design Group.

На основе рассмотрений этого и предыдущего разделов данной главы делаются следующие выводы.

1. Модель программы, положенная в основу Си++, допускает раздельную компиляцию компонент и в то же время не содержит развитых модульных средств. Механизм шаблонов, являясь потенциально очень мощным инструментом программирования, входит в серьезное противоречие с архаичной моделью программы Си++. Не вводя в язык существенных нововведений (то есть, оставаясь в рамках определения языка, данного в его Стандарте), улучшить ситуацию принципиально невозможно. Следовательно (и это подтверждает мировая практика), решение проблемы следует искать в направлении совершенствования архитектуры систем (сред) программирования, поддерживающих процесс разработки программ на Си++.

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

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

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

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

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

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

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

Описание сущности (класса, типа, функции, шаблона) становится, вместо единицы трансляции, основным "квантом" программной информации, обрабатываемой компилятором. Все новые описания компилируются в контексте уже существующих в промежуточном представлении описаний. Саму систему семантических таблиц, модель которой обсуждается в работе, можно было бы назвать ядром репозитория программы.

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

Заключение

Основной методологический результат диссертационной работы заключается в формулировании и обосновании концепции непрерывной компиляции. Эта концепция, отдельные положения которой рассматривались во введении, а также в главах 1, 2 и 4, позволяет преодолеть недостатки, свойственные традиционным подходам к компиляции, обеспечивает высокоуровневый диагностический сервис, адекватную поддержку новых языковых возможностей (в частности, шаблонов) и потенциально более высокую эффективность процесса разработки программ.

Концепция непрерывной компиляции образуется из следующих аспектов:

1. Фаза препроцессирования рассматривается как составная часть функциональности лексического анализатора, в противоположность традиционным подходам, реализующим препроцессирование в виде отдельной компоненты системы программирования. Данное решение повышает общую эффективность компилятора, исключая операции с промежуточным текстовым представлением программы, и делает лексический анализ "гладким". Исключение фазы препроцессирования, не ограничивая возможностей Си++ и потребностей программистов, создает предпосылки для поддержания полной семантической адекватности исходного текста и результирующих структур компиляции.

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

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

4. Концептуально компилятор переднего плана является однопроходным. Все его компоненты взаимодействуют по подпрограммному принципу, что исключает использование каких-либо громоздких промежуточных структур. Введение в реализацию дополнительного второго прохода не является принципиальным решением; оно продиктовано стремлением сделать общую структуру компилятора более обозримой и сопровождаемой и тем самым провести частичную "декомпозицию сложности" семантики Си++. Дополнительный проход компилятора не связан с порождением каких-либо новых структур и представляет собой однократный проход по уже построенному дереву программы с вычислением ряда семантических атрибутов и локальными преобразованиями поддеревьев.

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

Также в процессе исследований получены следующие результаты:

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

Основные результаты диссертации опубликованы в следующих работах:

    1. Зуев Е.А., Кротов А.Н. Новые возможности Си++. PC Magazine/Russian Edition, Октябрь 1994.
    2. Зуев Е.А. Системное программное обеспечение цифрового нейронного процессора с переменной разрядностью операндов. Известия ВУЗов. Приборостроение, том 39, №7, 1996.
    3. Зуев Е.А., Кротов А.Н., Сухомлин В.А. Язык программирования Си++: этапы эволюции и современное состояние. Тез. докл. Первой российской конференции "Индустрия программирования'96", Москва, 3-4 октября 1996 г.
    4. Зуев Е.А., Кротов А.Н., Сухомлин В.А., Давыдов Д., Недиков Н.Н. Система программирования тройного стандарта 3С++. Тез. докл. Первой российской конференции "Индустрия программирования'96", 3-4 октября 1996 г., Москва.
    5. Зуев Е.А. Редкая профессия. PC Magazine/Russian Edition. Спецвыпуск № 5(75), 1997.
    6. Зуев Е.А. Общий подход к созданию базового программного обеспечения нейропроцессора. Известия ВУЗов. Приборостроение, том 40, №3, 1997.
    7. Зуев Е.А., Кротов А.Н. Компилятор полного стандарта Си++. Известия ВУЗов. Приборостроение, том 40, №3, 1997.
    8. Зуев Е.А., Кротов А.Н., Сухомлин В.А. Система программирования тройного стандарта 3С++. Тез. докл. IV Международной конференции "Развитие и применение открытых систем", Н.Новгород, 27-31 октября 1997 г.
    9. Зуев Е.А., Котиков С.В., Челюбеев И.А. Язык ассемблера нейропроцессора и его реализация в инструментальной среде . Известия ВУЗов. Приборостроение, том 40, №3, 1997.
    10. Зуев Е.А. Реализация компилятора полного стандарта Си++ и виртуальной машины Си++, Интернет-форум "Языки программирования и Интернет", ИнфоАрт, июль 1998, http://www.infoart.ru/ .
    11. Зуев Е.А. Русские "плюсы". Мир ПК, № 4, 1999.

ЗАО "Интерстрон" 1998-08.06.2015, ООО "Интерстрон" 09.06.2015 по н.в. Все права защищены.
Москва, Дмитровское шоссе, 1/1
e-mail: interstron-info@mail.ru
web: www.interstron.ru
Тел.: +7 (495) 769-55-68