Как изменился подход к созданию компиляторов? Какими возможностями обладают современные интегрированные среды? Необходима ли разработка единого языка программирования? На эти и другие вопросы отвечает кандидат физико-математических наук Университета Иннополис Евгений Зуев.

Разработка компиляторов для языков программирования — одна из наиболее важных задач в том здании, которое образует наука Computer Science, или информатика. Наряду с базами данных и операционными системами это один из трех краеугольных камней этой науки.

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

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

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

Система Turbo Pascal появилась в 90-х годах прошлого века и мгновенно завоевала громадную популярность. Программисту гораздо удобнее видеть на экране текст своей программы с возможностью исправлять его, вносить в него изменения или улучшения. Причем этот текст, что называется, синтаксически расцвечен, то есть различные элементы программы представлены различными цветами, что помогает лучше увидеть структуру программы, и, нажав одну лишь кнопку, программист может свою программу скомпилировать, получить машинный код и выполнить его тут же, не выходя из этой среды. По сравнению с традиционными средствами, когда в распоряжении программиста был отдельный редактор, отдельный компилятор, отдельный отладчик, никак друг с другом не связанные, это было громадное достижение. Сейчас это достижение представляется уже обыденностью. Имеются не одна и не две развитые, мощные, интегрированные среды программирования, среди которых прежде всего нужно назвать систему Eclipse, а также систему Visual Studio фирмы Microsoft. Эти среды действительно интегрируют различные компоненты, причем степень интеграции этих компонентов достаточно глубока.

Например, если исправить какую-нибудь ошибку в программе, работая в системе Eclipse, система сама может исправить аналогичные ошибки в других местах программы.

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

Продвинутая архитектура компиляторов, состоящая из нескольких компонентов, взаимодействующих друг с другом и способных взаимодействовать с другими элементами интегрированных сред, требует нового инженерного подхода при их разработке. В начале 2000-х годов в лаборатории факультета ВМК МГУ мы начали работать над новой архитектурой компилятора для языка C++. Этот компилятор задумывался как совокупность компонентов, доступ к которым мог быть организован независимо друг от друга. Компилятор не представлял собой единую монолитную программу, это была именно совокупность компонент, и эти компоненты были спроектированы таким образом, чтобы обеспечить легкое включение в интегрированную среду. Например, компонента, занимающаяся синтаксическим разбором программы, могла бы взаимодействовать с визуальным редактором и тем самым поставлять этому визуальному редактору информацию о структуре программы. Этот редактор мог бы отображать эту структуру в наглядном виде на экране монитора.

К настоящему моменту есть по крайней мере две выдающиеся разработки, проводимые в сходном ключе. Первый проект носит название Roslyn, продвигается фирмой Microsoft, он реализован для языка C Sharp (C#) — совокупность компонент, позволяющих легкое включение их в любую среду программирования. Вторая известная система — это так называемая LLVM, Low Level Virtual Machine. Это свободно доступная система. Впрочем, Roslyn тоже уже стал с недавнего времени свободной системой, и каждый может бесплатно ее скачать на свой компьютер и использовать в своих проектах.

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

Разработчики, которые занимаются созданием интегрированных сред и компиляторов, сталкиваются с большим числом проблем. И чисто инженерные проблемы здесь составляют только часть. Дело в том, что наряду с очень динамичным развитием информатики достаточно большое количество решений в настоящее время остаются теми же, которые были приняты 20–30 лет назад. Так, очень многие программисты до сих пор используют обычные командные компиляторы, которые были созданы 20–30 лет назад. Эти компиляторы, будучи спроектированными по-старому, очень трудно интегрировать в современную среду, потому что они были спроектированы как большие, монолитные программы. На этом пути создаются и предлагаются всевозможные решения, но их нельзя назвать приемлемыми именно в силу того, что традиционный компилятор — это монолит, черный ящик, невозможно получить доступ к его компонентам и к его внутренним структурам данных.

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

Многие современные интегрированные среды поддерживают работу со многими языками программирования.

Таким образом, разработчик, получивший в свое распоряжение такую среду, может решать достаточно широкий комплекс задач. Какие-то задачи удобно решать с помощью языка C, какие-то задачи удобно решать с помощью языка Java, а какие-то, быть может, с помощью языка Lisp. Многие среды поддерживают несколько языков в рамках единой инфраструктуры.

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