我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