stringtranslate.com

Camlp4

Camlp4 — это программная система для написания расширяемых парсеров для языков программирования. Она предоставляет набор библиотек OCaml , которые используются для определения грамматик, а также загружаемых расширений синтаксиса таких грамматик. Camlp4 означает Caml Preprocessor and Pretty-Printer , и одним из его важнейших приложений было определение расширений синтаксиса OCaml , специфичных для определенной области .

Camlp4 был частью официального дистрибутива OCaml, разработанного в INRIA . Его первоначальным автором является Daniel de Rauglaudre. Версия 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 работает, загружая набор скомпилированных модулей, которые определяют парсер , а также pretty-printer : парсер преобразует входную программу во внутреннее представление. Это внутреннее представление составляет абстрактное синтаксическое дерево (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, файл, который определяет расширение синтаксиса:

пусть  уникальный  =  пусть  n  =  ссылка  0  в  fun  ()  ->  incr  n ;  "__pa_memo"  ^  string_of_int  ! nРАСШИРИТЬ  ГЛОБАЛЬНО :  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  [  "когда" ;  e  =  Pcaml . expr  ->  e  ];  "->" ;  e  =  Pcaml . expr  ->  ( p ,  w ,  e )  ]  ]; КОНЕЦ

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

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

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

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

Ссылки

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

Внешние ссылки