Skip to content

Instantly share code, notes, and snippets.

@eldesh
Last active December 22, 2015 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eldesh/6526181 to your computer and use it in GitHub Desktop.
Save eldesh/6526181 to your computer and use it in GitHub Desktop.
(**
* SML# <-> PCRE(http://www.pcre.org/) binding sample
*)
(*
* ~/work/pcre_sharp$ rlwrap -c smlsharp -L/usr/lib -lpcre
* SML# version 1.2.0 (2012-11-14 18:25:26 JST) for x86-linux
* # use "pcre.sml";
* match!(314)
* structure Pcre = ...
* #
*)
structure Pcre =
struct
infix =~
type pcre = unit ptr
type t = pcre
type table = Word8.word array
type extra = unit ptr
val pcre_compile_null = (* only for giving the NULL pointer *)
_import "pcre_compile"
: (string, int, string ref, int ref, Word8.word ptr)-> pcre
val pcre_compile_array =
_import "pcre_compile"
: (string, int, string ref, int ref, table)-> pcre
val pcre_free =
_import "free"
: pcre -> unit
fun compile (pattern, option, err, erroffset, table) =
case table
of SOME arr => pcre_compile_array (pattern, option, err, erroffset, arr)
| NONE => pcre_compile_null (pattern, option, err, erroffset, Pointer.NULL())
val pcre_exec =
_import "pcre_exec"
: (pcre, unit ptr, string, int, int, int, int array, int) -> int;
fun exec (code, subject, startoffset, option, ovector) =
pcre_exec (code, Pointer.NULL(), subject, size subject
, startoffset, option, ovector, Array.length ovector)
(**
* match pattern that have exactly one capturing subpattern
* e.g.
* "foo (bar)"
* "192.168.0.(\\d+)"
*)
fun match_one str re =
let
val err = ref ""
val errpos = ref 0
val regex = compile (re, 0, err, errpos, NONE)
val arr = Array.array(9, 0) (* how length is required ? *)
in
if 0 < exec (regex, str, 0, 0, arr)
then SOME(String.extract(str, Array.sub(arr, 2), NONE))
else NONE
end
structure Open =
struct
type t = t
fun str =~ re = match_one str re
end
open Open
end
(* sample code *)
local
open Pcre Pcre.Open
infix =~
fun maybe none f (SOME x) = f x
| maybe none f NONE = none
fun println s = print(s^"\n")
in
val _ =
let
val subject = "fixes #(\\d+)"
val pattern = "fixes #314"
val test = println o (maybe "<not match>" (fn x=> "match!("^x^")"))
in
println (concat[subject, " =~ ", pattern]);
test (pattern =~ subject)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment