Лексер / фильтр для комментариев
Есть ли инструмент OCaml, который позволяет фильтровать комментарии в исходных файлах, аналогично gcc -E
?
В идеале я ищу что-то, что удалит все, кроме комментариев, но было бы полезно и наоборот.
Например, если есть способ использовать camlp4/campl5/ppx для получения комментариев OCaml (включая комментарии не OCamldoc, определенные с помощью одной звездочки), я хотел бы знать. У меня не было большого успеха в поиске узлов комментариев в AST Camlp4 (хотя я знаю, что он должен существовать, потому что есть даже ошибки, связанные с тем, что Camlp4 изменяет их размещение).
Вот пример: в следующем файле:
(*** three asterisks *)
let f () =
Format.printf "end"
let () =
(* one asterisk (* nested comment *) *)
Printf.printf "hello world\n";
(** two asterisks *)
f();
()
Я хотел бы в идеале получить:
(*** three asterisks *)
(* one asterisk (* nested comment *) *)
(** two asterisks *)
Пробелы между ними и наличие или отсутствие (* *)
в основном не имеют значения, но он должен сохранять комментарии всех видов. Моя непосредственная цель - иметь возможность отфильтровать его для проверки орфографии, но очистка комментариев (то есть наличие фильтра, который удаляет только комментарии) также может быть полезна: я могу очистить комментарии и затем использовать diff
чтобы получить то, что было удалено.
3 ответа
Что ж, теперь существует лексер, основанный на ocamlwc, который удаляет все, кроме комментариев в коде, называемый ocaml-comment-sieve. Он основан на простом лексере, используемом в ocamlwc
,
Тем не менее, этот инструмент имеет лицензию GPL (потому что он является производным от ocamlwc
, который имеет лицензию GPL), поэтому не может быть размещен здесь. Тем не менее, он удовлетворяет моим требованиям, поэтому, пока кто-то не предложит лучший способ, я буду рассматривать его как ответ.
Я провел несколько интересных экспериментов с camlp5, подыгрывая идее симпатичной печати ""
для любого элемента кода. Следующий код:
let ignore _ _ _ = ""
let rule f = Extfun.(extend f [Evar (),false, fun _ -> Some ignore])
let () =
Eprinter.extend Pcaml.pr_str_item None [ None, rule ];
Eprinter.extend Pcaml.pr_sig_item None [ None, rule ]
отключит красивую печать любого str_item
(т. е. повысить уровень реализации модуля) или sig_item
(toplevel элементы интерфейсов модуля), расширяя соответствующий принтер по умолчанию с универсальным rule
которые выводят пустую строку для любого str_item
, компилировать pr_comment.ml
с
ocamlfind ocamlc -c -package camlp5 pr_comment.ml
и использовать его как
camlp5o pr_o.cmo path/to/pr_comment.cmo -o only_comment.ml my_file.ml