2016-02-23 11 views
5

Sto tentando di compilare una stringa di codice sorgente e stampare l'albero di analisi utilizzando Poly/ML. Il seguente codice compila, ma l'albero sintattico è vuota:Come ottenere l'albero di analisi dalla stringa del codice sorgente in 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 

L'esecuzione di questo:

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

Che cosa devo fare per ottenere l'albero sintattico dal compilatore? Ho anche provato una variazione utilizzando il parametro del compilatore CPCompilerResultFun. Ma questo non ha funzionato neanche:

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 

L'esecuzione di questo non produce alcun output.

risposta

3

Sono stato in grado di ottenerlo fornendo l'opzione del compilatore PolyML.Compiler.CPCompilerResultFun. Ti permette di access and save the parse tree. Tuttavia, non posso dire troppo su come l'albero di analisi sia effettivamente rappresentato. C'è della documentazione here (il sito web è giù per me), ma non potevo ancora averne troppo senso.

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(); 
+0

Potresti dimostrare i valori dell'albero di analisi? Ho usato il tuo codice e ho provato a stampare (a, b, c, ecc.) E ha stampato "fn" a prescindere. – eatonphil

+1

@eatonphil Non riuscivo a capire come attraversare l'albero. Darò un'occhiata più profonda stasera. Tutto quello che posso dire è non "PolyML.print", eseguire lo script all'interno del REPL, fornisce una migliore stampa carina. –

+1

In realtà, ho capito cosa stavo facendo male. Questi valori sono funzioni il cui valore di stampa è "fn". Li ho chiamati ed è stato in grado di ispezionare quello che mi aspettavo un po 'più chiaro. – eatonphil