Камлп4
Camlp4 — это программная система для написания расширяемых парсеров языков программирования. Он предоставляет набор библиотек OCaml , которые используются для определения грамматик, а также загружаемых расширений синтаксиса таких грамматик. Camlp4 означает Caml Preprocessor и Pretty-Printer , и одним из его наиболее важных приложений было определение доменно-ориентированных расширений синтаксиса OCaml .
Camlp4 был частью официального дистрибутива OCaml, разработанного в INRIA . Ее первоначальный автор — Даниэль де Рауглодр. Версия OCaml 3.10.0, выпущенная в мае 2007 года, представляет собой значительно модифицированную и обратно несовместимую версию Camlp4. De Rauglaudre поддерживает отдельную обратно совместимую версию, переименованную в Camlp5. Все приведенные ниже примеры относятся к Camlp5 или предыдущей версии Camlp4 (версии 3.09 и более ранние).
Версия 4.08, выпущенная летом 2019 года, [1] была последней официальной версией этой библиотеки. В настоящее время он устарел; [2] вместо этого рекомендуется использовать PPX (PreProcessor eXtensions) [3] [4] библиотеки. [5]
Конкретный и абстрактный синтаксис
[ редактировать ]Препроцессор 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 >>, т.е. деконструкция и построение абстрактных синтаксических деревьев в конкретном синтаксисе.
Пример
[ редактировать ]В следующем примере определяется расширение синтаксиса OCaml. Он предоставляет новое ключевое слово , memo
, который можно использовать в качестве замены function
и обеспечивает автоматическое запоминание функций с сопоставлением с образцом . Мемоизация заключается в сохранении результатов предыдущих вычислений в таблице так, чтобы фактическое вычисление функции для каждого возможного аргумента происходило не более одного раза.
Это pa_memo.ml, файл, который определяет расширение синтаксиса:
let unique =
let n = ref 0 in
fun () -> incr n; "__pa_memo" ^ string_of_int !n
EXTEND
GLOBAL: Pcaml.expr;
Pcaml.expr: LEVEL "expr1" [
[ "memo"; OPT "|"; pel = LIST1 match_case SEP "|" ->
let tbl = unique () in
let x = unique () in
let result = unique () in
<:expr<
let $lid:tbl$ = Hashtbl.create 100 in
fun $lid:x$ ->
try Hashtbl.find $lid:tbl$ $lid:x$
with [ Not_found ->
let $lid:result$ = match $lid:x$ with [ $list:pel$ ] in
do { Hashtbl.replace $lid:tbl$ $lid:x$ $lid:result$;
$lid:result$ } ]
>> ]
];
match_case: [
[ p = Pcaml.patt; w = OPT [ "when"; e = Pcaml.expr -> e ];
"->"; e = Pcaml.expr ->
(p, w, e) ]
];
END
Пример программы, использующей это расширение синтаксиса:
let counter = ref 0 (* global counter of multiplications *)
(* factorial with memoization *)
let rec fac = memo
0 -> 1
| n when n > 0 ->
(incr counter;
n * fac (n - 1))
| _ -> invalid_arg "fac"
let run n =
let result = fac n in
let count = !counter in
Printf.printf "%i! = %i number of multiplications so far = %i\n"
n result count
let _ =
List.iter run [5; 4; 6]
Вывод программы следующий: функция fac (факториал) вычисляет только те продукты, которые не вычислялись ранее:
5! = 120 number of multiplications so far = 5 4! = 24 number of multiplications so far = 5 6! = 720 number of multiplications so far = 6
Ссылки
[ редактировать ]- ^ "ocaml/camlp4" . Гитхаб . Проверено 4 февраля 2020 г.
- ^ Димино, Жереми (07.08.2019). «Конец Camlp4» . ОКамл . Архивировано из оригинала 04 февраля 2020 г. Проверено 4 февраля 2020 г.
- ^ «ППХ» . ocamllabs.io . Проверено 4 февраля 2020 г.
- ^ Мецгер, Перри. «Руководство по расширениям препроцессора» . OCamlverse . Архивировано из оригинала 5 февраля 2020 г. Проверено 5 февраля 2020 г.
- ^ Димино, Джереми. «Преобразование базы кода из camlp4 в ppx» . Джейн Стрит Технический блог . Архивировано из оригинала 04 февраля 2020 г. Проверено 4 февраля 2020 г.
Внешние ссылки
[ редактировать ]- Официальный сайт
- Camlp4 Wiki — охватывает версию 3.10.
- Справочное руководство и учебное пособие по Camlp4 — обложка версии 3.07
- Недокументированные функции Camlp4 — охватывают версии до 3.09.
- Как настроить синтаксис OCaml с помощью Camlp5. Все, что вы всегда хотели знать, но боялись спросить , касается версий до 3.10.
- Компиляторы-однодневки, или Как я научился не волноваться и полюбил метапрограммирование
- Учебник по созданию расширяемых парсеров с помощью Camlp4