是否有可能编写一个camlp4语法扩展,使您可以访问最后一个let绑定作为字符串?

时间:2012-01-05 05:55:30

标签: ocaml camlp4

我有一些这样的代码:

  type boolean = T | F
  type  bexp = Const of boolean 
  |  Var of variable
  |  Bop of bop * bexp * bexp
  |  Not of bexp
  and bop = And | Or | Xor 
  and variable = { name: string; mutable value: boolean }

如果我想创建一个我必须做的变量:

let full         = Var({name ="full"; value  = F});;   

我宁愿不必重复两次“完整”,并希望想出一些内省的方法来将名称作为字符串。我认为camlp4可以为此工作,但不知道从哪里开始。

所以最终我希望能够做到这样的事情:

let full          = Var({name = :letname:; value = F});;

其中:letname:将当前的let绑定填充为字符串代替(在本例中为“full”)。 (语法:letname:只是一个建议,其他语法的想法不会与OCaml的语法冲突?)

这样一个更简洁的语法可能更可取:

var full = F 

然后将扩展为:

let full = Var({name = "full"; value = F});;

这可能与camlp4有关吗?如果是这样,我该如何处理呢?

(经过进一步考虑,:letname:语法或类似的东西会更通用,在更多领域有用)

2 个答案:

答案 0 :(得分:3)

尝试以下方法。在单独的文件中,例如test.ml

(* A simple syntax extension for getting the name of an identifier. *) 
open Camlp4 

(* Create an ID for the macro*) 
module Id : Sig.Id = struct 
    let name = "let'"
    let version = "1.0" 
end 

module Make (Syntax : Sig.Camlp4Syntax) = struct 
    open Sig 
    include Syntax 

    (* Extend the syntax with a let' x=e1 in e2 construction*) 
    EXTEND Gram 
    expr: [ 
        [ "let'"; x = patt ; "=" ; e1=expr; "in"; e2=expr -> 
            let name=begin match x with
                | Ast.PaId (_,Ast.IdLid(_,name)) -> name
                | _ -> failwith "Require an identifier in a let' statement."
            end in
            <:expr<
                let $x$ = $e1$ in ($str:name$,$e2$)
            >>
        ] 
    ]; 
    END 
end 

module M = Register.OCamlSyntaxExtension(Id)(Make) 

接下来,使用

进行编译
 ocamlc -c -I +camlp4 dynlink.cma camlp4lib.cma -pp camlp4of.opt test.ml

在顶层

 ocaml dynlink.cma -I +camlp4 camlp4of.cma

然后

# #load "test03.cmo";;
# let' x=1 in x;;
- : string * int = ("x", 1)

为了使用扩展编译,请创建一个不同的文件,例如test2.ml

let' x=1 in x

然后,用

编译
ocamlc -pp "camlp4of test.cmo" test2.ml

答案 1 :(得分:0)

是的,这是可能的。首先阅读一些camlp4教程,了解它是如何工作的,并提出更具体的问题。

相关问题