2017-02-03 10 views
1

Есть ли инструмент OCaml, который позволяет фильтровать комментарии в исходных файлах, похожие на gcc -E?Lexer/filter для комментариев

В идеале, я ищу что-то, что удалит все , но комментариев, но наоборот.

Например, если есть возможность использовать camlp4/campl5/ppx для получения комментариев OCaml (включая комментарии, отличные от OCamldoc, определенные одной звездочкой), я хотел бы знать. У меня не было большого успеха в поиске узлов комментариев в ASTM 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, чтобы получить то, что было удалено.

ответ

0

Ну, теперь есть лексер на основе ocamlwc, что полосы все, кроме комментариев в коде, называемых ocaml-comment-sieve. Он основан на простой лексер, используемый в ocamlwc.

Однако этот инструмент лицензирован GPL (поскольку он получен из ocamlwc, который лицензирован GPL), поэтому it cannot be posted here. Тем не менее, он удовлетворяет моим требованиям, поэтому, пока кто-то не предложит лучший способ, я буду рассматривать его как ответ.

1

Вы можете использовать ocamldoc с настраиваемым генератором, который будет выгружать комментарии, используя текстовое представление.

+0

К сожалению, похоже, что ocamldoc не учитывает одиночные комментарии. Если я буду использовать 'sed', чтобы преобразовать его, он слишком усердствует, чтобы проанализировать их, что приведет к нескольким видам ошибок. Кроме того, тот факт, что для него требуется какая-то настройка компиляции (например, '-I' пути, позволяющие находить файлы' .cmi', например), делает его довольно тяжелым для того, что я намеревался. – anol

1

Я сделал несколько интересных экспериментов с 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 (верхнего уровня элементов интерфейсов модулей), расширяя соответствующий принтер по умолчанию с уловом-все 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 
+1

Это работает для комментариев toplevel, но, к сожалению, не для комментариев внутри функций, например. Он решает часть проблемы, но не все, поэтому я все еще ищу другое решение. – anol

+0

Да, я это заметил.Я попытался сыграть немного больше с camlp5, но документация немного скудна по этой теме, и я не добился большого прогресса. – Virgile