Получение дерева разбора из строки исходного кода в Poly/ML

Я пытаюсь скомпилировать строку исходного кода и распечатать дерево синтаксического анализа с помощью Poly/ML. Следующий код компилируется, но дерево синтаксического анализа пусто:

fun main () =
    let
        val stream = TextIO.openString "let val a = \"abc\"; val b = \"def\"; val c = a ^ b in print c end";
        val _ = PolyML.compiler (fn () => TextIO.input1 stream, []);
        val (_, parseTree) = !PolyML.IDEInterface.parseTree
    in
        PolyML.print (parseTree);
        PolyML.print (List.length parseTree);
        List.map PolyML.print (parseTree);
        ()
    end

Выполнение этого:

$ ./a.out
[...]
0
$

Что мне нужно сделать, чтобы получить дерево разбора от компилятора? Я также попробовал вариант с использованием параметра компилятора CPCompilerResultFun. Но и это не сработало:

fun main () =
    let
        fun useTree (NONE, _) () =
            (PolyML.print "not parsed"; ())
          | useTree (SOME parseTree, _) () =
            (PolyML.print "parsed"; PolyML.print parseTree; ());

        val stream = TextIO.openString "let val a = \"abc\"; val b = \"def\"; val c = a ^ b in print c end";
        val _ = PolyML.compiler (fn () => TextIO.input1 stream, [PolyML.Compiler.CPCompilerResultFun useTree]);
    in
        ()
    end

Запуск этого не дает никакого вывода.


person eatonphil    schedule 23.02.2016    source источник


Ответы (1)


Я смог получить его, предоставив параметр компилятора PolyML.Compiler.CPCompilerResultFun. Он позволяет получить доступ к дереву синтаксического анализа и сохранить его. Однако я не могу сказать слишком много о том, как на самом деле представлено дерево синтаксического анализа. Есть некоторая документация здесь (веб-сайт не работает для меня), но я еще не мог понять это слишком много.

val resultTrees : PolyML.parseTree list ref = ref [];

fun compilerResultFun (parsetree, codeOpt) =
  let
    val _ =
      case parsetree of
        SOME pt => resultTrees := !resultTrees @ [pt]
      | NONE => ()
  in
    fn () => raise Fail "not implemented"
  end;

val stream = TextIO.openString "val a = 1";

val _ = PolyML.compiler (fn () => TextIO.input1 stream, [
  PolyML.Compiler.CPCompilerResultFun compilerResultFun
]);

val [(a, [PolyML.PTfirstChild b])] = !resultTrees;
val (_, [PolyML.PTfirstChild c, PolyML.PTparent d, PolyML.PTprint e]) = b ();
person Ionuț G. Stan    schedule 24.02.2016
comment
Не могли бы вы продемонстрировать значения дерева синтаксического анализа? Я использовал ваш код и попытался напечатать (a, b, c и т. д.), и он все равно напечатал fn. - person eatonphil; 24.02.2016
comment
@eatonphil Я не мог понять, как пройти по дереву. Вечером посмотрю глубже. Все, что я могу сказать, это не PolyML.print их, запускайте скрипт внутри REPL, это обеспечивает лучшую красивую печать. - person Ionuț G. Stan; 24.02.2016
comment
Собственно, я понял, что я делаю не так. Эти значения являются функциями, чье красивое печатное значение равно fn. Я позвонил им и смог проверить то, что я ожидал, немного яснее. - person eatonphil; 24.02.2016