Получение дерева разбора из строки исходного кода в 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
Запуск этого не производит никакого вывода.
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 ();