Программа OCaml для проверки компилирования кода OCaml - PullRequest
2 голосов
/ 20 февраля 2011

Я хотел бы написать модуль OCaml, имеющий функцию compile, которая будет принимать строку, содержащую программу OCaml, и выводить результат компиляции как Correct или Error, а в случае Error - информацию о строке и символе. первой ошибки. Меня не волнует, в чем была ошибка (по крайней мере, на данный момент).

Основной тип модуля для этого:

module type Compile =
    sig
        type result = Correct | Error of (int*int)
        val compile : string -> result
    end

Существует как минимум два принципиально разных способа его реализации:

  1. быстрый способ взлома - записать строку с программой в файл, использовать процессы Unix для вызова ocamlc в командной строке и проанализировать stderr;
  2. правильный путь - используйте инструменты OCaml для анализа кода.

Что касается (1), у меня возникают проблемы с получением содержимого stderr. Я начал с использования Unix.open_process_in, который перенаправляет стандартный вывод в in_channel, который я затем могу прочитать. Так как ошибки компиляции, выводимые ocamlc, идут в stderr (а не в stdout), я попытался использовать

let ic = Unix.open_process_in "ocamlc test.ml 2>&1" 

, чтобы содержимое stderr было перенаправлено в командной строке на stdout. Таким образом, я ожидаю, ic будет содержать ошибки компиляции. К сожалению, это был не тот случай, и ic содержал только End_of_file.

Затем я перешел к команде Unix.create_process, так как она позволяет мне выбирать новые каналы для out, in, err. Но у меня проблемы с выбором этих каналов. Каким должен быть выходной канал, чтобы я мог прочитать его в своей программе?

Что касается (2), что, по вашему мнению, является (разумно) простым путем?

Большое спасибо за любую помощь!

Ответы [ 2 ]

3 голосов
/ 20 февраля 2011

Что касается 2), в установках OCaml обычно есть каталог compiler-lib, содержащий множество модулей, составляющих компилятор, включая синтаксический анализатор.Это не задокументировано, но может использоваться для компиляции и проверки типов.Для синтаксического анализа существует также Camlp4, который можно использовать для выполнения каких-либо задач помимо предварительной обработки (я мог бы представить, что вы можете загрузить Camlp4 в свою программу и использовать его в качестве библиотеки, возможно, после небольшого исправления), но он содержит только грамматикуа не проверщик типов.

2 голосов
/ 20 февраля 2011

Относительно 1) Я думаю, что вы сделали что-то не так. На моей машине:

> ocaml unix.cma
        Objective Caml version 3.12.0

# let ic = Unix.open_process_in "ocamlc test.ml 2>&1";;
val ic : in_channel = <abstr>
# input_line ic;;
- : string = "File \"test.ml\", line 1, characters 0-1:"
# input_line ic;;
- : string = "Error: I/O error: test.ml: No such file or directory"
# input_line ic;;
Exception: End_of_file.

Для Unix.create_process один из способов - передать Unix.stdin для new_stdout, чтобы вы могли прочитать выходные данные процесса через стандартный ввод вашей программы (предполагается, что вы не хотите использовать стандартный ввод). вашей программы для чего-то еще). Но мне проще использовать Unix.open_process_full.

Относительно 2) вы можете попытаться использовать toplevellib.cma (обратите внимание, однако, что это полностью недокументировано и не поддерживается). Взгляните на toplevel/toploop.mli в дистрибутиве, в частности Toploop.execute_phrase.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...