QSParsecTest.fsx 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. module QSParsecTest
  2. #if INTERACTIVE
  3. #r @"..\packages\FParsec.1.0.2\lib\net40-client\FParsecCS.dll"
  4. #r @"..\packages\FParsec.1.0.2\lib\net40-client\FParsec.dll"
  5. #endif
  6. #if INTERACTIVE
  7. #load "reflect.fs"
  8. #load "QSAST.fs"
  9. #load "show.fs"
  10. #endif
  11. #if INTERACTIVE
  12. #load "QSParsec.fs"
  13. #endif
  14. open FParsec
  15. open QSParsec
  16. open QSAST
  17. open Show
  18. let parsingP p = parsing p >> printfn "%A"
  19. parsingP pexpr "sprintchance =< nochance" // sprintchance =< (no chance)
  20. parsingP pstmt "a = obj 's'"
  21. parsingP pstmt "a =- 10"
  22. parsingP pstmt "a = a + 10"
  23. parsingP pstmt "if c:
  24. smt
  25. act arg: pl
  26. elseif c2:
  27. if a: k else pre if cond: d elseif celif: d
  28. stmt2
  29. end"
  30. parsingP pstmt "if x:
  31. s = {
  32. s
  33. }
  34. end"
  35. parsingP pstmt "if a: k else pre if cond: d elseif celif: d"
  36. parsingP pstmt "IF e:
  37. stmt1 & stmt
  38. elseif e2 :
  39. stmt2
  40. stmt3
  41. elseif e3 :
  42. end2
  43. if e4 :
  44. stmt5
  45. elseif e5:
  46. tm
  47. elsei
  48. end
  49. end
  50. "
  51. parsingP pstmt "if k:
  52. wear += 1
  53. end"
  54. //System.Text.Encoding.Default
  55. //System.Text.Encoding.UTF8
  56. parsing (many ploc) (System.IO.File.ReadAllText(@"e:\Disc D\All\It\DefaultBox\drive\C\All2\Games\GamesSourceCode\etoEdit.txt", System.Text.Encoding.UTF8))
  57. |> ignore
  58. //|> fun x -> System.IO.File.WriteAllText(@"e:\res.txt", sprintf "%A" x)
  59. parsing (many ploc) (System.IO.File.ReadAllText(@"e:\Disc D\All\It\DefaultBox\drive\C\All2\Games\GamesSourceCode\al.txt"))
  60. |> ignore
  61. //|> fun x -> System.IO.File.WriteAllText(@"e:\res.txt", sprintf "%A" x)
  62. let printState =
  63. let showValue = function
  64. | Int x -> shows x //| Float x -> x.ToString()
  65. | String x -> bet "'" "'" (x.Replace("'", "''") |> showString)
  66. let ops = Op.toString >> showString
  67. // let ops = function
  68. // | Plus -> "+" | Minus -> "-" | Times -> "*" | Divide -> "/"
  69. // | Eq -> "=" | Gt -> ">" | Ge -> ">=" | Lt -> "<" | Le -> "<=" | Ne -> "<>" // =, >, >=, <, <=, (<>|!)
  70. // | And -> "and" | Or -> "or" | Mod -> "mod"
  71. let unar = function No -> "no" | Obj -> "obj" | Neg -> "-"
  72. let rec showExpr = function
  73. | Val v -> showValue v
  74. | Var v -> showString v
  75. | Func(name, es) -> showString name << showParen true (List.map showExpr es |> joinS ", ")
  76. | UnarExpr(op, e) ->
  77. let space = function Obj | No -> showChar ' ' | Neg -> id
  78. showString (unar op) << space op << showExpr e
  79. //| Expr(op, e1, e2) -> showExpr e1 << showChar ' ' << showString(ops op) << showChar ' ' << showExpr e2
  80. | Expr(op, e1, e2) ->
  81. let prec = Precedences.OpB >> Precedences.prec
  82. let f = function
  83. | Expr(op', _, _) -> showParen (prec op > prec op')
  84. | UnarExpr _ -> showParen true | _ -> id
  85. let f x = f x (showExpr x)
  86. f e1 << showChar ' ' << ops op << showChar ' ' << f e2
  87. | Arr(name, es) -> showString name << bet "[" "]" (List.map showExpr es |> joinS ", ")
  88. let showAssign = function
  89. | Assign.AssignArr(nameVar, expr) -> showString nameVar << bet "[" "]" (showExpr expr)
  90. | Assign.AssignVar name -> showString name
  91. let (|OneStmt|_|) = function
  92. | [x] ->
  93. match x with
  94. | Assign _ | CallSt _ | StarPl _ | Comment _ -> Some x
  95. | AssingCode _ -> None // спорно
  96. | Act _ | If _ -> None
  97. | Sign _ -> None // эту нечисть нужно как можно более нагляднее подчеркнуть. Да странно будет, если она окажется одна в списке инструкций.
  98. | _ -> None
  99. //let (OneStmt x) = [ parsing pstmt "a = 1"; ]
  100. let (|AssingName|) = function AssignArr(x, _) -> x | AssignVar x -> x
  101. let tabss n = Show.replicate n '\t'
  102. let rec state tabs xs =
  103. let f = function [] -> nl | xs -> nl << joinS "\n" (List.map (state <| tabs + 1) xs)
  104. let indent = nl << tabss tabs : ShowS
  105. let rec f' = function
  106. | Assign(AssingName name' as ass, Expr((Plus|Minus) as op, Var name, e)) when name' = name ->
  107. showAssign ass << showChar ' ' << ops op << showString "= " << showExpr e
  108. | Assign(AssingName name' as ass, Expr((Plus|Minus) as op, e, Var name)) when name' = name ->
  109. showAssign ass << showString " =" << ops op << showChar ' ' << showExpr e
  110. | Assign(ass, e) -> showAssign ass << showString " = " << showExpr e
  111. | CallSt(name, es) -> showString name << showChar ' ' << (List.map showExpr es |> joinS ", ")
  112. | StarPl e -> showExpr e
  113. | Sign s -> showChar ':' << showString s
  114. | If(e, body, elseBody) ->
  115. let ifBegin e = showString "if " << showExpr e << showChar ':'
  116. let body =
  117. match body, elseBody with
  118. | OneStmt x, OneStmt y -> showChar ' ' << f' x << showString " else " << f' y
  119. | OneStmt x, [] -> showChar ' ' << f' x
  120. //| [CallSt _ as x], [CallSt _ as y] -> showChar ' ' << f' x << showString " else " << f' y
  121. //| [Assign _ as x], [] | [CallSt _ as x], [] | [StarPl _ as x], [] -> showChar ' ' << f' x
  122. | xs, ys ->
  123. let rec els xs =
  124. if List.isEmpty xs then id
  125. else
  126. let body = function [If(e, xs, ys)] -> ifBegin e << f xs << els ys | xs -> f xs
  127. indent << showString "else" << body xs
  128. // | [] -> id
  129. // | [If(e, xs, ys)] ->
  130. // indent << showString "else" << ifBegin e << f xs << els ys
  131. // | ys ->
  132. // indent << showString "else" << f ys
  133. f xs << els ys << indent << showString "end"
  134. ifBegin e << body
  135. | Act(es, body) ->
  136. let fbody = function
  137. | OneStmt x -> showChar ' ' << f' x
  138. | xs -> f xs << indent << showString "end"
  139. showString "act " << joinS ", " (List.map showExpr es) << showChar ':' << fbody body
  140. | Comment s -> showChar '!' << showString s
  141. | AssingCode(ass, stmts) ->
  142. showAssign ass << showString " = " << showChar '{' << nl << (f stmts) << indent << showChar '}'
  143. tabss tabs << f' xs
  144. state 0
  145. let showLoc (Location(name, statements)) =
  146. showString "# " << showString name << nl
  147. << joinS "\n" (List.map printState statements) << nl
  148. << showString (sprintf "--- %s ----------" name)
  149. let printLocs xs = List.map showLoc xs |> joinS "\n\n" |> show
  150. let s = parsing pstmt "k = k + 1" //"a = a = (no a) > b"
  151. let s' = parsing pstmt "a = a = no (a > b)"
  152. let test p s =
  153. let p = parsing p
  154. let before = p s
  155. let after = printState before |> show |> p
  156. if after <> before then failwithf "before:\n%A\nafter:\n%A" before after
  157. test pstmt "a = a = no -a > b"
  158. parsingP pstmt "asdf obj 'Персонаж'"
  159. parsingP pstmt "a = pstam> (pmaxstam/4)*2 and pstam <= (pmaxstam/4)*3"
  160. test pstmt "php -= 3*emdmg*2 - parm"
  161. parsing pstmt """php =+ 3*emdmg*2 - parm"""
  162. |> printState |> show |> printfn "%A"
  163. printState s |> show |> printfn "%s"
  164. printState s' |> show |> printfn "%s"
  165. let str = System.IO.File.ReadAllText(@"e:\Disc D\All\It\DefaultBox\drive\C\All2\Games\GamesSourceCode\destiny 0.5.txt", System.Text.Encoding.Default)
  166. let res = parsing (many ploc) str
  167. let test2 =
  168. let f x =
  169. let s = printState x |> show
  170. if s |> parsing pstmt = x then None
  171. else Some(s)
  172. List.choose (function Location(name, stmts) -> match List.choose f stmts with [] -> None | xs -> Some(name, xs)) res
  173. res |> fun x -> System.IO.File.WriteAllText(@"e:\res.txt", printLocs x)
  174. //System.IO.File.WriteAllLines(@"e:\res2.txt", test2)