Spec-Zone.ru › OCaml

Модуль Ast_mapper

module Ast_mapper: sig .. end

Интерфейс -ppx переписчика

Переписчик -ppx — это программа, которая принимает сериализованное абстрактное синтаксическое дерево и выводит другое, возможно, измененное, абстрактное синтаксическое дерево. Этот модуль инкапсулирует интерфейс между компилятором и -ppx переписчиками, обрабатывая такие детали, как формат сериализации, передачу флагов командной строки и хранение состояния.

Ast_mapper.mapper позволяет переписывать АСТ с помощью открытой рекурсии. Типичный переписчик будет основан на Ast_mapper.default_mapper, глубоком идентичном переписчике, и будет использовать его для обработки синтаксиса, который он не изменяет. Например:

open Asttypes
open Parsetree
open Ast_mapper

let test_mapper argv =
  { default_mapper with
    expr = fun mapper expr ->
      match expr with
      | { pexp_desc = Pexp_extension ({ txt = "test" }, PStr [])} ->
        Ast_helper.Exp.constant (Pconst_integer ("42", None))
      | other -> default_mapper.expr mapper other; }

let () =
  register "ppx_test" test_mapper

Этот -ppx переписчик, который заменяет [%test] в выражениях на константу 42, может быть скомпилирован с помощью ocamlc -o ppx_test -I +compiler-libs ocamlcommon.cma ppx_test.ml.

Предупреждение: этот модуль нестабилен и является частью compiler-libs.

Обобщенный переписчик Parsetree

type mapper = {
attribute : mapper -> Parsetree.attribute -> Parsetree.attribute;
attributes : mapper -> Parsetree.attribute list -> Parsetree.attribute list;
binding_op : mapper -> Parsetree.binding_op -> Parsetree.binding_op;
case : mapper -> Parsetree.case -> Parsetree.case;
cases : mapper -> Parsetree.case list -> Parsetree.case list;
class_declaration : mapper ->
Parsetree.class_declaration -> Parsetree.class_declaration
;
class_description : mapper ->
Parsetree.class_description -> Parsetree.class_description
;
class_expr : mapper -> Parsetree.class_expr -> Parsetree.class_expr;
class_field : mapper -> Parsetree.class_field -> Parsetree.class_field;
class_signature : mapper -> Parsetree.class_signature -> Parsetree.class_signature;
class_structure : mapper -> Parsetree.class_structure -> Parsetree.class_structure;
class_type : mapper -> Parsetree.class_type -> Parsetree.class_type;
class_type_declaration : mapper ->
Parsetree.class_type_declaration -> Parsetree.class_type_declaration
;
class_type_field : mapper -> Parsetree.class_type_field -> Parsetree.class_type_field;
constant : mapper -> Parsetree.constant -> Parsetree.constant;
constructor_declaration : mapper ->
Parsetree.constructor_declaration -> Parsetree.constructor_declaration
;
directive_argument : mapper ->
Parsetree.directive_argument -> Parsetree.directive_argument
;
expr : mapper -> Parsetree.expression -> Parsetree.expression;
extension : mapper -> Parsetree.extension -> Parsetree.extension;
extension_constructor : mapper ->
Parsetree.extension_constructor -> Parsetree.extension_constructor
;
include_declaration : mapper ->
Parsetree.include_declaration -> Parsetree.include_declaration
;
include_description : mapper ->
Parsetree.include_description -> Parsetree.include_description
;
label_declaration : mapper ->
Parsetree.label_declaration -> Parsetree.label_declaration
;
location : mapper -> Location.t -> Location.t;
module_binding : mapper -> Parsetree.module_binding -> Parsetree.module_binding;
module_declaration : mapper ->
Parsetree.module_declaration -> Parsetree.module_declaration
;
module_substitution : mapper ->
Parsetree.module_substitution -> Parsetree.module_substitution
;
module_expr : mapper -> Parsetree.module_expr -> Parsetree.module_expr;
module_type : mapper -> Parsetree.module_type -> Parsetree.module_type;
module_type_declaration : mapper ->
Parsetree.module_type_declaration -> Parsetree.module_type_declaration
;
open_declaration : mapper -> Parsetree.open_declaration -> Parsetree.open_declaration;
open_description : mapper -> Parsetree.open_description -> Parsetree.open_description;
pat : mapper -> Parsetree.pattern -> Parsetree.pattern;
payload : mapper -> Parsetree.payload -> Parsetree.payload;
signature : mapper -> Parsetree.signature -> Parsetree.signature;
signature_item : mapper -> Parsetree.signature_item -> Parsetree.signature_item;
structure : mapper -> Parsetree.structure -> Parsetree.structure;
structure_item : mapper -> Parsetree.structure_item -> Parsetree.structure_item;
toplevel_directive : mapper ->
Parsetree.toplevel_directive -> Parsetree.toplevel_directive
;
toplevel_phrase : mapper -> Parsetree.toplevel_phrase -> Parsetree.toplevel_phrase;
typ : mapper -> Parsetree.core_type -> Parsetree.core_type;
type_declaration : mapper -> Parsetree.type_declaration -> Parsetree.type_declaration;
type_extension : mapper -> Parsetree.type_extension -> Parsetree.type_extension;
type_exception : mapper -> Parsetree.type_exception -> Parsetree.type_exception;
type_kind : mapper -> Parsetree.type_kind -> Parsetree.type_kind;
value_binding : mapper -> Parsetree.value_binding -> Parsetree.value_binding;
value_description : mapper ->
Parsetree.value_description -> Parsetree.value_description
;
with_constraint : mapper -> Parsetree.with_constraint -> Parsetree.with_constraint;
}

Запись переписчика реализует по одному «методу» на каждую синтаксическую категорию, используя стиль открытой рекурсии: каждый метод принимает в качестве первого аргумента переписчика, который будет применяться к дочерним элементам в синтаксическом дереве.

val default_mapper : mapper

Переписчик по умолчанию, реализующий «глубокое идентичное» отображение.

Применение переписчиков к единицам компиляции

val tool_name : unit -> string

Может использоваться внутри ppx препроцессора, чтобы узнать, какой инструмент его вызывает "ocamlc", "ocamlopt", "ocamldoc", "ocamldep", "ocaml", ... Некоторые глобальные переменные, которые отражают параметры командной строки, автоматически синхронизируются между вызывающим инструментом и ppx препроцессором: Clflags.include_dirs, Clflags.hidden_include_dirs, Load_path, Clflags.open_modules, Clflags.for_package, Clflags.debug.

val apply : source:string -> target:string -> mapper -> unit

Применение переписчика (параметризованного именем единицы) к выгруженному парсетрею, найденному в файле source, и размещение результата в файле target. Поле structure или signature переписчика применяется к реализации или интерфейсу.

val run_main : (string list -> mapper) -> unit

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

API регистрации

val register_function : (string -> (string list -> mapper) -> unit) ref
val register : string -> (string list -> mapper) -> unit

Применение register_function. По умолчанию поведение заключается в немедленном запуске переписчика, принимая аргументы из командной строки процесса. Это для поддержки сценария, когда переписчик связан как автономный исполняемый файл.

Возможно переопределить register_function для определения «-ppx драйверов», которые объединяют несколько переписчиков в одном процессе. Обычно драйвер начинает с определения register_function для пользовательской реализации, затем позволяет ppx переписчикам (связанным статически или динамически) регистрировать себя и затем запускает все или некоторые из них. Также возможно, чтобы -ppx драйверы применяли переписчиков только к определенным частям АСТ.

Первый аргумент для register — это символическое имя, используемое ppx драйвером.

Функции для удобства написания переписчиков

val map_opt : ('a -> 'b) -> 'a option -> 'b option
val extension_of_error : Location.error -> Parsetree.extension

Кодирование ошибки в узел расширения 'ocaml.error', который может быть вставлен в сгенерированном Parsetree. Компилятор будет отвечать за сообщение об ошибке.

val attribute_of_warning : Location.t -> string -> Parsetree.attribute

Кодирование сообщения об ошибке в атрибут 'ocaml.ppwarning', который может быть вставлен в сгенерированном Parsetree. Компилятор будет отвечать за сообщение о предупреждении.

Вспомогательные функции для вызова внешних переписчиков

val add_ppx_context_str : tool_name:string -> Parsetree.structure -> Parsetree.structure

Извлечение информации из текущей среды и кодирование ее в атрибут, который добавляется в список элементов структуры для передачи информации внешнему процессору.

val add_ppx_context_sig : tool_name:string -> Parsetree.signature -> Parsetree.signature

То же, что и add_ppx_context_str, но для сигнатур.

val drop_ppx_context_str : restore:bool -> Parsetree.structure -> Parsetree.structure

Удаление атрибута ocaml.ppx.context из структуры. Если restore равно true, также восстановить связанные данные в текущем процессе.

val drop_ppx_context_sig : restore:bool -> Parsetree.signature -> Parsetree.signature

То же, что и drop_ppx_context_str, но для сигнатур.

Куки

Куки используются для передачи информации от ppx процессора к дальнейшему вызову его самого, когда он вызывается из OCaml интерпретатора (или других инструментов, которые поддерживают куки).

val set_cookie : string -> Parsetree.expression -> unit
val get_cookie : string -> Parsetree.expression option

© 1995-2024 INRIA.
https://ocaml.org/manual/5.2/api/compilerlibref/Ast_mapper.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API