我OCaml中是新的,这里是我的原代码:我可以用这种方式写“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
是不是不够好?有没有更优雅的方式?
关于你的更新,你的'让集... = i'其实都是非详尽的图案匹配问题,因为编译器应该警告过你(即使在这种情况下,你知道该模式是正确的)。触发编译器警告很少是一个好主意。在我看来,BenoîtGuédas使用'as'结合的答案是最好的解决方案。一个小的优化可以使用'Cil.isPointerType'而不是本地定义的'isPtr',但就是这样。 – Virgile