#compiler-construction #abstract-syntax-tree #syntactic-sugar
Вопрос:
Мне любопытно, как и когда компилятор «десугаризует» синтаксический сахар в его окончательную форму. Примером синтаксического сахара является оператор increment i
, превращающийся в оператор assign i=i 1
, или языки, поддерживающие перегрузку операторов.
Я знаю, что многие разные компиляторы будут реализовывать процесс «десугаринга» по-разному и на разных этапах, поэтому я был бы рад грубым примерам из любого языка.
Под этапами я имею в виду различные этапы процесса компиляции, такие как синтаксический анализ, семантический анализ, промежуточный этап, генерация кода и т.д.
Меня особенно интересует влияние (если таковое имеется) на AST и любые потенциальные преобразования, которые с ним произойдут.
Комментарии:
1. Это определенно происходило до генерации кода :-). Кроме того, я не думаю, что есть лучший ответ, чем «это зависит». По крайней мере, я не собираюсь его пробовать. (Постфикс
сложнее , чем простая подстановка с
(x = x 1)
, потому что возвращаемое значение этого выражения замены является новым значениемx
, но семантика постфиксного приращения требует, чтобы возвращаемое значение было старым значением.)2. @rici Хотя я понимаю, почему вы сделали свой ответ комментарием, в данном случае, поскольку вопрос более субъективен, чем объективен, я думаю, что вы должны опубликовать это в качестве ответа, чтобы другие могли видеть, что у вопроса есть ответ. Я бы высказал это в качестве ответа и принял бы его, если бы был ОП.
Ответ №1:
Я приму другой подход к ответу на этот вопрос. Вместо того, чтобы сосредотачиваться на этапах, я сосредоточусь на промежуточных языках.
Как упоминал @rici в комментариях к этому вопросу, это действительно зависит. Во многих современных компиляторах используются различные промежуточные представления:
- HIR (Промежуточное представление высокого уровня) (Интерфейс и «Середина»)
- MIR (промежуточное представление среднего уровня) (Промежуточный и серверный)
- LIR (Промежуточное представление низкого уровня) (Серверная часть)
Эти различные промежуточные представления, в свою очередь, могут быть подразделены, например, HIR-1 (с сахаром) HIR-2 (с сахаром).
По мере того как мы переходим между различными промежуточными представлениями, наш промежуточный язык становится менее специфичным для языка и более специфичным для конкретной цели. Промежуточное представление среднего уровня обычно напоминает машинно-независимый язык низкого уровня, в то время как LIR обычно очень близок к целевой машине. Обычно различные варианты HIR сохраняют такие вещи, как циклы и доступ к массиву, явными, и они используются, например, для проверки возможностей автоматического распараллеливания кода или выполнения других оптимизаций, связанных с циклическими конструкциями. Иногда там также можно найти более специфичные для языка оптимизации (или проверки).
В случае синтаксического сахара он либо будет сохранен после синтаксического анализа и, таким образом, станет частью некоторого представления HIR, либо дизайнер мог бы решить удалить его напрямую. Преимущество сохранения его после синтаксического анализа заключается в том, что его можно использовать, например, в инструментах, которые предоставляют советы пользователям, или в том, что существует некоторый синтаксический сахар, который можно использовать для некоторой оптимизации HIR. Недостатком его сохранения является то, что сахар должен быть закодирован и может вводить больше кода и больше проверок в компиляторе.