Почему компиляторы не переводят на более простые языки? - PullRequest
9 голосов
/ 14 ноября 2010

Обычно компиляторы переводят с языка, который они поддерживают, на ассемблер.Или, самое большее, на язык, похожий на ассемблер (байт-код), такой как GIMPLE / GENERIC для GCC или байт-код Python / Java / .NET.

Не будет ли проще, если компилятор переведет на более простой язык, которыйуже реализует большое подмножество своей грамматики?

Например, компилятор Objective-C, который на 100% совместим с C, может добавить семантику только для синтаксиса, который он расширяет до C, переводя его на C. Iможет видеть много преимуществ в этом;Можно использовать этот компилятор Objective-C, чтобы перевести его код в C, чтобы скомпилировать сгенерированный код C с другим компилятором, который не поддерживает C ++ (но который оптимизирует больше, или который компилируется быстрее, или способен компилироваться для большего количества архитектур).Или можно было бы использовать сгенерированный код C в проекте, где разрешен только C.

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

Какие будут штрафы?Сгенерированный код будет очень трудно понять людям?Компиляторы не смогут оптимизировать столько, сколько они могут сейчас?Что еще?

Ответы [ 5 ]

6 голосов
/ 14 ноября 2010

На самом деле это используется многими языками, используя Промежуточные языки . Самым большим примером для этого был бы Паскаль, у которого была система Pascal-P: Паскаль был скомпилирован в гипотетический язык ассемблера. Портировать паскаль будет означать только создание компилятора для этого языка ассемблера: задача намного проще, чем перенос всего компилятора паскаля. После написания этого компилятора вам нужно будет только скомпилировать (машинно-независимый) паскаль-компилятор, который был написан в этом.

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

Я не думаю, что проблема с этим методом на самом деле заключается в читабельности сгенерированного кода (лично я не разбираюсь в байт-коде сборки, сгенерированном компиляторами), а в оптимизации. Многие идеи в языках программирования более высокого уровня (на ум приходит слабая типизация) трудно автоматически перевести на системные языки более низкого уровня, такие как C. Есть причина, по которой GCC стремится оптимизировать работу перед генерацией кода.

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

2 голосов
/ 16 ноября 2010

Кстати, в качестве контрпримера, Tcl - это один из языков, который, как известно, очень-очень трудно (если не полностью невозможно) перевести на C. За последние 20 лет было несколько проектов, которые пытались это сделать, даже одно обещание о коммерческом продукте, но ни одно из них не осуществилось.

Частично это связано с тем, что Tcl является очень динамичным языком (как любой язык с функцией eval). Частично это потому, что единственный способ узнать, является ли что-то кодом или данными, - это запустить программу.

1 голос
/ 10 августа 2011

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

http://blog.llvm.org/2010/05/glasgow-haskell-compiler-and-llvm.html

1 голос
/ 14 ноября 2010

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

Любая попыткаскопируйте и вставьте материал, похожий на C, и переведите остальное вокруг него, что может привести к проблемам.Во-первых, C ++ не является строгим надмножеством C, поэтому вещи, похожие на C, не обязательно компилируются точно так же (особенно по сравнению с C99).И даже если бы они это сделали, предположив, что пользователь допустил ошибку в своих материалах на C, компиляторы не склонны предоставлять информацию об ошибках в машиночитаемом формате, поэтому слою Objective-C-C было бы очень сложно датьПользователь получает значимую ошибку после получения, например, «error at line 99».

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

Итак: компиляторы не работают так по чисто практическим причинам.

0 голосов
/ 16 ноября 2010

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

http://www.meta -alternative.net / mbase.html

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

...