src/HOL/Import/scan.ML
author chaieb
Sun, 08 Jul 2007 19:01:32 +0200
changeset 23650 0a6a719d24d5
parent 19093 6d584f9d2021
child 32960 69916a850301
permissions -rw-r--r--
Show the use of reflection attribute; fixed comments about the order of absorbing equations : f (C x) = x ; now automaically tried as last;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
19093
6d584f9d2021 use monomorphic sequences / scanners
obua
parents: 19089
diff changeset
     1
(*  Title:      HOL/Import/scan.ML
19089
2e487fe9593a improved scanning
obua
parents:
diff changeset
     2
    ID:         $Id$
2e487fe9593a improved scanning
obua
parents:
diff changeset
     3
    Author:     Sebastian Skalberg, TU Muenchen / Steven Obua, TU Muenchen
2e487fe9593a improved scanning
obua
parents:
diff changeset
     4
2e487fe9593a improved scanning
obua
parents:
diff changeset
     5
Scanner combinators for sequences.
2e487fe9593a improved scanning
obua
parents:
diff changeset
     6
*)
2e487fe9593a improved scanning
obua
parents:
diff changeset
     7
2e487fe9593a improved scanning
obua
parents:
diff changeset
     8
signature SCANNER =
2e487fe9593a improved scanning
obua
parents:
diff changeset
     9
sig
2e487fe9593a improved scanning
obua
parents:
diff changeset
    10
2e487fe9593a improved scanning
obua
parents:
diff changeset
    11
    include SCANNER_SEQ
2e487fe9593a improved scanning
obua
parents:
diff changeset
    12
2e487fe9593a improved scanning
obua
parents:
diff changeset
    13
    exception SyntaxError
2e487fe9593a improved scanning
obua
parents:
diff changeset
    14
2e487fe9593a improved scanning
obua
parents:
diff changeset
    15
    type ('a,'b) scanner = 'a seq -> 'b * 'a seq
2e487fe9593a improved scanning
obua
parents:
diff changeset
    16
2e487fe9593a improved scanning
obua
parents:
diff changeset
    17
    val :--      : ('a,'b) scanner * ('b -> ('a,'c) scanner)
2e487fe9593a improved scanning
obua
parents:
diff changeset
    18
		   -> ('a,'b*'c) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    19
    val --       : ('a,'b) scanner * ('a,'c) scanner -> ('a,'b*'c) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    20
    val >>       : ('a,'b) scanner * ('b -> 'c) -> ('a,'c) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    21
    val --|      : ('a,'b) scanner * ('a,'c) scanner -> ('a,'b) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    22
    val |--      : ('a,'b) scanner * ('a,'c) scanner -> ('a,'c) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    23
    val ^^       : ('a,string) scanner * ('a,string) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    24
		   -> ('a,string) scanner 
2e487fe9593a improved scanning
obua
parents:
diff changeset
    25
    val ||       : ('a,'b) scanner * ('a,'b) scanner -> ('a,'b) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    26
    val one      : ('a -> bool) -> ('a,'a) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    27
    val anyone   : ('a,'a) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    28
    val succeed  : 'b -> ('a,'b) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    29
    val any      : ('a -> bool) -> ('a,'a list) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    30
    val any1     : ('a -> bool) -> ('a,'a list) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    31
    val optional : ('a,'b) scanner -> 'b -> ('a,'b) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    32
    val option   : ('a,'b) scanner -> ('a,'b option) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    33
    val repeat   : ('a,'b) scanner -> ('a,'b list) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    34
    val repeat1  : ('a,'b) scanner -> ('a,'b list) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    35
    val repeat_fixed : int -> ('a, 'b) scanner -> ('a, 'b list) scanner  
2e487fe9593a improved scanning
obua
parents:
diff changeset
    36
    val ahead    : ('a,'b) scanner -> ('a,'b) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    37
    val unless   : ('a, 'b) scanner -> ('a,'c) scanner -> ('a,'c) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    38
    val $$       : ''a -> (''a,''a) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    39
    val !!       : ('a seq -> string) -> ('a,'b) scanner -> ('a,'b) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    40
    
2e487fe9593a improved scanning
obua
parents:
diff changeset
    41
    val scan_id : (string, string) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    42
    val scan_nat : (string, int) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    43
2e487fe9593a improved scanning
obua
parents:
diff changeset
    44
    val this : ''a list -> (''a, ''a list) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    45
    val this_string : string -> (string, string) scanner
2e487fe9593a improved scanning
obua
parents:
diff changeset
    46
end
2e487fe9593a improved scanning
obua
parents:
diff changeset
    47
2e487fe9593a improved scanning
obua
parents:
diff changeset
    48
functor Scanner (structure Seq : SCANNER_SEQ) : SCANNER =
2e487fe9593a improved scanning
obua
parents:
diff changeset
    49
struct
2e487fe9593a improved scanning
obua
parents:
diff changeset
    50
2e487fe9593a improved scanning
obua
parents:
diff changeset
    51
infix 7 |-- --|
2e487fe9593a improved scanning
obua
parents:
diff changeset
    52
infix 5 :-- -- ^^
2e487fe9593a improved scanning
obua
parents:
diff changeset
    53
infix 3 >>
2e487fe9593a improved scanning
obua
parents:
diff changeset
    54
infix 0 ||
2e487fe9593a improved scanning
obua
parents:
diff changeset
    55
2e487fe9593a improved scanning
obua
parents:
diff changeset
    56
exception SyntaxError
2e487fe9593a improved scanning
obua
parents:
diff changeset
    57
exception Fail of string
2e487fe9593a improved scanning
obua
parents:
diff changeset
    58
2e487fe9593a improved scanning
obua
parents:
diff changeset
    59
type 'a seq = 'a Seq.seq
2e487fe9593a improved scanning
obua
parents:
diff changeset
    60
type ('a,'b) scanner = 'a seq -> 'b * 'a seq
2e487fe9593a improved scanning
obua
parents:
diff changeset
    61
2e487fe9593a improved scanning
obua
parents:
diff changeset
    62
val pull = Seq.pull
2e487fe9593a improved scanning
obua
parents:
diff changeset
    63
2e487fe9593a improved scanning
obua
parents:
diff changeset
    64
fun (sc1 :-- sc2) toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
    65
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
    66
	val (x,toks2) = sc1 toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
    67
	val (y,toks3) = sc2 x toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
    68
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
    69
	((x,y),toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
    70
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
    71
2e487fe9593a improved scanning
obua
parents:
diff changeset
    72
fun (sc1 -- sc2) toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
    73
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
    74
	val (x,toks2) = sc1 toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
    75
	val (y,toks3) = sc2 toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
    76
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
    77
	((x,y),toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
    78
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
    79
2e487fe9593a improved scanning
obua
parents:
diff changeset
    80
fun (sc >> f) toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
    81
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
    82
	val (x,toks2) = sc toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
    83
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
    84
	(f x,toks2)
2e487fe9593a improved scanning
obua
parents:
diff changeset
    85
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
    86
2e487fe9593a improved scanning
obua
parents:
diff changeset
    87
fun (sc1 --| sc2) toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
    88
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
    89
	val (x,toks2) = sc1 toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
    90
	val (_,toks3) = sc2 toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
    91
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
    92
	(x,toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
    93
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
    94
2e487fe9593a improved scanning
obua
parents:
diff changeset
    95
fun (sc1 |-- sc2) toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
    96
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
    97
	val (_,toks2) = sc1 toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
    98
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
    99
	sc2 toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   100
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   101
2e487fe9593a improved scanning
obua
parents:
diff changeset
   102
fun (sc1 ^^ sc2) toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   103
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   104
	val (x,toks2) = sc1 toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
   105
	val (y,toks3) = sc2 toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   106
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   107
	(x^y,toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   108
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   109
2e487fe9593a improved scanning
obua
parents:
diff changeset
   110
fun (sc1 || sc2) toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   111
    (sc1 toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   112
    handle SyntaxError => sc2 toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
   113
2e487fe9593a improved scanning
obua
parents:
diff changeset
   114
fun anyone toks = case pull toks of NONE => raise SyntaxError | SOME x => x
2e487fe9593a improved scanning
obua
parents:
diff changeset
   115
2e487fe9593a improved scanning
obua
parents:
diff changeset
   116
fun one p toks = case anyone toks of x as (t, toks) => if p t then x else raise SyntaxError
2e487fe9593a improved scanning
obua
parents:
diff changeset
   117
2e487fe9593a improved scanning
obua
parents:
diff changeset
   118
fun succeed e toks = (e,toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   119
2e487fe9593a improved scanning
obua
parents:
diff changeset
   120
fun any p toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   121
    case pull toks of
2e487fe9593a improved scanning
obua
parents:
diff changeset
   122
	NONE =>  ([],toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   123
      | SOME(x,toks2) => if p x
2e487fe9593a improved scanning
obua
parents:
diff changeset
   124
			 then
2e487fe9593a improved scanning
obua
parents:
diff changeset
   125
			     let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   126
				 val (xs,toks3) = any p toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   127
			     in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   128
				 (x::xs,toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   129
			     end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   130
			 else ([],toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   131
2e487fe9593a improved scanning
obua
parents:
diff changeset
   132
fun any1 p toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   133
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   134
	val (x,toks2) = one p toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
   135
	val (xs,toks3) = any p toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   136
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   137
	(x::xs,toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   138
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   139
2e487fe9593a improved scanning
obua
parents:
diff changeset
   140
fun optional sc def =  sc || succeed def
2e487fe9593a improved scanning
obua
parents:
diff changeset
   141
fun option sc = (sc >> SOME) || succeed NONE
2e487fe9593a improved scanning
obua
parents:
diff changeset
   142
2e487fe9593a improved scanning
obua
parents:
diff changeset
   143
(*
2e487fe9593a improved scanning
obua
parents:
diff changeset
   144
fun repeat sc =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   145
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   146
	fun R toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   147
	    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   148
		val (x,toks2) = sc toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
   149
		val (xs,toks3) = R toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   150
	    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   151
		(x::xs,toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   152
	    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   153
	    handle SyntaxError => ([],toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   154
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   155
	R
2e487fe9593a improved scanning
obua
parents:
diff changeset
   156
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   157
*)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   158
2e487fe9593a improved scanning
obua
parents:
diff changeset
   159
(* A tail-recursive version of repeat.  It is (ever so) slightly slower
2e487fe9593a improved scanning
obua
parents:
diff changeset
   160
 * than the above, non-tail-recursive version (due to the garbage generation
2e487fe9593a improved scanning
obua
parents:
diff changeset
   161
 * associated with the reversal of the list).  However,  this version will be
2e487fe9593a improved scanning
obua
parents:
diff changeset
   162
 * able to process input where the former version must give up (due to stack
2e487fe9593a improved scanning
obua
parents:
diff changeset
   163
 * overflow).  The slowdown seems to be around the one percent mark.
2e487fe9593a improved scanning
obua
parents:
diff changeset
   164
 *)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   165
fun repeat sc =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   166
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   167
	fun R xs toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   168
	    case SOME (sc toks) handle SyntaxError => NONE of
2e487fe9593a improved scanning
obua
parents:
diff changeset
   169
		SOME (x,toks2) => R (x::xs) toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   170
	      | NONE => (List.rev xs,toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   171
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   172
	R []
2e487fe9593a improved scanning
obua
parents:
diff changeset
   173
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   174
2e487fe9593a improved scanning
obua
parents:
diff changeset
   175
fun repeat1 sc toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   176
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   177
	val (x,toks2) = sc toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
   178
	val (xs,toks3) = repeat sc toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   179
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   180
	(x::xs,toks3)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   181
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   182
2e487fe9593a improved scanning
obua
parents:
diff changeset
   183
fun repeat_fixed n sc =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   184
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   185
	fun R n xs toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   186
	    if (n <= 0) then (List.rev xs, toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   187
	    else case (sc toks) of (x, toks2) => R (n-1) (x::xs) toks2
2e487fe9593a improved scanning
obua
parents:
diff changeset
   188
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   189
	R n []
2e487fe9593a improved scanning
obua
parents:
diff changeset
   190
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   191
2e487fe9593a improved scanning
obua
parents:
diff changeset
   192
fun ahead (sc:'a->'b*'a) toks = (#1 (sc toks),toks)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   193
2e487fe9593a improved scanning
obua
parents:
diff changeset
   194
fun unless test sc toks =
2e487fe9593a improved scanning
obua
parents:
diff changeset
   195
    let
2e487fe9593a improved scanning
obua
parents:
diff changeset
   196
	val test_failed = (test toks;false) handle SyntaxError => true
2e487fe9593a improved scanning
obua
parents:
diff changeset
   197
    in
2e487fe9593a improved scanning
obua
parents:
diff changeset
   198
	if test_failed
2e487fe9593a improved scanning
obua
parents:
diff changeset
   199
	then sc toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
   200
	else raise SyntaxError
2e487fe9593a improved scanning
obua
parents:
diff changeset
   201
    end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   202
2e487fe9593a improved scanning
obua
parents:
diff changeset
   203
fun $$ arg = one (fn x => x = arg)
2e487fe9593a improved scanning
obua
parents:
diff changeset
   204
2e487fe9593a improved scanning
obua
parents:
diff changeset
   205
fun !! f sc toks = (sc toks
2e487fe9593a improved scanning
obua
parents:
diff changeset
   206
		    handle SyntaxError => raise Fail (f toks))
2e487fe9593a improved scanning
obua
parents:
diff changeset
   207
2e487fe9593a improved scanning
obua
parents:
diff changeset
   208
val scan_id = one Symbol.is_letter ^^ (any Symbol.is_letdig >> implode);
2e487fe9593a improved scanning
obua
parents:
diff changeset
   209
2e487fe9593a improved scanning
obua
parents:
diff changeset
   210
val nat_of_list = the o Int.fromString o implode 
2e487fe9593a improved scanning
obua
parents:
diff changeset
   211
2e487fe9593a improved scanning
obua
parents:
diff changeset
   212
val scan_nat = repeat1 (one Symbol.is_digit) >> nat_of_list 
2e487fe9593a improved scanning
obua
parents:
diff changeset
   213
2e487fe9593a improved scanning
obua
parents:
diff changeset
   214
fun this [] = (fn toks => ([], toks))
2e487fe9593a improved scanning
obua
parents:
diff changeset
   215
  | this (xs' as (x::xs)) = one (fn y => x=y) -- this xs >> K xs'
2e487fe9593a improved scanning
obua
parents:
diff changeset
   216
2e487fe9593a improved scanning
obua
parents:
diff changeset
   217
fun this_string s = this (explode s) >> K s
2e487fe9593a improved scanning
obua
parents:
diff changeset
   218
2e487fe9593a improved scanning
obua
parents:
diff changeset
   219
end
2e487fe9593a improved scanning
obua
parents:
diff changeset
   220