Camlp4 - Camlp4

Camlp4 программная система для написания расширяемых парсеров для языков программирования. Он предоставляет набор OCaml библиотеки, которые используются для определения грамматик, а также загружаемых расширений синтаксиса таких грамматик. Camlp4 означает Caml Препроцессор и Довольно-Принтер и одним из наиболее важных приложений было определение доменных расширений синтаксиса OCaml.

Camlp4 был частью официального дистрибутива OCaml, разработанного на INRIA. Первоначальный автор - Даниэль де Рауглодр. Версия OCaml 3.10.0, выпущенная в мае 2007 г., представила значительно измененную и обратно несовместимый версия Camlp4. De Rauglaudre поддерживает отдельную обратно совместимую версию, которая была переименована в Camlp5. Все приведенные ниже примеры относятся к Camlp5 или предыдущей версии Camlp4 (версии 3.09 и ранее).

Версия 4.08, выпущенная летом 2019 года,[1] была последней официальной версией этой библиотеки. В настоящее время не рекомендуется.[2] Вместо camlp4 рекомендую использовать PPX (PreProcessor eXtensions)[3][4] библиотеки.[5]

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

Препроцессор Camlp4 работает, загружая набор скомпилированных модулей, которые определяют парсер также как и хорошенький принтер: парсер преобразует ввод программа во внутреннее представление. Это внутреннее представление составляет абстрактное синтаксическое дерево (АСТ). Его можно вывести в двоичной форме, например его можно передать прямо в один из OCaml компиляторы, или его можно преобразовать обратно в программу с открытым текстом. Понятие конкретный синтаксис относится к формату, в котором абстрактный синтаксис представлен.

Например, OCaml выражение (1 + 2) также можно записать ((+) 1 2) или (((+) 1) 2). Разница только на уровне конкретного синтаксиса, поскольку эти три версии являются эквивалентными представлениями одного и того же абстрактного синтаксического дерева. Как показывает определение измененного синтаксиса для OCaml, один и тот же язык программирования может использовать разные конкретные синтаксисы. Все они сведутся к абстрактному синтаксическому дереву в уникальном формате, с которым может справиться компилятор.

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

Сферы применения

Доменные языки являются основным приложением Camlp4. Поскольку OCaml - это многопарадигмальный язык с интерактивным верхним уровнем и компилятором нативного кода, его можно использовать как бэкэнд для любого исходного языка. Единственное, что нужно сделать разработчику, - это написать грамматику Camlp4, которая преобразует рассматриваемый предметно-ориентированный язык в обычную программу OCaml. Также можно использовать другие целевые языки, например C.

Если целевой язык - OCaml, простые синтаксические надстройки или синтаксический сахар может быть определен, чтобы обеспечить выразительность, которую нелегко достичь с помощью стандартных функций языка OCaml. Расширение синтаксиса определяется скомпилированным модулем OCaml, который передается исполняемому файлу camlp4o вместе с программой для обработки.

Camlp4 включает предметно-ориентированный язык поскольку он предоставляет расширения синтаксиса, которые упрощают разработку расширений синтаксиса. Эти расширения позволяют компактно определять грамматики (ПРОДЛЕВАТЬ операторы) и цитаты, такие как <: expr <1 + 1 >>, то есть деконструкция и построение абстрактных синтаксических деревьев в конкретном синтаксисе.

Пример

В следующем примере определяется расширение синтаксиса OCaml. Это дает новый ключевое слово, памятка, который можно использовать как замену функция и обеспечивает автоматический мемоизация функций с сопоставление с образцом. Мемоизация заключается в хранении результатов предыдущих вычисления в таблице, чтобы фактическое вычисление функции для каждого возможного аргумента происходило не более одного раза.

Это pa_memo.ml, файл, который определяет расширение синтаксиса:

позволять уникальный =  позволять п = ссылка 0 в  весело () -> incr п; «__pa_memo» ^ string_of_int !пПРОДЛЕВАТЬ  ГЛОБАЛЬНЫЙ: Pcaml.expr;  Pcaml.expr: УРОВЕНЬ "expr1" [    [ "памятка"; OPT "|"; пел = LIST1 Учитывать регистр СЕН "|" ->      позволять таблица = уникальный () в      позволять Икс = уникальный () в      позволять результат = уникальный () в      <:expr<       позволять $крышка:таблица$ = Hashtbl.Создайте 100 в      весело $крышка:Икс$ ->        пытаться Hashtbl.найти $крышка:таблица$ $крышка:Икс$         с [ Не найден ->                 позволять $крышка:результат$ = матч $крышка:Икс$ с [ $список:пел$ ] в                делать { Hashtbl.заменять $крышка:таблица$ $крышка:Икс$ $крышка:результат$;                      $крышка:результат$ } ]      >> ]  ];  Учитывать регистр: [    [ п = Pcaml.патт; ш = OPT [ "когда"; е = Pcaml.expr -> е ];       "->"; е = Pcaml.expr ->        (п, ш, е) ]  ];КОНЕЦ

Пример программы, использующей это расширение синтаксиса:

позволять прилавок = ссылка 0 (* глобальный счетчик умножений *)(* факториал с мемоизацией *)позволять rec фак = памятка    0 -> 1  | п когда п > 0 ->       (incr прилавок;       п * фак (п - 1))  | _ -> invalid_arg "фак"позволять пробег п =  позволять результат = фак п в  позволять считать = !прилавок в  Printf.printf "% i! =% i количество умножений на данный момент =% i п"    п результат считать позволять _ =  Список.iter пробег [5; 4; 6]

Результат программы выглядит следующим образом, показывая, что функция fac (факториал) вычисляет только те продукты, которые ранее не вычислялись:

5! = 120 количество умножений на данный момент = 54! = 24 количество умножений на данный момент = 56! = 720 количество умножений на данный момент = 6

Рекомендации

  1. ^ "ocaml / camlp4". GitHub. Получено 2020-02-04.
  2. ^ Димино, Жереми (07.08.2019). «Конец Camlp4». OCaml. Получено 2020-02-04.
  3. ^ «PPX». ocamllabs.io. Получено 2020-02-04.
  4. ^ Мецгер, Перри. "Руководство по расширениям препроцессора". OCamlverse. Получено 2020-02-05.
  5. ^ Димино, Джереми. "Преобразование базы кода из camlp4 в ppx". Джейн Стрит Технический блог. Получено 2020-02-04.

внешняя ссылка