【发布时间】:2014-04-01 20:54:26
【问题描述】:
我是 OCaml 的新手,这是我的原始代码:
method vinst(i) =
match i with
| Set (lv , e, _) ->
let (host, _) = lv in
match host with
| Mem _ ->
( self#queueInstr [mkPtrLVal (addressOf lv) e];
ChangeTo [])
| _ -> SkipChildren
......
因为Set (lv, e, _)的模式匹配后,我仍然需要对lv和e进行模式匹配,所以我想用这种方式重写它(摆脱烦人的开始......结束块):
method vinst(i) =
match i with
| Set (lv , e, _) when (Mem _, _) = lv -> (* see I re-write it this way *)
( self#queueInstr [mkPtrLVal (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) when (Lval (Mem _, _)) = lv ->
( self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) when (TPtr _) = typeOf e->
(self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| _ -> DoChildren
我试图编译它,但是
错误:语法错误:需要运算符。
发生...
那么基本上可以这样写?如果是,我应该调整哪个部分?
==================更新===============
这是我刚才所做的:
method vinst(i) =
match i with
| Set ((Mem _, _), e, _) -> (* pattern 1 *)
let Set (lv, e, _) = i in
( self#queueInstr [mkPtrLVal (addressOf lv) e];
ChangeTo [])
| Set (_, Lval (Mem _, _), _) -> (* pattern 2 *)
let Set (lv, e, _) = i in
( self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| Set (lv , e, _) -> (* pattern 3 *)
begin
match typeOf e with
| TPtr _ ->
(self#queueInstr [mkPtrE (addressOf lv) e];
ChangeTo [])
| _ -> SkipChildren
end
| _ -> DoChildren
够好吗?还有更优雅的方式吗?
【问题讨论】:
-
关于您的更新,您的
let Set ... = i实际上是非详尽的模式匹配,因为编译器应该警告您(即使在这种情况下您知道该模式是正确的)。触发编译器警告很少是一个好主意。在我看来,Benoît Guédas 使用asbinder 给出的答案是最好的解决方案。一个小的优化可能是使用Cil.isPointerType而不是本地定义的isPtr,但仅此而已。