36 end; |
36 end; |
37 |
37 |
38 signature SCAN = |
38 signature SCAN = |
39 sig |
39 sig |
40 include BASIC_SCAN |
40 include BASIC_SCAN |
41 val prompt: string -> ('a -> 'b) -> 'a -> 'b |
|
42 val permissive: ('a -> 'b) -> 'a -> 'b |
41 val permissive: ('a -> 'b) -> 'a -> 'b |
43 val error: ('a -> 'b) -> 'a -> 'b |
42 val error: ('a -> 'b) -> 'a -> 'b |
44 val catch: ('a -> 'b) -> 'a -> 'b (*exception Fail*) |
43 val catch: ('a -> 'b) -> 'a -> 'b (*exception Fail*) |
45 val fail: 'a -> 'b |
44 val fail: 'a -> 'b |
46 val fail_with: ('a -> message) -> 'a -> 'b |
45 val fail_with: ('a -> message) -> 'a -> 'b |
74 val is_stopper: 'a stopper -> 'a -> bool |
73 val is_stopper: 'a stopper -> 'a -> bool |
75 val finite': 'a stopper -> ('b * 'a list -> 'c * ('d * 'a list)) |
74 val finite': 'a stopper -> ('b * 'a list -> 'c * ('d * 'a list)) |
76 -> 'b * 'a list -> 'c * ('d * 'a list) |
75 -> 'b * 'a list -> 'c * ('d * 'a list) |
77 val finite: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b * 'a list |
76 val finite: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b * 'a list |
78 val read: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b option |
77 val read: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b option |
79 val drain: string -> (string -> 'a -> 'b list * 'a) -> 'b stopper -> |
78 val drain: ('a -> 'b list * 'a) -> 'b stopper -> ('c * 'b list -> 'd * ('e * 'b list)) -> |
80 ('c * 'b list -> 'd * ('e * 'b list)) -> ('c * 'b list) * 'a -> ('d * ('e * 'b list)) * 'a |
79 ('c * 'b list) * 'a -> ('d * ('e * 'b list)) * 'a |
81 type lexicon |
80 type lexicon |
82 val is_literal: lexicon -> string list -> bool |
81 val is_literal: lexicon -> string list -> bool |
83 val literal: lexicon -> (string * 'a) list -> (string * 'a) list * (string * 'a) list |
82 val literal: lexicon -> (string * 'a) list -> (string * 'a) list * (string * 'a) list |
84 val empty_lexicon: lexicon |
83 val empty_lexicon: lexicon |
85 val extend_lexicon: string list -> lexicon -> lexicon |
84 val extend_lexicon: string list -> lexicon -> lexicon |
96 |
95 |
97 (* exceptions *) |
96 (* exceptions *) |
98 |
97 |
99 type message = unit -> string; |
98 type message = unit -> string; |
100 |
99 |
101 exception MORE of string option; (*need more input (prompt)*) |
100 exception MORE of unit; (*need more input*) |
102 exception FAIL of message option; (*try alternatives (reason of failure)*) |
101 exception FAIL of message option; (*try alternatives (reason of failure)*) |
103 exception ABORT of message; (*dead end*) |
102 exception ABORT of message; (*dead end*) |
104 |
103 |
105 fun !! err scan xs = scan xs handle FAIL msg => raise ABORT (err (xs, msg)); |
104 fun !! err scan xs = scan xs handle FAIL msg => raise ABORT (err (xs, msg)); |
106 fun permissive scan xs = scan xs handle MORE _ => raise FAIL NONE | ABORT _ => raise FAIL NONE; |
105 fun permissive scan xs = scan xs handle MORE () => raise FAIL NONE | ABORT _ => raise FAIL NONE; |
107 fun strict scan xs = scan xs handle MORE _ => raise FAIL NONE; |
106 fun strict scan xs = scan xs handle MORE () => raise FAIL NONE; |
108 fun prompt str scan xs = scan xs handle MORE NONE => raise MORE (SOME str); |
|
109 fun error scan xs = scan xs handle ABORT msg => Library.error (msg ()); |
107 fun error scan xs = scan xs handle ABORT msg => Library.error (msg ()); |
110 |
108 |
111 fun catch scan xs = scan xs |
109 fun catch scan xs = scan xs |
112 handle ABORT msg => raise Fail (msg ()) |
110 handle ABORT msg => raise Fail (msg ()) |
113 | FAIL msg => raise Fail (case msg of NONE => "Syntax error" | SOME m => m ()); |
111 | FAIL msg => raise Fail (case msg of NONE => "Syntax error" | SOME m => m ()); |
138 |
136 |
139 fun fail _ = raise FAIL NONE; |
137 fun fail _ = raise FAIL NONE; |
140 fun fail_with msg_of xs = raise FAIL (SOME (msg_of xs)); |
138 fun fail_with msg_of xs = raise FAIL (SOME (msg_of xs)); |
141 fun succeed y xs = (y, xs); |
139 fun succeed y xs = (y, xs); |
142 |
140 |
143 fun some _ [] = raise MORE NONE |
141 fun some _ [] = raise MORE () |
144 | some f (x :: xs) = |
142 | some f (x :: xs) = |
145 (case f x of SOME y => (y, xs) | _ => raise FAIL NONE); |
143 (case f x of SOME y => (y, xs) | _ => raise FAIL NONE); |
146 |
144 |
147 fun one _ [] = raise MORE NONE |
145 fun one _ [] = raise MORE () |
148 | one pred (x :: xs) = |
146 | one pred (x :: xs) = |
149 if pred x then (x, xs) else raise FAIL NONE; |
147 if pred x then (x, xs) else raise FAIL NONE; |
150 |
148 |
151 fun $$ a = one (fn s: string => s = a); |
149 fun $$ a = one (fn s: string => s = a); |
152 fun ~$$ a = one (fn s: string => s <> a); |
150 fun ~$$ a = one (fn s: string => s <> a); |
153 |
151 |
154 fun this ys xs = |
152 fun this ys xs = |
155 let |
153 let |
156 fun drop_prefix [] xs = xs |
154 fun drop_prefix [] xs = xs |
157 | drop_prefix (_ :: _) [] = raise MORE NONE |
155 | drop_prefix (_ :: _) [] = raise MORE () |
158 | drop_prefix (y :: ys) (x :: xs) = |
156 | drop_prefix (y :: ys) (x :: xs) = |
159 if (y: string) = x then drop_prefix ys xs else raise FAIL NONE; |
157 if (y: string) = x then drop_prefix ys xs else raise FAIL NONE; |
160 in (ys, drop_prefix ys xs) end; |
158 in (ys, drop_prefix ys xs) end; |
161 |
159 |
162 fun this_string s = this (raw_explode s) >> K s; (*primitive string -- no symbols here!*) |
160 fun this_string s = this (raw_explode s) >> K s; (*primitive string -- no symbols here!*) |
163 |
161 |
164 fun many _ [] = raise MORE NONE |
162 fun many _ [] = raise MORE () |
165 | many pred (lst as x :: xs) = |
163 | many pred (lst as x :: xs) = |
166 if pred x then apfst (cons x) (many pred xs) |
164 if pred x then apfst (cons x) (many pred xs) |
167 else ([], lst); |
165 else ([], lst); |
168 |
166 |
169 fun many1 pred = one pred ::: many pred; |
167 fun many1 pred = one pred ::: many pred; |
263 | _ => NONE); |
261 | _ => NONE); |
264 |
262 |
265 |
263 |
266 (* infinite scans -- draining state-based source *) |
264 (* infinite scans -- draining state-based source *) |
267 |
265 |
268 fun drain def_prompt get stopper scan ((state, xs), src) = |
266 fun drain get stopper scan ((state, xs), src) = |
269 (scan (state, xs), src) handle MORE prompt => |
267 (scan (state, xs), src) handle MORE () => |
270 (case get (the_default def_prompt prompt) src of |
268 (case get src of |
271 ([], _) => (finite' stopper scan (state, xs), src) |
269 ([], _) => (finite' stopper scan (state, xs), src) |
272 | (xs', src') => drain def_prompt get stopper scan ((state, xs @ xs'), src')); |
270 | (xs', src') => drain get stopper scan ((state, xs @ xs'), src')); |
273 |
271 |
274 |
272 |
275 |
273 |
276 (** datatype lexicon -- position tree **) |
274 (** datatype lexicon -- position tree **) |
277 |
275 |
290 |
288 |
291 fun literal lexicon = |
289 fun literal lexicon = |
292 let |
290 let |
293 fun finish (SOME (res, rest)) = (rev res, rest) |
291 fun finish (SOME (res, rest)) = (rev res, rest) |
294 | finish NONE = raise FAIL NONE; |
292 | finish NONE = raise FAIL NONE; |
295 fun scan _ res (Lexicon tab) [] = if Symtab.is_empty tab then finish res else raise MORE NONE |
293 fun scan _ res (Lexicon tab) [] = |
|
294 if Symtab.is_empty tab then finish res else raise MORE () |
296 | scan path res (Lexicon tab) (c :: cs) = |
295 | scan path res (Lexicon tab) (c :: cs) = |
297 (case Symtab.lookup tab (fst c) of |
296 (case Symtab.lookup tab (fst c) of |
298 SOME (tip, lex) => |
297 SOME (tip, lex) => |
299 let val path' = c :: path |
298 let val path' = c :: path |
300 in scan path' (if tip then SOME (path', cs) else res) lex cs end |
299 in scan path' (if tip then SOME (path', cs) else res) lex cs end |