src/Pure/Syntax/scan.ML
changeset 4919 9397b1446cdb
parent 4903 0f56199a8d97
child 4924 cf6bb75968c4
equal deleted inserted replaced
4918:f66f67577cf3 4919:9397b1446cdb
     9 infix 3 >>;
     9 infix 3 >>;
    10 infix 0 ||;
    10 infix 0 ||;
    11 
    11 
    12 signature BASIC_SCAN =
    12 signature BASIC_SCAN =
    13 sig
    13 sig
    14   val !! : ('a -> string) -> ('a -> 'b) -> 'a -> 'b
    14   val !! : ('a * string option -> string) -> ('a -> 'b) -> 'a -> 'b
    15   val >> : ('a -> 'b * 'c) * ('b -> 'd) -> 'a -> 'd * 'c
    15   val >> : ('a -> 'b * 'c) * ('b -> 'd) -> 'a -> 'd * 'c
    16   val || : ('a -> 'b) * ('a -> 'b) -> 'a -> 'b
    16   val || : ('a -> 'b) * ('a -> 'b) -> 'a -> 'b
    17   val -- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e
    17   val -- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e
    18   val |-- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'd * 'e
    18   val |-- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'd * 'e
    19   val --| : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'b * 'e
    19   val --| : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'b * 'e
    23 
    23 
    24 signature SCAN =
    24 signature SCAN =
    25 sig
    25 sig
    26   include BASIC_SCAN
    26   include BASIC_SCAN
    27   val fail: 'a -> 'b
    27   val fail: 'a -> 'b
       
    28   val fail_with: ('a -> string) -> 'a -> 'b
    28   val succeed: 'a -> 'b -> 'a * 'b
    29   val succeed: 'a -> 'b -> 'a * 'b
    29   val one: ('a -> bool) -> 'a list -> 'a * 'a list
    30   val one: ('a -> bool) -> 'a list -> 'a * 'a list
    30   val any: ('a -> bool) -> 'a list -> 'a list * 'a list
    31   val any: ('a -> bool) -> 'a list -> 'a list * 'a list
    31   val any1: ('a -> bool) -> 'a list -> 'a list * 'a list
    32   val any1: ('a -> bool) -> 'a list -> 'a list * 'a list
    32   val optional: ('a -> 'b * 'a) -> 'b -> 'a -> 'b * 'a
    33   val optional: ('a -> 'b * 'a) -> 'b -> 'a -> 'b * 'a
    62 
    63 
    63 
    64 
    64 (** scanners **)
    65 (** scanners **)
    65 
    66 
    66 exception MORE of string option;	(*need more input (use prompt)*)
    67 exception MORE of string option;	(*need more input (use prompt)*)
    67 exception FAIL;				(*try alternatives*)
    68 exception FAIL of string option;	(*try alternatives (reason of failure)*)
    68 exception ABORT of string;		(*dead end*)
    69 exception ABORT of string;		(*dead end*)
    69 
    70 
    70 
    71 
    71 (* scanner combinators *)
    72 (* scanner combinators *)
    72 
    73 
    73 fun (scan >> f) xs = apfst f (scan xs);
    74 fun (scan >> f) xs = apfst f (scan xs);
    74 
    75 
    75 fun (scan1 || scan2) xs = scan1 xs handle FAIL => scan2 xs;
    76 fun (scan1 || scan2) xs = scan1 xs handle FAIL _ => scan2 xs;
    76 
    77 
    77 fun (scan1 -- scan2) xs =
    78 fun (scan1 -- scan2) xs =
    78   let
    79   let
    79     val (x, ys) = scan1 xs;
    80     val (x, ys) = scan1 xs;
    80     val (y, zs) = scan2 ys;
    81     val (y, zs) = scan2 ys;
    86 fun (scan1 ^^ scan2) = scan1 -- scan2 >> op ^;
    87 fun (scan1 ^^ scan2) = scan1 -- scan2 >> op ^;
    87 
    88 
    88 
    89 
    89 (* generic scanners *)
    90 (* generic scanners *)
    90 
    91 
    91 fun fail _ = raise FAIL;
    92 fun fail _ = raise FAIL None;
       
    93 fun fail_with msg_of xs = raise FAIL (Some (msg_of xs));
    92 fun succeed y xs = (y, xs);
    94 fun succeed y xs = (y, xs);
    93 
    95 
    94 fun one _ [] = raise MORE None
    96 fun one _ [] = raise MORE None
    95   | one pred (x :: xs) =
    97   | one pred (x :: xs) =
    96       if pred x then (x, xs) else raise FAIL;
    98       if pred x then (x, xs) else raise FAIL None;
    97 
    99 
    98 fun $$ _ [] = raise MORE None
   100 fun $$ _ [] = raise MORE None
    99   | $$ a (x :: xs) =
   101   | $$ a (x :: xs) =
   100       if a = x then (x, xs) else raise FAIL;
   102       if a = x then (x, xs) else raise FAIL None;
   101 
   103 
   102 fun any _ [] = raise MORE None
   104 fun any _ [] = raise MORE None
   103   | any pred (lst as x :: xs) =
   105   | any pred (lst as x :: xs) =
   104       if pred x then apfst (cons x) (any pred xs)
   106       if pred x then apfst (cons x) (any pred xs)
   105       else ([], lst);
   107       else ([], lst);
   112 fun repeat scan xs = (scan -- repeat scan >> op :: || succeed []) xs;
   114 fun repeat scan xs = (scan -- repeat scan >> op :: || succeed []) xs;
   113 fun repeat1 scan = scan -- repeat scan >> op ::;
   115 fun repeat1 scan = scan -- repeat scan >> op ::;
   114 
   116 
   115 fun max leq scan1 scan2 xs =
   117 fun max leq scan1 scan2 xs =
   116   (case (option scan1 xs, option scan2 xs) of
   118   (case (option scan1 xs, option scan2 xs) of
   117     ((None, _), (None, _)) => raise FAIL
   119     ((None, _), (None, _)) => raise FAIL None		(*looses FAIL msg!*)
   118   | ((Some tok1, xs'), (None, _)) => (tok1, xs')
   120   | ((Some tok1, xs'), (None, _)) => (tok1, xs')
   119   | ((None, _), (Some tok2, xs')) => (tok2, xs')
   121   | ((None, _), (Some tok2, xs')) => (tok2, xs')
   120   | ((Some tok1, xs1'), (Some tok2, xs2')) =>
   122   | ((Some tok1, xs1'), (Some tok2, xs2')) =>
   121       if leq (tok2, tok1) then (tok1, xs1') else (tok2, xs2'));
   123       if leq (tok2, tok1) then (tok1, xs1') else (tok2, xs2'));
   122 
   124 
   138   in (y, xs') end;
   140   in (y, xs') end;
   139 
   141 
   140 
   142 
   141 (* exception handling *)
   143 (* exception handling *)
   142 
   144 
   143 fun !! err scan xs = scan xs handle FAIL => raise ABORT (err xs);
   145 fun !! err scan xs = scan xs handle FAIL msg => raise ABORT (err (xs, msg));
   144 fun try scan xs = scan xs handle MORE _ => raise FAIL | ABORT _ => raise FAIL;
   146 fun try scan xs = scan xs handle MORE _ => raise FAIL None | ABORT _ => raise FAIL None;
   145 fun force scan xs = scan xs handle MORE _ => raise FAIL;
   147 fun force scan xs = scan xs handle MORE _ => raise FAIL None;
   146 fun prompt str scan xs = scan xs handle MORE None => raise MORE (Some str);
   148 fun prompt str scan xs = scan xs handle MORE None => raise MORE (Some str);
   147 fun error scan xs = scan xs handle ABORT msg => Library.error msg;
   149 fun error scan xs = scan xs handle ABORT msg => Library.error msg;
   148 
   150 
   149 
   151 
   150 (* finite scans *)
   152 (* finite scans *)
   249 	  if c < d then lit lt res chs
   251 	  if c < d then lit lt res chs
   250 	  else if c > d then lit gt res chs
   252 	  else if c > d then lit gt res chs
   251 	  else lit eq (if a = no_literal then res else Some (a, cs)) cs;
   253 	  else lit eq (if a = no_literal then res else Some (a, cs)) cs;
   252   in
   254   in
   253     (case lit lex None chrs of
   255     (case lit lex None chrs of
   254       None => raise FAIL
   256       None => raise FAIL None
   255     | Some res => res)
   257     | Some res => res)
   256   end;
   258   end;
   257 
   259 
   258 
   260 
   259 end;
   261 end;