| author | wenzelm | 
| Sun, 02 Oct 2016 14:07:43 +0200 | |
| changeset 63992 | 3aa9837d05c7 | 
| parent 62491 | 7187cb7a77c5 | 
| child 78817 | 30bcf149054d | 
| permissions | -rw-r--r-- | 
| 11523 | 1  | 
(* Title: Pure/General/scan.ML  | 
2  | 
Author: Markus Wenzel and Tobias Nipkow, TU Muenchen  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
3  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
4  | 
Generic scanners (for potentially infinite input).  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
5  | 
*)  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
6  | 
|
| 24025 | 7  | 
infix 5 -- :-- :|-- |-- --| ^^;  | 
| 25999 | 8  | 
infixr 5 ::: @@@;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
9  | 
infix 3 >>;  | 
| 23699 | 10  | 
infixr 0 ||;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
11  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
12  | 
signature BASIC_SCAN =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
13  | 
sig  | 
| 
43947
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
14  | 
type message = unit -> string  | 
| 14677 | 15  | 
(*error msg handler*)  | 
| 
43947
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
16  | 
  val !! : ('a * message option -> message) -> ('a -> 'b) -> 'a -> 'b
 | 
| 14677 | 17  | 
(*apply function*)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
18  | 
  val >> : ('a -> 'b * 'c) * ('b -> 'd) -> 'a -> 'd * 'c
 | 
| 14677 | 19  | 
(*alternative*)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
20  | 
  val || : ('a -> 'b) * ('a -> 'b) -> 'a -> 'b
 | 
| 14677 | 21  | 
(*sequential pairing*)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
22  | 
  val -- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e
 | 
| 14677 | 23  | 
(*dependent pairing*)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
24  | 
  val :-- : ('a -> 'b * 'c) * ('b -> 'c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e
 | 
| 24025 | 25  | 
(*projections*)  | 
26  | 
  val :|-- : ('a -> 'b * 'c) * ('b -> 'c -> 'd * 'e) -> 'a -> 'd * 'e
 | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
27  | 
  val |-- : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'd * 'e
 | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
28  | 
  val --| : ('a -> 'b * 'c) * ('c -> 'd * 'e) -> 'a -> 'b * 'e
 | 
| 14677 | 29  | 
(*concatenation*)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
30  | 
  val ^^ : ('a -> string * 'b) * ('b -> string * 'c) -> 'a -> string * 'c
 | 
| 25999 | 31  | 
  val ::: : ('a -> 'b * 'c) * ('c -> 'b list * 'd) -> 'a -> 'b list * 'd
 | 
32  | 
  val @@@ : ('a -> 'b list * 'c) * ('c -> 'b list * 'd) -> 'a -> 'b list * 'd
 | 
|
| 14677 | 33  | 
(*one element literal*)  | 
| 19291 | 34  | 
val $$ : string -> string list -> string * string list  | 
| 19306 | 35  | 
val ~$$ : string -> string list -> string * string list  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
36  | 
end;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
37  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
38  | 
signature SCAN =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
39  | 
sig  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
40  | 
include BASIC_SCAN  | 
| 
48743
 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 
wenzelm 
parents: 
43947 
diff
changeset
 | 
41  | 
  val permissive: ('a -> 'b) -> 'a -> 'b
 | 
| 23699 | 42  | 
  val error: ('a -> 'b) -> 'a -> 'b
 | 
43  | 
  val catch: ('a -> 'b) -> 'a -> 'b    (*exception Fail*)
 | 
|
| 58864 | 44  | 
  val recover: ('a -> 'b) -> (string -> 'a -> 'b) -> 'a -> 'b
 | 
| 61466 | 45  | 
  val triple1: ('a * 'b) * 'c -> 'a * 'b * 'c
 | 
46  | 
  val triple2: 'a * ('b * 'c) -> 'a * 'b * 'c
 | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
47  | 
val fail: 'a -> 'b  | 
| 
43947
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
48  | 
  val fail_with: ('a -> message) -> 'a -> 'b
 | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
49  | 
val succeed: 'a -> 'b -> 'a * 'b  | 
| 15664 | 50  | 
  val some: ('a -> 'b option) -> 'a list -> 'b * 'a list
 | 
51  | 
  val one: ('a -> bool) -> 'a list -> 'a * 'a list
 | 
|
| 19291 | 52  | 
val this: string list -> string list -> string list * string list  | 
| 14927 | 53  | 
val this_string: string -> string list -> string * string list  | 
| 
21858
 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 
wenzelm 
parents: 
19473 
diff
changeset
 | 
54  | 
  val many: ('a -> bool) -> 'a list -> 'a list * 'a list
 | 
| 
 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 
wenzelm 
parents: 
19473 
diff
changeset
 | 
55  | 
  val many1: ('a -> bool) -> 'a list -> 'a list * 'a list
 | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
56  | 
  val optional: ('a -> 'b * 'a) -> 'b -> 'a -> 'b * 'a
 | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
57  | 
  val option: ('a -> 'b * 'a) -> 'a -> 'b option * 'a
 | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
58  | 
  val repeat: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
 | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
59  | 
  val repeat1: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
 | 
| 61476 | 60  | 
  val repeats: ('a -> 'b list * 'a) -> 'a -> 'b list * 'a
 | 
61  | 
  val repeats1: ('a -> 'b list * 'a) -> 'a -> 'b list * 'a
 | 
|
| 23699 | 62  | 
  val single: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
 | 
63  | 
  val bulk: ('a -> 'b * 'a) -> 'a -> 'b list * 'a
 | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
64  | 
  val max: ('a * 'a -> bool) -> ('b -> 'a * 'b) -> ('b -> 'a * 'b) -> 'b -> 'a * 'b
 | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
65  | 
  val ahead: ('a -> 'b * 'c) -> 'a -> 'b * 'a
 | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
66  | 
  val unless: ('a -> 'b * 'a) -> ('a -> 'c * 'd) -> 'a -> 'c * 'd
 | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
67  | 
  val first: ('a -> 'b) list -> 'a -> 'b
 | 
| 14677 | 68  | 
  val state: 'a * 'b -> 'a * ('a * 'b)
 | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
69  | 
  val depend: ('a -> 'b -> ('c * 'd) * 'e) -> 'a * 'b -> 'd * ('c * 'e)
 | 
| 15664 | 70  | 
  val peek: ('a -> 'b -> 'c * 'd) -> 'a * 'b -> 'c * ('a * 'd)
 | 
| 
55104
 
8284c0d5bf52
clarified scan_cartouche_depth, according to Scala version;
 
wenzelm 
parents: 
48743 
diff
changeset
 | 
71  | 
  val provide: ('a -> bool) -> 'b -> ('b * 'c -> 'd * ('a * 'e)) -> 'c -> 'd * 'e
 | 
| 15664 | 72  | 
  val pass: 'a -> ('a * 'b -> 'c * ('d * 'e)) -> 'b -> 'c * 'e
 | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
73  | 
  val lift: ('a -> 'b * 'c) -> 'd * 'a -> 'b * ('d * 'c)
 | 
| 23699 | 74  | 
  val unlift: (unit * 'a -> 'b * ('c * 'd)) -> 'a -> 'b * 'd
 | 
| 15664 | 75  | 
  val trace: ('a list -> 'b * 'c list) -> 'a list -> ('b * 'a list) * 'c list
 | 
| 
27731
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
76  | 
type 'a stopper  | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
77  | 
  val stopper: ('a list -> 'a) -> ('a -> bool) -> 'a stopper
 | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
78  | 
val is_stopper: 'a stopper -> 'a -> bool  | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
79  | 
  val finite': 'a stopper -> ('b * 'a list -> 'c * ('d * 'a list))
 | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
80  | 
    -> 'b * 'a list -> 'c * ('d * 'a list)
 | 
| 
27731
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
81  | 
  val finite: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b * 'a list
 | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
82  | 
  val read: 'a stopper -> ('a list -> 'b * 'a list) -> 'a list -> 'b option
 | 
| 58850 | 83  | 
  val drain: ('a -> 'b list * 'a) -> 'b stopper -> ('c * 'b list -> 'd * ('e * 'b list)) ->
 | 
84  | 
    ('c * 'b list) * 'a -> ('d * ('e * 'b list)) * 'a
 | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
85  | 
type lexicon  | 
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
86  | 
val is_literal: lexicon -> string list -> bool  | 
| 
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
87  | 
val literal: lexicon -> (string * 'a) list -> (string * 'a) list * (string * 'a) list  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
88  | 
val empty_lexicon: lexicon  | 
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
89  | 
val extend_lexicon: string list -> lexicon -> lexicon  | 
| 
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
90  | 
val make_lexicon: string list list -> lexicon  | 
| 
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
91  | 
val dest_lexicon: lexicon -> string list  | 
| 
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
92  | 
val merge_lexicons: lexicon * lexicon -> lexicon  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
93  | 
end;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
94  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
95  | 
structure Scan: SCAN =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
96  | 
struct  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
97  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
98  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
99  | 
(** scanners **)  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
100  | 
|
| 23699 | 101  | 
(* exceptions *)  | 
102  | 
||
| 
43947
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
103  | 
type message = unit -> string;  | 
| 
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
104  | 
|
| 58850 | 105  | 
exception MORE of unit; (*need more input*)  | 
106  | 
exception FAIL of message option; (*try alternatives (reason of failure)*)  | 
|
107  | 
exception ABORT of message; (*dead end*)  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
108  | 
|
| 23699 | 109  | 
fun !! err scan xs = scan xs handle FAIL msg => raise ABORT (err (xs, msg));  | 
| 58850 | 110  | 
fun permissive scan xs = scan xs handle MORE () => raise FAIL NONE | ABORT _ => raise FAIL NONE;  | 
111  | 
fun strict scan xs = scan xs handle MORE () => raise FAIL NONE;  | 
|
| 62491 | 112  | 
fun error scan xs = scan xs handle ABORT msg => Exn.error (msg ());  | 
| 23699 | 113  | 
|
114  | 
fun catch scan xs = scan xs  | 
|
| 
43947
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
115  | 
handle ABORT msg => raise Fail (msg ())  | 
| 
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
116  | 
| FAIL msg => raise Fail (case msg of NONE => "Syntax error" | SOME m => m ());  | 
| 23699 | 117  | 
|
| 58864 | 118  | 
fun recover scan1 scan2 xs =  | 
119  | 
catch scan1 xs handle Fail msg => scan2 msg xs;  | 
|
120  | 
||
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
121  | 
|
| 61466 | 122  | 
(* utils *)  | 
123  | 
||
124  | 
fun triple1 ((x, y), z) = (x, y, z);  | 
|
125  | 
fun triple2 (x, (y, z)) = (x, y, z);  | 
|
126  | 
||
127  | 
||
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
128  | 
(* scanner combinators *)  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
129  | 
|
| 19306 | 130  | 
fun (scan >> f) xs = scan xs |>> f;  | 
| 14078 | 131  | 
|
| 19306 | 132  | 
fun (scan1 || scan2) xs = scan1 xs handle FAIL _ => scan2 xs;  | 
| 14078 | 133  | 
|
| 19306 | 134  | 
fun (scan1 :-- scan2) xs =  | 
| 
14108
 
eaf3c75f2c8e
Restored old (tail recursive!) version of repeat.
 
berghofe 
parents: 
14078 
diff
changeset
 | 
135  | 
let  | 
| 19306 | 136  | 
val (x, ys) = scan1 xs;  | 
137  | 
val (y, zs) = scan2 x ys;  | 
|
138  | 
in ((x, y), zs) end;  | 
|
| 14078 | 139  | 
|
| 19306 | 140  | 
fun (scan1 -- scan2) = scan1 :-- (fn _ => scan2);  | 
| 24025 | 141  | 
fun (scan1 :|-- scan2) = scan1 :-- scan2 >> #2;  | 
| 19306 | 142  | 
fun (scan1 |-- scan2) = scan1 -- scan2 >> #2;  | 
143  | 
fun (scan1 --| scan2) = scan1 -- scan2 >> #1;  | 
|
144  | 
fun (scan1 ^^ scan2) = scan1 -- scan2 >> op ^;  | 
|
| 25999 | 145  | 
fun (scan1 ::: scan2) = scan1 -- scan2 >> op ::;  | 
146  | 
fun (scan1 @@@ scan2) = scan1 -- scan2 >> op @;  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
147  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
148  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
149  | 
(* generic scanners *)  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
150  | 
|
| 15531 | 151  | 
fun fail _ = raise FAIL NONE;  | 
152  | 
fun fail_with msg_of xs = raise FAIL (SOME (msg_of xs));  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
153  | 
fun succeed y xs = (y, xs);  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
154  | 
|
| 58850 | 155  | 
fun some _ [] = raise MORE ()  | 
| 15664 | 156  | 
| some f (x :: xs) =  | 
157  | 
(case f x of SOME y => (y, xs) | _ => raise FAIL NONE);  | 
|
158  | 
||
| 58850 | 159  | 
fun one _ [] = raise MORE ()  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
160  | 
| one pred (x :: xs) =  | 
| 15531 | 161  | 
if pred x then (x, xs) else raise FAIL NONE;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
162  | 
|
| 19306 | 163  | 
fun $$ a = one (fn s: string => s = a);  | 
164  | 
fun ~$$ a = one (fn s: string => s <> a);  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
165  | 
|
| 14833 | 166  | 
fun this ys xs =  | 
| 14726 | 167  | 
let  | 
168  | 
fun drop_prefix [] xs = xs  | 
|
| 58850 | 169  | 
| drop_prefix (_ :: _) [] = raise MORE ()  | 
| 14726 | 170  | 
| drop_prefix (y :: ys) (x :: xs) =  | 
| 19291 | 171  | 
if (y: string) = x then drop_prefix ys xs else raise FAIL NONE;  | 
| 14726 | 172  | 
in (ys, drop_prefix ys xs) end;  | 
173  | 
||
| 
40627
 
becf5d5187cc
renamed raw "explode" function to "raw_explode" to emphasize its meaning;
 
wenzelm 
parents: 
38875 
diff
changeset
 | 
174  | 
fun this_string s = this (raw_explode s) >> K s; (*primitive string -- no symbols here!*)  | 
| 14907 | 175  | 
|
| 58850 | 176  | 
fun many _ [] = raise MORE ()  | 
| 
21858
 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 
wenzelm 
parents: 
19473 
diff
changeset
 | 
177  | 
| many pred (lst as x :: xs) =  | 
| 
 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 
wenzelm 
parents: 
19473 
diff
changeset
 | 
178  | 
if pred x then apfst (cons x) (many pred xs)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
179  | 
else ([], lst);  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
180  | 
|
| 25999 | 181  | 
fun many1 pred = one pred ::: many pred;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
182  | 
|
| 15664 | 183  | 
fun optional scan def = scan || succeed def;  | 
184  | 
fun option scan = (scan >> SOME) || succeed NONE;  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
185  | 
|
| 13795 | 186  | 
fun repeat scan =  | 
| 15664 | 187  | 
let  | 
188  | 
fun rep ys xs =  | 
|
189  | 
(case (SOME (scan xs) handle FAIL _ => NONE) of  | 
|
190  | 
NONE => (rev ys, xs)  | 
|
191  | 
| SOME (y, xs') => rep (y :: ys) xs');  | 
|
| 
14108
 
eaf3c75f2c8e
Restored old (tail recursive!) version of repeat.
 
berghofe 
parents: 
14078 
diff
changeset
 | 
192  | 
in rep [] end;  | 
| 13795 | 193  | 
|
| 25999 | 194  | 
fun repeat1 scan = scan ::: repeat scan;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
195  | 
|
| 61476 | 196  | 
fun repeats scan = repeat scan >> flat;  | 
197  | 
fun repeats1 scan = repeat1 scan >> flat;  | 
|
198  | 
||
| 23699 | 199  | 
fun single scan = scan >> (fn x => [x]);  | 
200  | 
fun bulk scan = scan -- repeat (permissive scan) >> (op ::);  | 
|
201  | 
||
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
202  | 
fun max leq scan1 scan2 xs =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
203  | 
(case (option scan1 xs, option scan2 xs) of  | 
| 15531 | 204  | 
((NONE, _), (NONE, _)) => raise FAIL NONE (*looses FAIL msg!*)  | 
205  | 
| ((SOME tok1, xs'), (NONE, _)) => (tok1, xs')  | 
|
206  | 
| ((NONE, _), (SOME tok2, xs')) => (tok2, xs')  | 
|
207  | 
| ((SOME tok1, xs1'), (SOME tok2, xs2')) =>  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
208  | 
if leq (tok2, tok1) then (tok1, xs1') else (tok2, xs2'));  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
209  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
210  | 
fun ahead scan xs = (fst (scan xs), xs);  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
211  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
212  | 
fun unless test scan =  | 
| 15531 | 213  | 
ahead (option test) :-- (fn NONE => scan | _ => fail) >> #2;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
214  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
215  | 
fun first [] = fail  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
216  | 
| first (scan :: scans) = scan || first scans;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
217  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
218  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
219  | 
(* state based scanners *)  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
220  | 
|
| 9122 | 221  | 
fun state (st, xs) = (st, (st, xs));  | 
222  | 
||
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
223  | 
fun depend scan (st, xs) =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
224  | 
let val ((st', y), xs') = scan st xs  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
225  | 
in (y, (st', xs')) end;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
226  | 
|
| 15664 | 227  | 
fun peek scan = depend (fn st => scan st >> pair st);  | 
228  | 
||
| 
55104
 
8284c0d5bf52
clarified scan_cartouche_depth, according to Scala version;
 
wenzelm 
parents: 
48743 
diff
changeset
 | 
229  | 
fun provide pred st scan xs =  | 
| 
 
8284c0d5bf52
clarified scan_cartouche_depth, according to Scala version;
 
wenzelm 
parents: 
48743 
diff
changeset
 | 
230  | 
let val (y, (st', xs')) = scan (st, xs)  | 
| 
 
8284c0d5bf52
clarified scan_cartouche_depth, according to Scala version;
 
wenzelm 
parents: 
48743 
diff
changeset
 | 
231  | 
in if pred st' then (y, xs') else fail () end;  | 
| 
 
8284c0d5bf52
clarified scan_cartouche_depth, according to Scala version;
 
wenzelm 
parents: 
48743 
diff
changeset
 | 
232  | 
|
| 
 
8284c0d5bf52
clarified scan_cartouche_depth, according to Scala version;
 
wenzelm 
parents: 
48743 
diff
changeset
 | 
233  | 
fun pass st = provide (K true) st;  | 
| 15664 | 234  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
235  | 
fun lift scan (st, xs) =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
236  | 
let val (y, xs') = scan xs  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
237  | 
in (y, (st, xs')) end;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
238  | 
|
| 15664 | 239  | 
fun unlift scan = pass () scan;  | 
240  | 
||
241  | 
||
242  | 
(* trace input *)  | 
|
243  | 
||
| 23699 | 244  | 
fun trace scan xs =  | 
245  | 
let val (y, xs') = scan xs  | 
|
| 33957 | 246  | 
in ((y, take (length xs - length xs') xs), xs') end;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
247  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
248  | 
|
| 
27731
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
249  | 
(* stopper *)  | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
250  | 
|
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
251  | 
datatype 'a stopper = Stopper of ('a list -> 'a) * ('a -> bool);
 | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
252  | 
|
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
253  | 
fun stopper mk_stopper is_stopper = Stopper (mk_stopper, is_stopper);  | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
254  | 
fun is_stopper (Stopper (_, is_stopper)) = is_stopper;  | 
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
255  | 
|
| 
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
256  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
257  | 
(* finite scans *)  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
258  | 
|
| 
27731
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
259  | 
fun finite' (Stopper (mk_stopper, is_stopper)) scan (state, input) =  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
260  | 
let  | 
| 
43947
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
261  | 
fun lost () = raise ABORT (fn () => "Bad scanner: lost stopper of finite scan!");  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
262  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
263  | 
fun stop [] = lost ()  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
264  | 
| stop lst =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
265  | 
let val (xs, x) = split_last lst  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
266  | 
in if is_stopper x then ((), xs) else lost () end;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
267  | 
in  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
268  | 
if exists is_stopper input then  | 
| 
43947
 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 
wenzelm 
parents: 
40627 
diff
changeset
 | 
269  | 
raise ABORT (fn () => "Stopper may not occur in input of finite scan!")  | 
| 
27731
 
a7444ded92cf
abstract type stopper, may depend on final input;
 
wenzelm 
parents: 
25999 
diff
changeset
 | 
270  | 
else (strict scan --| lift stop) (state, input @ [mk_stopper input])  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
271  | 
end;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
272  | 
|
| 15664 | 273  | 
fun finite stopper scan = unlift (finite' stopper (lift scan));  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
274  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
275  | 
fun read stopper scan xs =  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
276  | 
(case error (finite stopper (option scan)) xs of  | 
| 15531 | 277  | 
(y as SOME _, []) => y  | 
278  | 
| _ => NONE);  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
279  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
280  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
281  | 
(* infinite scans -- draining state-based source *)  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
282  | 
|
| 58850 | 283  | 
fun drain get stopper scan ((state, xs), src) =  | 
284  | 
(scan (state, xs), src) handle MORE () =>  | 
|
285  | 
(case get src of  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
286  | 
([], _) => (finite' stopper scan (state, xs), src)  | 
| 58850 | 287  | 
| (xs', src') => drain get stopper scan ((state, xs @ xs'), src'));  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
288  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
289  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
290  | 
|
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
291  | 
(** datatype lexicon -- position tree **)  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
292  | 
|
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
293  | 
datatype lexicon = Lexicon of (bool * lexicon) Symtab.table;  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
294  | 
|
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
295  | 
val empty_lexicon = Lexicon Symtab.empty;  | 
| 59071 | 296  | 
fun is_empty_lexicon (Lexicon tab) = Symtab.is_empty tab;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
297  | 
|
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
298  | 
fun is_literal _ [] = false  | 
| 32784 | 299  | 
| is_literal (Lexicon tab) (c :: cs) =  | 
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
300  | 
(case Symtab.lookup tab c of  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
301  | 
SOME (tip, lex) => tip andalso null cs orelse is_literal lex cs  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
302  | 
| NONE => false);  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
303  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
304  | 
|
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
305  | 
(* scan longest match *)  | 
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
306  | 
|
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
307  | 
fun literal lexicon =  | 
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
308  | 
let  | 
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
309  | 
fun finish (SOME (res, rest)) = (rev res, rest)  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
310  | 
| finish NONE = raise FAIL NONE;  | 
| 58850 | 311  | 
fun scan _ res (Lexicon tab) [] =  | 
312  | 
if Symtab.is_empty tab then finish res else raise MORE ()  | 
|
| 32784 | 313  | 
| scan path res (Lexicon tab) (c :: cs) =  | 
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
314  | 
(case Symtab.lookup tab (fst c) of  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
315  | 
SOME (tip, lex) =>  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
316  | 
let val path' = c :: path  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
317  | 
in scan path' (if tip then SOME (path', cs) else res) lex cs end  | 
| 27784 | 318  | 
| NONE => finish res);  | 
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
319  | 
in scan [] NONE lexicon end;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
320  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
321  | 
|
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
322  | 
(* build lexicons *)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
323  | 
|
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
324  | 
fun extend_lexicon chrs lexicon =  | 
| 
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
325  | 
let  | 
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
326  | 
fun ext [] lex = lex  | 
| 32784 | 327  | 
| ext (c :: cs) (Lexicon tab) =  | 
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
328  | 
(case Symtab.lookup tab c of  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
329  | 
SOME (tip, lex) => Lexicon (Symtab.update (c, (tip orelse null cs, ext cs lex)) tab)  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
330  | 
| NONE => Lexicon (Symtab.update (c, (null cs, ext cs empty_lexicon)) tab));  | 
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
331  | 
in if is_literal lexicon chrs then lexicon else ext chrs lexicon end;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
332  | 
|
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
333  | 
fun make_lexicon chrss = fold extend_lexicon chrss empty_lexicon;  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
334  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
335  | 
|
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
336  | 
(* merge lexicons *)  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
337  | 
|
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
338  | 
fun dest path (Lexicon tab) = Symtab.fold (fn (d, (tip, lex)) =>  | 
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
339  | 
let  | 
| 
27782
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
340  | 
val path' = d :: path;  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
341  | 
val content = dest path' lex;  | 
| 
 
377810fd718e
datatype lexicon: alternative representation using nested Symtab.table;
 
wenzelm 
parents: 
27765 
diff
changeset
 | 
342  | 
in append (if tip then rev path' :: content else content) end) tab [];  | 
| 
27765
 
5df443dd9deb
reorganized lexicon: allow scanning of annotated symbols, tuned representation and interfaces;
 
wenzelm 
parents: 
27731 
diff
changeset
 | 
343  | 
|
| 59196 | 344  | 
val dest_lexicon = sort_strings o map implode o dest [];  | 
| 59071 | 345  | 
|
346  | 
fun merge_lexicons (lex1, lex2) =  | 
|
347  | 
if pointer_eq (lex1, lex2) then lex1  | 
|
348  | 
else if is_empty_lexicon lex1 then lex2  | 
|
349  | 
else fold extend_lexicon (dest [] lex2) lex1;  | 
|
| 
6116
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
350  | 
|
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
351  | 
end;  | 
| 
 
8ba2f25610f7
files scan.ML, source.ML, symbol.ML, pretty.ML moved to Pure/General;
 
wenzelm 
parents:  
diff
changeset
 | 
352  | 
|
| 
37216
 
3165bc303f66
modernized some structure names, keeping a few legacy aliases;
 
wenzelm 
parents: 
33957 
diff
changeset
 | 
353  | 
structure Basic_Scan: BASIC_SCAN = Scan;  | 
| 
 
3165bc303f66
modernized some structure names, keeping a few legacy aliases;
 
wenzelm 
parents: 
33957 
diff
changeset
 | 
354  | 
open Basic_Scan;  |