Size: a a a

Compiler Development

2021 May 21

МБ

Михаил Бахтерев... in Compiler Development
По условиям вопроса https://t.me/CompilerDev/85429 нужны только языки
источник

NK

ID:0 in Compiler Development
https://arxiv.org/pdf/2002.06187v1.pdf
Reusing Static Analysis across Different Domain-Specific Languages using Reference Attribute Grammars

Авторы немного поскромничали с названием статьи — в работе используются не просто ссылочные атрибутные грамматики (Reference Attribute Grammars, RAGs), а их расширение — реляционные ссылочные атрибутные грамматики (Relational Reference Attribute Grammars) и конкретно фреймворк JastAdd.

Если говорить совсем по-простому, то авторы предлагают решение аналога Expression Problem в области языков и алгоритмов статического анализа (N языков x M алгоритмов) при помощи языка промежуточного представления (Intermediate Representation, IR). Идея не нова, но есть нюанс. 😊

При традиционном подходе к (универсальному) IR, как, например, в проекте LLVM, один и тот же IR используется для всех типов статического анализа и трансформаций. С одной стороны, это действительно позволяет переиспользовать алгоритмы анализа для всех языков, которые транслируются в данный IR. Но с другой стороны, такой IR с необходимостью должен содержать информацию, требующуюся каждому реализованному алгоритму и преобразованию. Это приводит к "раздуванию" IR, как видно по тому же LLVM, но также это приводит и к "радуванию" транслятора язык->IR, поскольку разработчику приходится строить корректный IR со всей требуемой информацией даже если он использует только один алгоритм анализа, который опирается на одну десятую доступных данных. Это едва ли можно считать проблемой General-Purpose фреймворка, но для работы с Domain-Specific языками может заметно повысить сложность и трудоёмкость реализации.

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

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

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

1. нетерминальные атрибуты (Nonterminal Attributes, NTA aka Higher-Order Attributes) позволяют лаконично и декларативно задавать преобразования AST->AST, что сильно облегчает построение специализированных IR для каждого отдельного вида статического анализа;

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

3. наконец, отношения (Relations) между узлами задают рёбра "внешним" по отношению к графу способом, что позволяет "автоматически" получить ссылки из узлов IR к соответствующим узлам в исходном дереве DSL.

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

Для полноты картины, авторы приводят результаты анализа производительности реализованных алгоритмов на наборе открытых Java-проектов по сравнению с традиционной реализацией на основе паттерна "посетитель" (Visitor Pattern). Благодаря механизмам мемоизации внутри фреймворка Relational RAGs (использовался JastAdd), производительность не уступает, а в некоторых случаях и превосходит традиционную реализацию, которую невозможно переиспользовать.
источник

NK

ID:0 in Compiler Development
Тем не менее несколько моментов вызывают вопросы, если не к подходу в целом, то к его реализации в JastAdd.

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

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

В любом случае, для прояснения деталей предлагаемого подхода читателю предлагается ознакомиться со статьёй, благо, она достаточно проста для понимания. Механизм Relational RAGs весьма мощный и универсальный – его полезно иметь в виду при реализации самых разных аспектов работы с языками программирования, не только статического анализа. 😊

#dsl #rag #static #analysis
источник

АД

Антоний Диоген... in Compiler Development
BEAM считается за язык?
источник

AT

Alexander Tchitchigi... in Compiler Development
Тогда уж WAM и JAM надо вспомнить. Но так-то машины — не языки.
источник

AK

Andrei Kurosh in Compiler Development
А про диалект K&R C уже упоминали?
источник

AT

Alexander Tchitchigi... in Compiler Development
Вы ещё про язык Pike вспомните! 😂
источник

AK

Andrei Kurosh in Compiler Development
Вы про то, что он изначально назывался Lars Pensjo C?
источник

AT

Alexander Tchitchigi... in Compiler Development
Нет, этой истории я не знал. 😊
источник
2021 May 23

РС

Роман Соловьев... in Compiler Development
Всем привет, кто-нибудь реализовывал LL(1) для грамматик описанных с помощью расширенной формы Бекуса-Наура?

Т.е. когда элемент предиката может быть не обязательным или кол-во повторений задано диапазоном (2-3)
источник

TC

Tom Cauf in Compiler Development
Visual Python.NET,  ну или просто P#
источник

AK

Andrei Kurosh in Compiler Development
Такой уже был, назывался IronPython
источник

AK

Andrei Kurosh in Compiler Development
Но что-то не зашел особо
источник

TC

Tom Cauf in Compiler Development
Подозреваю, что его возродят. Не зря же Гвидо к Майкам ушел работать
источник

TC

Tom Cauf in Compiler Development
А не зашло потому, что сильно по версии от мейнстрима отставало
источник

ВМ

Виталий Медоваров... in Compiler Development
Я что-то думал что он никуда не пропадал
источник

AK

Andrei Kurosh in Compiler Development
Не зашло потому, что интеграция python и CLR не оказалась никому особо нужна
источник

TC

Tom Cauf in Compiler Development
Он ушел из команды разработки питона и самоустранился от управления процессом
источник

AK

Andrei Kurosh in Compiler Development
Тем более что тогда .NET еще даже не был кроссплатформенным
источник

ВМ

Виталий Медоваров... in Compiler Development
Я знаю пример где IronPython встраивали для скриптинга в движке игровом
источник