PageRenderTime 65ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/re_emacs.ml

https://github.com/heidi-ann/ocaml-re
OCaml | 121 lines | 96 code | 5 blank | 20 comment | 58 complexity | 4dcec5bf5424c96fff858da44a181b37 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 rec regexp () = regexp' (branch ())
  29. and regexp' left =
  30. if accept2 '\\' '|' then regexp' (Re.alt [left; branch ()]) else left
  31. and branch () = branch' []
  32. and branch' left =
  33. if eos () || test2 '\\' '|' || test2 '\\' ')' then Re.seq (List.rev left)
  34. else branch' (piece () :: left)
  35. and piece () =
  36. let r = atom () in
  37. if accept '*' then Re.rep r else
  38. if accept '+' then Re.rep1 r else
  39. if accept '?' then Re.opt r else
  40. r
  41. and atom () =
  42. if accept '.' then begin
  43. Re.notnl
  44. end else if accept '^' then begin
  45. Re.bol
  46. end else if accept '$' then begin
  47. Re.eol
  48. end else if accept '[' then begin
  49. if accept '^' then
  50. Re.compl (bracket [])
  51. else
  52. Re.alt (bracket [])
  53. end else if accept '\\' then begin
  54. if accept '(' then begin
  55. let r = regexp () in
  56. if not (accept2 '\\' ')') then raise Parse_error;
  57. Re.group r
  58. end else if accept '`' then
  59. Re.bos
  60. else if accept '\'' then
  61. Re.eos
  62. else if accept '=' then
  63. Re.start
  64. else if accept 'b' then
  65. Re.alt [Re.bow; Re.eow]
  66. else if accept 'B' then
  67. Re.not_boundary
  68. else if accept '<' then
  69. Re.bow
  70. else if accept '>' then
  71. Re.eow
  72. else if accept 'w' then
  73. Re.alt [Re.alnum; Re.char '_']
  74. else if accept 'W' then
  75. Re.compl [Re.alnum; Re.char '_']
  76. else begin
  77. if eos () then raise Parse_error;
  78. match get () with
  79. '*' | '+' | '?' | '[' | ']' | '.' | '^' | '$' | '\\' as c ->
  80. Re.char c
  81. | '0' .. '9' ->
  82. raise Not_supported
  83. | _ ->
  84. raise Parse_error
  85. end
  86. end else begin
  87. if eos () then raise Parse_error;
  88. match get () with
  89. '*' | '+' | '?' -> raise Parse_error
  90. | c -> Re.char c
  91. end
  92. and bracket s =
  93. if s <> [] && accept ']' then s else begin
  94. let c = char () in
  95. if accept '-' then begin
  96. if accept ']' then Re.char c :: Re.char '-' :: s else begin
  97. let c' = char () in
  98. bracket (Re.rg c c' :: s)
  99. end
  100. end else
  101. bracket (Re.char c :: s)
  102. end
  103. and char () =
  104. if eos () then raise Parse_error;
  105. get ()
  106. in
  107. let res = regexp () in
  108. if not (eos ()) then raise Parse_error;
  109. res
  110. let re ?(case = true) s = let r = parse s in if case then r else Re.no_case r
  111. let compile = Re.compile
  112. let compile_pat ?(case = true) s = compile (re ~case s)