Введение

Camlp4 — это программная система для создания расширяемых парсеров для языков программирования. Она предоставляет набор библиотек OCaml, используемых для определения грамматик, а также загружаемых синтаксических расширений для этих грамматик. Аббревиатура Camlp4 расшифровывается как Caml Preprocessor and Pretty Printer, и одним из важнейших применений Camlp4 было определение предметно-ориентированных расширений синтаксиса OCaml. Camlp4 входила в состав официального дистрибутива OCaml, разрабатываемого в INRIA. Её первоначальным автором является Даниэль де Роглаудр. Версия OCaml 3.10.0, выпущенная в мае 2007 года, представила значительно измененную и обратно несовместимую версию Camlp4. Де Роглаудр поддерживает отдельную обратно совместимую версию, которая была переименована в Camlp5. Все примеры, приведенные ниже, относятся к Camlp5 или к более ранним версиям Camlp4 (версиям 3.09 и более старым). Версия 4.08, выпущенная летом 2019 года, была последней официальной версией этой библиотеки. В настоящее время она считается устаревшей, и вместо неё рекомендуется использовать библиотеки PPX (PreProcessor eXtensions).

Конкретный и абстрактный синтаксис

Предпроцессор Camlp4 работает, загружая набор скомпилированных модулей, которые определяют как парсер, так и модуль форматированного вывода: парсер преобразует входную программу во внутреннее представление. Это внутреннее представление и составляет абстрактное синтаксическое дерево (AST). Оно может быть выведено в двоичном формате, например, передано непосредственно одному из компиляторов OCaml, или преобразовано обратно в текстовую программу. Понятие конкретного синтаксиса относится к формату, в котором представлен абстрактный синтаксис. Например, выражение OCaml (1 + 2) также может быть записано как ((+) 1 2) или (((+) 1) 2). Разница заключается лишь в уровне конкретного синтаксиса, поскольку все три варианта являются эквивалентными представлениями одного и того же абстрактного синтаксического дерева. Как демонстрирует определение пересмотренного синтаксиса для OCaml, один и тот же язык программирования может использовать различные конкретные синтаксисы. Все они сходятся к абстрактному синтаксическому дереву в едином формате, который может обработать компилятор. Абстрактное синтаксическое дерево лежит в основе синтаксических расширений, которые, по сути, являются программами OCaml. Хотя определение грамматик должно выполняться в OCaml, парсер, который определяется или расширяется, не обязательно связан с OCaml, и в этом случае дерево синтаксиса, с которым ведется работа, не является деревом синтаксиса OCaml. Предоставлено несколько библиотек, облегчающих специфическую манипуляцию синтаксическими деревьями OCaml.

Области применения

Языки, специфичные для предметной области, являются одним из основных применений Camlp4. Поскольку OCaml — это многопарадигмальный язык с интерактивной средой разработки и компилятором в машинный код, его можно использовать как бэкенд для любого оригинального языка. Разработчику необходимо лишь написать грамматику Camlp4, которая преобразует рассматриваемый язык, специфичный для предметной области, в обычную программу на OCaml. Можно также использовать другие целевые языки, такие как C.

Если целевым языком является OCaml, можно определить простые синтаксические расширения или синтаксический сахар для обеспечения выразительности, которую сложно достичь, используя стандартные возможности языка OCaml. Расширение синтаксиса определяется скомпилированным модулем OCaml, который передается исполняемому файлу camlp4o вместе с программой для обработки. Camlp4 сам по себе включает язык, специфичный для предметной области, поскольку предоставляет расширения синтаксиса, облегчающие разработку таких расширений. Эти расширения позволяют компактно определять грамматики (операторы EXTEND) и использовать цитаты, такие как <:expr< 1 + 1 >>, то есть деконструировать и конструировать абстрактные синтаксические деревья в конкретном синтаксисе.