Разбор файла OCaml с помощью OCaml
Я хочу проанализировать файлы OCaml (.ml), используя OCaml. Я хочу разбить файлы на абстрактные синтаксические деревья для анализа. Я пытался использовать camlp4, но мне не повезло. Кто-нибудь еще успешно делал это раньше? Это лучший способ для анализа файла OCaml?
2 ответа
(Я предполагаю, что вы уже знаете основные части OCaml: как писать код OCaml, как связывать модули и библиотеки, как писать сценарии сборки и т. Д. Если нет, сначала изучите их.)
Наилучшим способом является использование подлинного анализатора кода OCaml, используемого в самом компиляторе OCaml, поскольку он на 100% совместим по определению.
CamlP4 также реализует синтаксический анализатор OCaml, но он немного несовместим с подлинным синтаксическим анализатором, и дерево синтаксического анализа несколько специализировано для написания расширений синтаксиса: не очень хорошо для любого другого вида анализа.
Вы можете захотеть разобрать .ml
файлы с расширениями синтаксиса с использованием P4. Даже в этом случае вам следует придерживаться подлинного синтаксического анализатора: вы можете удалить исходный код с помощью P4, а затем отправить результат в анализатор с помощью подлинного синтаксического анализатора.
Чтобы использовать парсер компилятора OCaml, проще всего использовать пакет OCamlFind compiler-libs.common. Он содержит анализатор и средство проверки типов компилятора OCaml.
Начните с изменения driver/compile.ml
исходного кода компилятора OCaml, он реализует основные этапы компиляции: вызов препроцессора, анализ, типизация и генерация кода. Разобрать .ml
файлы, которые вы должны изменить (или упростить) Compile.implementation
, За .mli
файлы Compile.interface
,
Удачи.
Не могли бы вы использовать опцию -dparsetree для компилятора ocaml?
hello.ml:
let _ = print_endline "Hello AST"
Теперь скомпилируйте это:
$ ocamlc -dparsetree hello.ml
Что приводит к:
[
structure_item (hello.ml[1,0+0]..[1,0+33])
Pstr_eval
expression (hello.ml[1,0+8]..[1,0+33])
Pexp_apply
expression (hello.ml[1,0+8]..[1,0+21])
Pexp_ident "print_endline" (hello.ml[1,0+8]..[1,0+21])
[
<label> ""
expression (hello.ml[1,0+22]..[1,0+33])
Pexp_constant Const_string("Hello AST",None)
]
]
См. Также этот пост в блоге о расширениях -ppx, в котором содержится некоторая информация о расширениях синтаксиса точек расширения (новый способ написания расширений синтаксиса в OCaml 4.02). Там есть информация о различных модулях манипуляции AST.