2013-03-31 44 views
5

我有这段包含camlp4引用的代码。打印OCaml AST作为OCaml代码

let f_name = "my_func" 
<:str_item< value $lid:f_name$ a = a * 2 >> 

通过camlp4of运行此之后,它会产生这样的:

Ast.StExp (_loc, 
    (Ast.ExApp (_loc, 
     (Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "=")))), 
      (Ast.ExApp (_loc, 
      (Ast.ExApp (_loc, 
       (Ast.ExId (_loc, (Ast.IdLid (_loc, "value")))), 
       (Ast.ExId (_loc, (Ast.IdLid (_loc, f_name)))))), 
      (Ast.ExId (_loc, (Ast.IdLid (_loc, "a")))))))), 
     (Ast.ExApp (_loc, 
      (Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "*")))), 
      (Ast.ExId (_loc, (Ast.IdLid (_loc, "a")))))), 
      (Ast.ExInt (_loc, "2"))))))) 

我的问题是这样的,反正是有打印生成的代码OCaml的?我应该使用什么camlp4of命令或选项来显示代码?我期望从上面的例子中看到的是:

value my_func a = a * 2 

这可能吗?原因是因为我想做一些调试,看看生成的ocaml代码是怎样的。

回答

5

这是我几天前问过自己的一个很好的问题。

可以使用`Camlp4.PreCast.Printers.OCaml.print_implem其具有类型

value print_implem : ?input_file:string -> ?output_file:string -> 
        Ast.str_item -> unit; 

例如,在顶层(仅示出的最后一个命令的输出):

# #use "topfind";; 
# #require "camlp4";; 
# #load "camlp4of.cma";; 
# open Camlp4.PreCast;; 
# let _loc = Loc.ghost;; 
# let test = 
    let f_name = "my_func" in 
    <:str_item< value $lid:f_name$ a = a * 2 >>;; 
# Printers.OCaml.print_implem test;; 
let _ = (value my_func a) = (a * 2);; 
- : unit =() 

另一种解决方案是创建一个语法扩展,它将生成您正在查找的输出。例如,一个Camlp4AstFilter只会忽略它的输入,并将你的东西作为输出返回,所以你可以使用camlp4of my_filter.cmo -str ''来获得你正在寻找的AST。

+0

函数'Camlp4.PreCast.Printers.OCaml.print_implem'只适用于'str_item'。有没有其他打印机可​​以打印'expr's? –

+1

当然,在钩子下,但他们不通过'Printers'界面暴露。把你的表情换成'let _ = 'str_item?对于类型,你也可以'输入foo = '等。 – gasche