Mendapatkan pohon parsing dari string kode sumber di Poly/ML

Saya mencoba mengkompilasi string kode sumber dan mencetak pohon parse menggunakan Poly/ML. Kode berikut dikompilasi, tetapi pohon parsingnya kosong:

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

Menjalankan ini:

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

Apa yang harus saya lakukan untuk mendapatkan pohon parse dari kompiler? Saya juga mencoba variasi menggunakan parameter kompiler CPCompilerResultFun. Tapi ini juga tidak berhasil:

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

Menjalankan ini tidak menghasilkan output apa pun.


person eatonphil    schedule 23.02.2016    source sumber


Jawaban (1)


Saya bisa mendapatkannya dengan menyediakan opsi kompiler PolyML.Compiler.CPCompilerResultFun. Ini memungkinkan Anda mengakses dan menyimpan pohon parsing. Namun, saya tidak bisa mengatakan terlalu banyak tentang bagaimana pohon parse sebenarnya direpresentasikan. Ada beberapa dokumentasi di sini (situs web tidak aktif bagi saya), tapi saya masih belum bisa memahaminya.

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
Bisakah Anda mendemonstrasikan nilai pohon parse? Saya menggunakan kode Anda dan mencoba mencetak (a, b, c, dll.) dan tetap mencetak fn. - person eatonphil; 24.02.2016
comment
@eatonphil Saya tidak tahu cara melintasi pohon. Saya akan melihat lebih dalam malam ini. Yang bisa saya katakan adalah jangan PolyML.print mereka, jalankan skrip di dalam REPL, ini memberikan pencetakan cantik yang lebih baik. - person IonuČ› G. Stan; 24.02.2016
comment
Sebenarnya, saya sudah tahu apa yang saya lakukan salah. Nilai-nilai tersebut adalah fungsi yang nilai cetak cantiknya adalah fn. Saya menelepon mereka dan dapat melihat apa yang saya harapkan dengan lebih jelas. - person eatonphil; 24.02.2016