signature BASIC_SCAN = sig type message = unit -> string (*error msg handler*) val !! : ('a * message option -> message) -> ('a -> 'b) -> 'a -> 'b val !!! : string -> ('a -> string option) -> ('a -> 'b) -> 'a -> 'b (*apply function*) val >> : ('a -> 'b * 'c) * ('b -> 'd) -> 'a -> 'd * 'c (*alternative*) val || : ('a -> 'b) * ('a -> 'b) -> 'a -> 'b (*sequential pairing*) val -- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e (*dependent pairing*) val :-- : ('a -> 'b * 'c) * ('b -> 'c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e (*projections*) val :|-- : ('a -> 'b * 'c) * ('b -> 'c -> 'd * 'e) -> 'a -> 'd * 'e val |-- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'd * 'e val --| : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'b * 'e (*concatenation*) val ^^ : ('a -> string * 'b) * ('b -> string * 'c) -> 'a -> string * 'c val ::: : ('a -> 'b * 'c) * ('c -> 'b list * 'd) -> 'a -> 'b list * 'd val @@@ : ('a -> 'b list * 'c) * ('c -> 'b list * 'd) -> 'a -> 'b list * 'd (*one element literal*) val $$ : string -> stringlist -> string * stringlist val ~$$ : string -> stringlist -> string * stringlist end;
signature SCAN = sig
include BASIC_SCAN val permissive: ('a -> 'b) -> 'a -> 'b val error: ('a -> 'b) -> 'a -> 'b val catch: ('a -> 'b) -> 'a -> 'b (*exception Fail*) val recover: ('a -> 'b) -> (string -> 'a -> 'b) -> 'a -> 'b val triple1: ('a * 'b) * 'c -> 'a * 'b * 'c val triple2: 'a * ('b * 'c) -> 'a * 'b * 'c val fail: 'a -> 'b val fail_with: ('a -> message) -> 'a -> 'b val succeed: 'a -> 'b -> 'a * 'b val some: ('a -> 'b option) -> 'a list -> 'b * 'a list val one: ('a -> bool) -> 'a list -> 'a * 'a list val this: stringlist -> stringlist -> stringlist * stringlist val this_string: string -> stringlist -> string * stringlist val many: ('a -> bool) -> 'a list -> 'a list * 'a list val many1: ('a -> bool) -> 'a list -> 'a list * 'a list val optional: ('a -> 'b * 'a) -> 'b -> 'a -> 'b * 'a valoption: ('a -> 'b * 'a) -> 'a -> 'b option * 'a val repeat: ('a -> 'b * 'a) -> 'a -> 'b list * 'a val repeat1: ('a -> 'b * 'a) -> 'a -> 'b list * 'a val repeats: ('a -> 'b list * 'a) -> 'a -> 'b list * 'a val repeats1: ('a -> 'b list * 'a) -> 'a -> 'b list * 'a val single: ('a -> 'b * 'a) -> 'a -> 'b list * 'a val bulk: ('a -> 'b * 'a) -> 'a -> 'b list * 'a val max: ('a * 'a -> bool) -> ('b -> 'a * 'b) -> ('b -> 'a * 'b) -> 'b -> 'a * 'b val ahead: ('a -> 'b * 'c) -> 'a -> 'b * 'a val unless: ('a -> 'b * 'a) -> ('a -> 'c * 'd) -> 'a -> 'c * 'd val first: ('a -> 'b) list -> 'a -> 'b val state: 'a * 'b -> 'a * ('a * 'b) val depend: ('a -> 'b -> ('c * 'd) * 'e) -> 'a * 'b -> 'd * ('c * 'e) val peek: ('a -> 'b -> 'c * 'd) -> 'a * 'b -> 'c * ('a * 'd) val provide: ('a -> bool) -> 'b -> ('b * 'c -> 'd * ('a * 'e)) -> 'c -> 'd * 'e val pass: 'a -> ('a * 'b -> 'c * ('d * 'e)) -> 'b -> 'c * 'e val lift: ('a -> 'b * 'c) -> 'd * 'a -> 'b * ('d * 'c) val unlift: (unit * 'a -> 'b * ('c * 'd)) -> 'a -> 'b * 'd val trace: ('a list -> 'b * 'c list) -> 'a list -> ('b * 'a list) * 'c list type'a stopper val stopper: ('a list -> 'a) -> ('a -> bool) -> 'a stopper val is_stopper: 'a stopper -> 'a -> bool val finite': 'a stopper -> ('b * 'a list -> 'c * ('d * 'a list))
-> 'b * 'a list -> 'c * ('d * 'a list) val finite: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b * 'a list val read: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b option val drain: ('a -> 'b list * 'a) -> 'b stopper -> ('c * 'b list -> 'd * ('e * 'b list)) ->
('c * 'b list) * 'a -> ('d * ('e * 'b list)) * 'a type lexicon val is_literal: lexicon -> stringlist -> bool val literal: lexicon -> (string * 'a) list -> (string * 'a) list * (string * 'a) list val empty_lexicon: lexicon val build_lexicon: (lexicon -> lexicon) -> lexicon val extend_lexicon: stringlist -> lexicon -> lexicon val make_lexicon: stringlistlist -> lexicon val dest_lexicon: lexicon -> stringlist val merge_lexicons: lexicon * lexicon -> lexicon end;
structure Scan: SCAN = struct
(** scanners **)
(* exceptions *)
type message = unit -> string;
exception MORE of unit; (*need more input*)
exception FAIL of message option; (*try alternatives (reason of failure)*)
exception ABORT of message; (*dead end*)
fun unless test scan =
ahead (optiontest) :-- (fn NONE => scan | _ => fail) >> #2;
fun first [] = fail
| first (scan :: scans) = scan || first scans;
(* state based scanners *)
fun state (st, xs) = (st, (st, xs));
fun depend scan (st, xs) = letval ((st', y), xs') = scan st xs in (y, (st', xs')) end;
fun peek scan = depend (fn st => scan st >> pair st);
fun provide pred st scan xs = letval (y, (st', xs')) = scan (st, xs) inif pred st' then (y, xs') else fail () end;
fun pass st = provide (K true) st;
fun lift scan (st, xs) = letval (y, xs') = scan xs in (y, (st, xs')) end;
fun unlift scan = pass () scan;
(* trace input *)
fun trace scan xs = letval (y, xs') = scan xs in ((y, take (length xs - length xs') xs), xs') end;
(* stopper *)
datatype'a stopper = Stopper of ('a list -> 'a) * ('a -> bool);
fun stopper mk_stopper is_stopper = Stopper (mk_stopper, is_stopper); fun is_stopper (Stopper (_, is_stopper)) = is_stopper;
(* finite scans *)
fun finite' (Stopper (mk_stopper, is_stopper)) scan (state, input) = let fun lost () = raise ABORT (fn () => "Bad scanner: lost stopper of finite scan!");
fun stop [] = lost ()
| stop lst = letval (xs, x) = split_last lst inif is_stopper x then ((), xs) else lost () end; in ifexists is_stopper input then raise ABORT (fn () => "Stopper may not occur in input of finite scan!") else (strict scan --| lift stop) (state, input @ [mk_stopper input]) end;
fun finite stopper scan = unlift (finite' stopper (lift scan));
fun read stopper scan xs =
(case error (finite stopper (option scan)) xs of
(y as SOME _, []) => y
| _ => NONE);
fun drain get stopper scan ((state, xs), src) =
(scan (state, xs), src) handle MORE () =>
(case get src of
([], _) => (finite' stopper scan (state, xs), src)
| (xs', src') => drain get stopper scan ((state, xs @ xs'), src'));
(** datatype lexicon -- position tree **)
datatype lexicon = Lexicon of (bool * lexicon) Symtab.table;
val empty_lexicon = Lexicon Symtab.empty;
fun build_lexicon f : lexicon = f empty_lexicon;
fun is_empty_lexicon (Lexicon tab) = Symtab.is_empty tab;
fun is_literal _ [] = false
| is_literal (Lexicon tab) (c :: cs) =
(case Symtab.lookup tab c of
SOME (tip, lex) => tip andalso null cs orelse is_literal lex cs
| NONE => false);
(* scan longest match *)
fun literal lexicon = let fun finish (SOME (res, rest)) = (rev res, rest)
| finish NONE = raise FAIL NONE; fun scan _ res (Lexicon tab) [] = if Symtab.is_empty tab then finish res elseraise MORE ()
| scan path res (Lexicon tab) (c :: cs) =
(case Symtab.lookup tab (fst c) of
SOME (tip, lex) => letval path' = c :: path in scan path' (if tip then SOME (path', cs) else res) lex cs end
| NONE => finish res); in scan [] NONE lexicon end;
(* build lexicons *)
fun extend_lexicon chrs lexicon = let fun ext [] lex = lex
| ext (c :: cs) (Lexicon tab) =
(case Symtab.lookup tab c of
SOME (tip, lex) => Lexicon (Symtab.update (c, (tip orelse null cs, ext cs lex)) tab)
| NONE => Lexicon (Symtab.update (c, (null cs, ext cs empty_lexicon)) tab)); inif is_literal lexicon chrs then lexicon else ext chrs lexicon end;
fun make_lexicon chrss = fold extend_lexicon chrss empty_lexicon;
(* merge lexicons *)
fun dest path (Lexicon tab) = Symtab.fold (fn (d, (tip, lex)) => let val path' = d :: path; val content = dest path' lex; in append (if tip then rev path' :: content else content) end) tab [];
val dest_lexicon = sort_strings o map implode o dest [];
fun merge_lexicons (lex1, lex2) = if pointer_eq (lex1, lex2) then lex1 elseif is_empty_lexicon lex1 then lex2 else fold extend_lexicon (dest [] lex2) lex1;
end;
structure Basic_Scan: BASIC_SCAN = Scan; open Basic_Scan;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.