Разработка компиляторов

       

Идея массового применения промежуточного языка


Задача проектирования ПЯ особенно сложна при проектировании многоязыковых систем трансляции, позволяющих генерировать код сразу для нескольких целевых платформ. В этом случае становится выгодно спроектировать единый промежуточный язык для всего семейства трансляторов. Таким образом, можно свести задачу написания m*n компиляторов к реализации разбора m входных языков с построением в процессе анализа единого внутреннего представления и последующему написанию n просмотров, синтезирующих объектный код для n целевых платформ.

Эта идея была известна уже более 30 лет назад (UNCOL, Warren Abstract Machine, Виртовский p-code, АЛЬФА и т.д.), но лишь недавно такой подход стал широко применяться на практике, причем в основном совместно с идеей динамической компиляции:

  • Java bytecode представляет собой подход, в котором один входной язык проецируется сразу на множество целевых платформ с помощью единого промежуточного языка. Собственно синтез объектного кода возлагается на реализаторов Java Virtual Machine для данной платформы. Интересно, что несмотря на тот факт, что Java bytecode создавался только для одного входного языка, впоследствии появилось множество компиляторов, генерирующих Java bytecode для других исходных языков (например, Кобол).
  • MSIL представляет собой более общий случай той же идеи, с множеством входных языков и множеством целевых платформ. При этом синтез машинного кода выполняется .NET runtime во время выполнения программы.
  • Возможно, наиболее "чистой" реализацией идеи единого промежуточного языка является семейство компиляторов GNU, в котором единое внутреннее представление GNU RTL (RTL расшифровывается как Register Transfer Language) может порождаться из целого ряда языков (С/С++, Fortran, Ада, CHILL) и впоследствии может быть использовано для генерации объектного кода сразу для целого ряда платформ. GNU RTL также позволяет писать независимые просмотры оптимизации, причем наличие информации об относительной стоимости выполнения различных операций позволяет задавать как машинно-независимые, так и машинно-зависимые оптимизации.



Содержание раздела