src/Pure/Syntax/scan.ML
changeset 4958 ad2acb8d2db4
parent 4953 78ff4a45a822
child 4968 c68a9c510c90
equal deleted inserted replaced
4957:30c49821e61f 4958:ad2acb8d2db4
    44   val force: ('a -> 'b) -> 'a -> 'b
    44   val force: ('a -> 'b) -> 'a -> 'b
    45   val prompt: string -> ('a -> 'b) -> 'a -> 'b
    45   val prompt: string -> ('a -> 'b) -> 'a -> 'b
    46   val finite': 'a * ('a -> bool) -> ('b * 'a list -> 'c * ('d * 'a list))
    46   val finite': 'a * ('a -> bool) -> ('b * 'a list -> 'c * ('d * 'a list))
    47     -> 'b * 'a list -> 'c * ('d * 'a list)
    47     -> 'b * 'a list -> 'c * ('d * 'a list)
    48   val finite: 'a * ('a -> bool) -> ('a list -> 'b * 'a list) -> 'a list -> 'b * 'a list
    48   val finite: 'a * ('a -> bool) -> ('a list -> 'b * 'a list) -> 'a list -> 'b * 'a list
       
    49   val catch: ('a -> 'b) -> 'a -> 'b
    49   val error: ('a -> 'b) -> 'a -> 'b
    50   val error: ('a -> 'b) -> 'a -> 'b
    50   val source': string -> (string -> 'a -> 'b list * 'a) ->
    51   val source': string -> (string -> 'a -> 'b list * 'a) -> ('b list * 'a -> 'c) ->
    51     ('b list * 'a -> 'c) -> 'b * ('b -> bool) -> ('d * 'b list -> 'e list * ('d * 'b list)) ->
    52     'b * ('b -> bool) -> ('d * 'b list -> 'e list * ('d * 'b list)) ->
    52       'd * 'a -> 'e list * ('d * 'c)
    53     ('d * 'b list -> 'f * ('d * 'b list)) option -> 'd * 'a -> 'e list * ('d * 'c)
    53   val source: string -> (string -> 'a -> 'b list * 'a) ->
    54   val source: string -> (string -> 'a -> 'b list * 'a) -> ('b list * 'a -> 'c) ->
    54     ('b list * 'a -> 'c) -> 'b * ('b -> bool) -> ('b list -> 'd list * 'b list) ->
    55     'b * ('b -> bool) -> ('b list -> 'd list * 'b list) ->
    55       'a -> 'd list * 'c
    56     ('b list -> 'e * 'b list) option -> 'a -> 'd list * 'c
    56   val single: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
    57   val single: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
    57   val bulk: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
    58   val bulk: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
    58   type lexicon
    59   type lexicon
    59   val dest_lexicon: lexicon -> string list list
    60   val dest_lexicon: lexicon -> string list list
    60   val make_lexicon: string list list -> lexicon
    61   val make_lexicon: string list list -> lexicon
    68 struct
    69 struct
    69 
    70 
    70 
    71 
    71 (** scanners **)
    72 (** scanners **)
    72 
    73 
    73 exception MORE of string option;	(*need more input (use prompt)*)
    74 exception MORE of string option;	(*need more input (prompt)*)
    74 exception FAIL of string option;	(*try alternatives (reason of failure)*)
    75 exception FAIL of string option;	(*try alternatives (reason of failure)*)
    75 exception ABORT of string;		(*dead end*)
    76 exception ABORT of string;		(*dead end*)
    76 
    77 
    77 
    78 
    78 (* scanner combinators *)
    79 (* scanner combinators *)
   151 
   152 
   152 fun !! err scan xs = scan xs handle FAIL msg => raise ABORT (err (xs, msg));
   153 fun !! err scan xs = scan xs handle FAIL msg => raise ABORT (err (xs, msg));
   153 fun try scan xs = scan xs handle MORE _ => raise FAIL None | ABORT _ => raise FAIL None;
   154 fun try scan xs = scan xs handle MORE _ => raise FAIL None | ABORT _ => raise FAIL None;
   154 fun force scan xs = scan xs handle MORE _ => raise FAIL None;
   155 fun force scan xs = scan xs handle MORE _ => raise FAIL None;
   155 fun prompt str scan xs = scan xs handle MORE None => raise MORE (Some str);
   156 fun prompt str scan xs = scan xs handle MORE None => raise MORE (Some str);
       
   157 fun catch scan xs = scan xs handle ABORT msg => raise FAIL (Some msg);
   156 fun error scan xs = scan xs handle ABORT msg => Library.error msg;
   158 fun error scan xs = scan xs handle ABORT msg => Library.error msg;
   157 
   159 
   158 
   160 
   159 (* finite scans *)
   161 (* finite scans *)
   160 
   162 
   177   in (y, xs') end;
   179   in (y, xs') end;
   178 
   180 
   179 
   181 
   180 (* infinite scans -- draining state-based source *)
   182 (* infinite scans -- draining state-based source *)
   181 
   183 
   182 fun source' def_prmpt get unget stopper scan (state, src) =
   184 fun drain def_prmpt get stopper scan ((state, xs), src) =
   183   let
   185   (scan (state, xs), src) handle MORE prmpt =>
   184     fun drain (xs, s) =
   186     (case get (if_none prmpt def_prmpt) src of
   185       (scan (state, xs), s) handle MORE prmpt =>
   187       ([], _) => (finite' stopper scan (state, xs), src)
   186         (case get (if_none prmpt def_prmpt) s of
   188     | (xs', src') => drain def_prmpt get stopper scan ((state, xs @ xs'), src'));
   187           ([], _) => (finite' stopper scan (state, xs), s)
   189 
   188         | (xs', s') => drain (xs @ xs', s'));
   190 fun source' def_prmpt get unget stopper scanner opt_recover (state, src) =
   189 
   191   let
   190     val ((ys, (state', rest)), src') =
   192     val drain_with = drain def_prmpt get stopper;
   191       (case get def_prmpt src of
   193 
   192         ([], s) => (([], (state, [])), s)
   194     fun drain_loop recover inp =
   193       | xs_s => drain xs_s);
   195       drain_with (catch scanner) inp handle FAIL msg =>
   194   in
   196         (warning (if_none msg "Syntax error."); warning "Trying to recover ...";
   195     (ys, (state', unget (rest, src')))
   197           drain_loop recover (apfst snd (drain_with recover inp)));
   196   end;
   198 
   197 
   199     val ((ys, (state', xs')), src') =
   198 fun source def_prmpt get unget stopper scan src =
   200       (case (get def_prmpt src, opt_recover) of
   199   let val (ys, ((), src')) = source' def_prmpt get unget stopper (lift scan) ((), src)
   201         (([], s), _) => (([], (state, [])), s)
       
   202       | ((xs, s), None) => drain_with (error scanner) ((state, xs), s)
       
   203       | ((xs, s), Some scan) => drain_loop scan ((state, xs), s));
       
   204   in
       
   205     (ys, (state', unget (xs', src')))
       
   206   end;
       
   207 
       
   208 fun source def_prmpt get unget stopper scan opt_recover src =
       
   209   let val (ys, ((), src')) =
       
   210     source' def_prmpt get unget stopper (lift scan) (apsome lift opt_recover) ((), src)
   200   in (ys, src') end;
   211   in (ys, src') end;
   201 
   212 
   202 fun single scan = scan >> (fn x => [x]);
   213 fun single scan = scan >> (fn x => [x]);
   203 fun bulk scan = scan -- repeat (try scan) >> (op ::);
   214 fun bulk scan = scan -- repeat (try scan) >> (op ::);
   204 
   215