PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/re_emacs.ml

http://github.com/avsm/ocaml-re
OCaml | 122 lines | 97 code | 5 blank | 20 comment | 58 complexity | 6a4c2686f40d9ff8aefc4fc1b2baf68b MD5 | raw file
Possible License(s): LGPL-2.1
  1. (*
  2. RE - A regular expression library
  3. Copyright (C) 2001 Jerome Vouillon
  4. email: Jerome.Vouillon@pps.jussieu.fr
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. *)
  17. exception Parse_error
  18. exception Not_supported
  19. let parse s =
  20. let i = ref 0 in
  21. let l = String.length s in
  22. let eos () = !i = l in
  23. let test c = not (eos ()) && s.[!i] = c in
  24. let test2 c c' = !i + 1 < l && s.[!i] = c && s.[!i + 1] = c' in
  25. let accept c = let r = test c in if r then incr i; r in
  26. let accept2 c c' = let r = test2 c c' in if r then i := !i + 2; r in
  27. let get () = let r = s.[!i] in incr i; r in
  28. let unget () = decr i in
  29. let rec regexp () = regexp' (branch ())
  30. and regexp' left =
  31. if accept2 '\\' '|' then regexp' (Re.alt [left; branch ()]) else left
  32. and branch () = branch' []
  33. and branch' left =
  34. if eos () || test2 '\\' '|' || test2 '\\' ')' then Re.seq (List.rev left)
  35. else branch' (piece () :: left)
  36. and piece () =
  37. let r = atom () in
  38. if accept '*' then Re.rep r else
  39. if accept '+' then Re.rep1 r else
  40. if accept '?' then Re.opt r else
  41. r
  42. and atom () =
  43. if accept '.' then begin
  44. Re.notnl
  45. end else if accept '^' then begin
  46. Re.bol
  47. end else if accept '$' then begin
  48. Re.eol
  49. end else if accept '[' then begin
  50. if accept '^' then
  51. Re.compl (bracket [])
  52. else
  53. Re.alt (bracket [])
  54. end else if accept '\\' then begin
  55. if accept '(' then begin
  56. let r = regexp () in
  57. if not (accept2 '\\' ')') then raise Parse_error;
  58. Re.group r
  59. end else if accept '`' then
  60. Re.bos
  61. else if accept '\'' then
  62. Re.eos
  63. else if accept '=' then
  64. Re.start
  65. else if accept 'b' then
  66. Re.alt [Re.bow; Re.eow]
  67. else if accept 'B' then
  68. Re.not_boundary
  69. else if accept '<' then
  70. Re.bow
  71. else if accept '>' then
  72. Re.eow
  73. else if accept 'w' then
  74. Re.alt [Re.alnum; Re.char '_']
  75. else if accept 'W' then
  76. Re.compl [Re.alnum; Re.char '_']
  77. else begin
  78. if eos () then raise Parse_error;
  79. match get () with
  80. '*' | '+' | '?' | '[' | ']' | '.' | '^' | '$' | '\\' as c ->
  81. Re.char c
  82. | '0' .. '9' ->
  83. raise Not_supported
  84. | _ ->
  85. raise Parse_error
  86. end
  87. end else begin
  88. if eos () then raise Parse_error;
  89. match get () with
  90. '*' | '+' | '?' -> raise Parse_error
  91. | c -> Re.char c
  92. end
  93. and bracket s =
  94. if s <> [] && accept ']' then s else begin
  95. let c = char () in
  96. if accept '-' then begin
  97. if accept ']' then Re.char c :: Re.char '-' :: s else begin
  98. let c' = char () in
  99. bracket (Re.rg c c' :: s)
  100. end
  101. end else
  102. bracket (Re.char c :: s)
  103. end
  104. and char () =
  105. if eos () then raise Parse_error;
  106. get ()
  107. in
  108. let res = regexp () in
  109. if not (eos ()) then raise Parse_error;
  110. res
  111. let re ?(case = true) s = let r = parse s in if case then r else Re.no_case r
  112. let compile = Re.compile
  113. let compile_pat ?(case = true) s = compile (re ~case s)