Guest User

Untitled

a guest
Jun 1st, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 3.01 KB | None | 0 0
  1. (*
  2.     use "set.ml";;
  3.     use "imp-syntax";;
  4. *)
  5.  
  6. type blabel = string;;
  7. type block = BAssignVar of ide * exp
  8.     | BAssignArray of ide * exp * exp
  9.     | BSkip
  10.     | BGuard of exp;;
  11.  
  12. type cfg = (blabel * block) set        (* nodes *)
  13.          * (blabel * blabel) set;;     (* edges *)
  14.  
  15. type s =
  16.     SSkip of blabel
  17.     | SAssignVar of blabel * ide * exp
  18.     | SAssignArray of blabel * ide * exp * exp
  19.     | SCseq of s * s
  20.     | SIf of (blabel * exp) * s * s
  21.     | SWhile of (blabel * exp) * s;;
  22.  
  23. let rec get_last_label n : blabel = match n with
  24.     SSkip l -> l
  25.     | SAssignVar(l, _, _) -> l
  26.     | SAssignArray(l, _, _, _) -> l
  27.     | SCseq(_, s) -> get_last_label s
  28.     | SIf(_, _, s) -> get_last_label s
  29.     | SWhile(_, s) -> get_last_label s;;
  30.  
  31. let labeledprog imp : s = match imp with
  32.     ImpProg(_, c) ->
  33.         let rec labeledprog' c i = match c with
  34.             Skip -> SSkip(string_of_int i)
  35.             | AssignVar(n, e) -> SAssignVar(string_of_int i, n, e)
  36.             | AssignArray(n, p, e) -> SAssignArray(string_of_int i, n, p, e)
  37.             | Cseq(c1, c2) ->
  38.                 let l' = (labeledprog' c1 i) in
  39.                 let i' = int_of_string (get_last_label l') in
  40.                 SCseq(l', (labeledprog' c2 (i' + 1)))
  41.             | If(e, c1, c2) ->
  42.                 let l' = (labeledprog' c1 (i + 1)) in
  43.                 let i' = int_of_string (get_last_label l') in
  44.                 SIf((string_of_int i, e), l', (labeledprog' c2 (i' + 1)))
  45.             | While(e, c) -> SWhile((string_of_int i, e), (labeledprog' c (i + 1)))
  46.     in labeledprog' c 1;;
  47.  
  48. let rec init s : blabel = match s with
  49.         SSkip l -> l
  50.         | SAssignVar(l, _, _) -> l
  51.         | SAssignArray(l, _, _, _) -> l
  52.         | SCseq(s1, _) -> init s1
  53.         | SIf((l, _), _, _) -> l
  54.         | SWhile((l, _), _) -> l;;
  55.  
  56. let rec final s : blabel set = match s with
  57.     SSkip l -> [l]
  58.     | SAssignVar(l, _, _) -> [l]
  59.     | SAssignArray(l, _, _, _) -> [l]
  60.     | SCseq(_, s2) -> final s2
  61.     | SIf(_, s1, s2) -> final s1 @ final s2
  62.     | SWhile((l, _), _) -> [l];;
  63.  
  64. let rec labels s : blabel set = match s with
  65.     SSkip l -> [l]
  66.     | SAssignVar(l, _, _) -> [l]
  67.     | SAssignArray(l, _, _, _) -> [l]
  68.     | SCseq(s1, s2) -> labels s1 @ labels s2
  69.     | SIf((l, _), s1, s2) -> [l] @ labels s1 @ labels s2
  70.     | SWhile((l, _), s) -> [l] @ labels s;;
  71.  
  72. let rec flow s : (blabel * blabel) set = match s with
  73.     SSkip l -> []
  74.     | SAssignVar _ -> []
  75.     | SAssignArray _ -> []
  76.     | SCseq(s1, s2) ->
  77.         flow s1 @ flow s2 @ [(List.hd (final s1), init s2)]
  78.     | SIf((l, _), s1, s2) ->
  79.         flow s1 @ flow s2 @ [init s1, init s2]
  80.     | SWhile((l, _), s) ->
  81.         flow s @ [(l, init s)] @ [List.hd (final s), l];;
  82.  
  83. let flow_rev s : (blabel * blabel) set =
  84.     let rec flow_rev' f = match f with
  85.         [] -> []
  86.         | (l, l')::f -> [(l', l)] @ flow_rev' f
  87.     in flow_rev' (flow s);;
  88.    
  89. let rec blocks s : (blabel * block) set = match s with
  90.     SSkip l -> [l, BSkip]
  91.     | SAssignVar(l, n, e) -> [l, BAssignVar(n, e)]
  92.     | SAssignArray(l, n, p, e) -> [(l, BAssignArray(n, p, e))]
  93.     | SCseq(s1, s2) -> blocks s1 @ blocks s2
  94.     | SIf((l, e), s1, s2) -> [l, BGuard e] @ blocks s1 @ blocks s2
  95.     | SWhile((l, e), s) -> [l, BGuard e] @ blocks s;;
  96.    
  97. let cfg_of_imp imp : cfg =
  98.     let s = labeledprog imp in
  99.     (blocks s, flow s);;
Add Comment
Please, Sign In to add comment