| author | blanchet | 
| Wed, 18 Sep 2013 20:43:55 +0200 | |
| changeset 53705 | f58e289eceba | 
| parent 53016 | fa9c38891cf2 | 
| child 54732 | b01bb3d09928 | 
| permissions | -rw-r--r-- | 
| 27763 | 1 | (* Title: Pure/General/symbol_pos.ML | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Symbols with explicit position information. | |
| 5 | *) | |
| 6 | ||
| 53016 
fa9c38891cf2
disable old identifier syntax by default, legacy_isub_isup := true may be used temporarily as fall-back;
 wenzelm parents: 
52920diff
changeset | 7 | val legacy_isub_isup = Unsynchronized.ref false; | 
| 
fa9c38891cf2
disable old identifier syntax by default, legacy_isub_isup := true may be used temporarily as fall-back;
 wenzelm parents: 
52920diff
changeset | 8 | |
| 36957 | 9 | signature SYMBOL_POS = | 
| 27763 | 10 | sig | 
| 11 | type T = Symbol.symbol * Position.T | |
| 12 | val symbol: T -> Symbol.symbol | |
| 13 | val $$$ : Symbol.symbol -> T list -> T list * T list | |
| 14 | val ~$$$ : Symbol.symbol -> T list -> T list * T list | |
| 27797 | 15 | val content: T list -> string | 
| 27763 | 16 | val is_eof: T -> bool | 
| 17 | val stopper: T Scan.stopper | |
| 43947 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43773diff
changeset | 18 | val !!! : Scan.message -> (T list -> 'a) -> T list -> 'a | 
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 19 |   val change_prompt: ('a -> 'b) -> 'a -> 'b
 | 
| 27778 
3ec7a4d9ef18
renamed SymbolPos.scan_position to SymbolPos.scan_pos;
 wenzelm parents: 
27763diff
changeset | 20 | val scan_pos: T list -> Position.T * T list | 
| 48764 | 21 | val scan_string_q: string -> T list -> (Position.T * (T list * Position.T)) * T list | 
| 22 | val scan_string_qq: string -> T list -> (Position.T * (T list * Position.T)) * T list | |
| 23 | val scan_string_bq: string -> T list -> (Position.T * (T list * Position.T)) * T list | |
| 48743 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 24 | val recover_string_q: T list -> T list * T list | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 25 | val recover_string_qq: T list -> T list * T list | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 26 | val recover_string_bq: T list -> T list * T list | 
| 43773 | 27 | val quote_string_q: string -> string | 
| 28 | val quote_string_qq: string -> string | |
| 29 | val quote_string_bq: string -> string | |
| 27763 | 30 | val scan_comment: (string -> (T list -> T list * T list) -> T list -> T list * T list) -> | 
| 31 | T list -> T list * T list | |
| 32 | val scan_comment_body: (string -> (T list -> T list * T list) -> T list -> T list * T list) -> | |
| 33 | T list -> T list * T list | |
| 48743 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 34 | val recover_comment: T list -> T list * T list | 
| 27763 | 35 | val source: Position.T -> (Symbol.symbol, 'a) Source.source -> | 
| 36 | (T, Position.T * (Symbol.symbol, 'a) Source.source) Source.source | |
| 27778 
3ec7a4d9ef18
renamed SymbolPos.scan_position to SymbolPos.scan_pos;
 wenzelm parents: 
27763diff
changeset | 37 | type text = string | 
| 27797 | 38 | val implode: T list -> text | 
| 39 | val range: T list -> Position.range | |
| 40 | val implode_range: Position.T -> Position.T -> T list -> text * Position.range | |
| 27778 
3ec7a4d9ef18
renamed SymbolPos.scan_position to SymbolPos.scan_pos;
 wenzelm parents: 
27763diff
changeset | 41 | val explode: text * Position.T -> T list | 
| 50239 | 42 | val scan_ident: T list -> T list * T list | 
| 43 | val is_identifier: string -> bool | |
| 27763 | 44 | end; | 
| 45 | ||
| 30573 | 46 | structure Symbol_Pos: SYMBOL_POS = | 
| 27763 | 47 | struct | 
| 48 | ||
| 49 | (* type T *) | |
| 50 | ||
| 51 | type T = Symbol.symbol * Position.T; | |
| 52 | ||
| 53 | fun symbol ((s, _): T) = s; | |
| 27852 | 54 | |
| 27797 | 55 | val content = implode o map symbol; | 
| 27763 | 56 | |
| 57 | ||
| 58 | (* stopper *) | |
| 59 | ||
| 60 | fun mk_eof pos = (Symbol.eof, pos); | |
| 61 | val eof = mk_eof Position.none; | |
| 62 | ||
| 63 | val is_eof = Symbol.is_eof o symbol; | |
| 64 | ||
| 65 | val stopper = | |
| 66 | Scan.stopper (fn [] => eof | inp => mk_eof (List.last inp |-> Position.advance)) is_eof; | |
| 67 | ||
| 68 | ||
| 69 | (* basic scanners *) | |
| 70 | ||
| 71 | fun !!! text scan = | |
| 72 | let | |
| 48911 
5debc3e4fa81
tuned messages: end-of-input rarely means physical end-of-file from the past;
 wenzelm parents: 
48770diff
changeset | 73 | fun get_pos [] = " (end-of-input)" | 
| 48992 | 74 | | get_pos ((_, pos) :: _) = Position.here pos; | 
| 27763 | 75 | |
| 43947 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43773diff
changeset | 76 | fun err (syms, msg) = fn () => | 
| 48770 | 77 | text () ^ get_pos syms ^ | 
| 50201 
c26369c9eda6
Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
 wenzelm parents: 
48992diff
changeset | 78 |       Markup.markup Markup.no_report (" at " ^ Symbol.beginning 10 (map symbol syms)) ^
 | 
| 43947 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43773diff
changeset | 79 | (case msg of NONE => "" | SOME m => "\n" ^ m ()); | 
| 27763 | 80 | in Scan.!! err scan end; | 
| 81 | ||
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 82 | fun change_prompt scan = Scan.prompt "# " scan; | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 83 | |
| 27763 | 84 | fun $$$ s = Scan.one (fn x => symbol x = s) >> single; | 
| 85 | fun ~$$$ s = Scan.one (fn x => symbol x <> s) >> single; | |
| 86 | ||
| 27778 
3ec7a4d9ef18
renamed SymbolPos.scan_position to SymbolPos.scan_pos;
 wenzelm parents: 
27763diff
changeset | 87 | val scan_pos = Scan.ahead (Scan.one (K true)) >> (fn (_, pos): T => pos); | 
| 27763 | 88 | |
| 89 | ||
| 43773 | 90 | (* scan string literals *) | 
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 91 | |
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 92 | local | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 93 | |
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 94 | val char_code = | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 95 | Scan.one (Symbol.is_ascii_digit o symbol) -- | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 96 | Scan.one (Symbol.is_ascii_digit o symbol) -- | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 97 | Scan.one (Symbol.is_ascii_digit o symbol) :|-- | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 98 | (fn (((a, pos), (b, _)), (c, _)) => | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 99 | let val (n, _) = Library.read_int [a, b, c] | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 100 | in if n <= 255 then Scan.succeed [(chr n, pos)] else Scan.fail end); | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 101 | |
| 48764 | 102 | fun scan_str q err_prefix = | 
| 103 | $$$ "\\" |-- !!! (fn () => err_prefix ^ "bad escape character in string") | |
| 104 | ($$$ q || $$$ "\\" || char_code) || | |
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 105 | Scan.one (fn (s, _) => s <> q andalso s <> "\\" andalso Symbol.is_regular s) >> single; | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 106 | |
| 48764 | 107 | fun scan_strs q err_prefix = | 
| 108 | (scan_pos --| $$$ q) -- !!! (fn () => err_prefix ^ "missing quote at end of string") | |
| 109 | (change_prompt ((Scan.repeat (scan_str q err_prefix) >> flat) -- ($$$ q |-- scan_pos))); | |
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 110 | |
| 48743 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 111 | fun recover_strs q = | 
| 48764 | 112 | $$$ q @@@ (Scan.repeat (Scan.permissive (scan_str q "")) >> flat); | 
| 48743 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 113 | |
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 114 | in | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 115 | |
| 42503 | 116 | val scan_string_q = scan_strs "'"; | 
| 117 | val scan_string_qq = scan_strs "\""; | |
| 118 | val scan_string_bq = scan_strs "`"; | |
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 119 | |
| 48743 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 120 | val recover_string_q = recover_strs "'"; | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 121 | val recover_string_qq = recover_strs "\""; | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 122 | val recover_string_bq = recover_strs "`"; | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 123 | |
| 30586 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 124 | end; | 
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 125 | |
| 
9674f64a0702
moved basic change_prompt, scan_string, scan_alt_string, scan_quoted to symbol_pos.ML;
 wenzelm parents: 
30573diff
changeset | 126 | |
| 43773 | 127 | (* quote string literals *) | 
| 128 | ||
| 129 | local | |
| 130 | ||
| 131 | fun char_code i = | |
| 132 | (if i < 10 then "00" else if i < 100 then "0" else "") ^ string_of_int i; | |
| 133 | ||
| 134 | fun quote_str q s = | |
| 135 | if Symbol.is_ascii_control s then "\\" ^ char_code (ord s) | |
| 136 | else if s = q orelse s = "\\" then "\\" ^ s | |
| 137 | else s; | |
| 138 | ||
| 139 | fun quote_string q = enclose q q o implode o map (quote_str q) o Symbol.explode; | |
| 140 | ||
| 141 | in | |
| 142 | ||
| 143 | val quote_string_q = quote_string "'"; | |
| 144 | val quote_string_qq = quote_string "\""; | |
| 145 | val quote_string_bq = quote_string "`"; | |
| 146 | ||
| 147 | end; | |
| 148 | ||
| 149 | ||
| 27763 | 150 | (* ML-style comments *) | 
| 151 | ||
| 152 | local | |
| 153 | ||
| 154 | val scan_cmt = | |
| 155 |   Scan.depend (fn (d: int) => $$$ "(" @@@ $$$ "*" >> pair (d + 1)) ||
 | |
| 156 | Scan.depend (fn 0 => Scan.fail | d => $$$ "*" @@@ $$$ ")" >> pair (d - 1)) || | |
| 157 | Scan.lift ($$$ "*" --| Scan.ahead (~$$$ ")")) || | |
| 158 | Scan.lift (Scan.one (fn (s, _) => s <> "*" andalso Symbol.is_regular s)) >> single; | |
| 159 | ||
| 48743 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 160 | val scan_cmts = Scan.pass 0 (Scan.repeat scan_cmt >> flat); | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 161 | |
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 162 | val scan_body = change_prompt scan_cmts; | 
| 27763 | 163 | |
| 164 | in | |
| 165 | ||
| 166 | fun scan_comment cut = | |
| 167 |   $$$ "(" @@@ $$$ "*" @@@ cut "missing end of comment" (scan_body @@@ $$$ "*" @@@ $$$ ")");
 | |
| 168 | ||
| 169 | fun scan_comment_body cut = | |
| 170 |   $$$ "(" |-- $$$ "*" |-- cut "missing end of comment" (scan_body --| $$$ "*" --| $$$ ")");
 | |
| 171 | ||
| 48743 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 172 | val recover_comment = | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 173 |   $$$ "(" @@@ $$$ "*" @@@ scan_cmts;
 | 
| 
a72f8ffecf31
refined recovery of scan errors: longest prefix of delimited token after failure, otherwise just one symbol;
 wenzelm parents: 
43947diff
changeset | 174 | |
| 27763 | 175 | end; | 
| 176 | ||
| 177 | ||
| 178 | (* source *) | |
| 179 | ||
| 180 | fun source pos = | |
| 181 | Source.source' pos Symbol.stopper (Scan.bulk (Scan.depend (fn pos => | |
| 182 | Scan.one Symbol.not_eof >> (fn s => (Position.advance s pos, (s, pos)))))) NONE; | |
| 183 | ||
| 184 | ||
| 185 | (* compact representation -- with Symbol.DEL padding *) | |
| 186 | ||
| 27778 
3ec7a4d9ef18
renamed SymbolPos.scan_position to SymbolPos.scan_pos;
 wenzelm parents: 
27763diff
changeset | 187 | type text = string; | 
| 
3ec7a4d9ef18
renamed SymbolPos.scan_position to SymbolPos.scan_pos;
 wenzelm parents: 
27763diff
changeset | 188 | |
| 27763 | 189 | fun pad [] = [] | 
| 190 | | pad [(s, _)] = [s] | |
| 32784 | 191 | | pad ((s1, pos1) :: (rest as (_, pos2) :: _)) = | 
| 27763 | 192 | let | 
| 193 | val end_pos1 = Position.advance s1 pos1; | |
| 27797 | 194 | val d = Int.max (0, Position.distance_of end_pos1 pos2); | 
| 27763 | 195 | in s1 :: replicate d Symbol.DEL @ pad rest end; | 
| 196 | ||
| 27797 | 197 | val implode = implode o pad; | 
| 27763 | 198 | |
| 27797 | 199 | fun range (syms as (_, pos) :: _) = | 
| 27763 | 200 | let val pos' = List.last syms |-> Position.advance | 
| 27797 | 201 | in Position.range pos pos' end | 
| 202 | | range [] = Position.no_range; | |
| 27763 | 203 | |
| 27797 | 204 | fun implode_range pos1 pos2 syms = | 
| 205 |   let val syms' = (("", pos1) :: syms @ [("", pos2)])
 | |
| 206 | in (implode syms', range syms') end; | |
| 27778 
3ec7a4d9ef18
renamed SymbolPos.scan_position to SymbolPos.scan_pos;
 wenzelm parents: 
27763diff
changeset | 207 | |
| 27763 | 208 | fun explode (str, pos) = | 
| 41416 | 209 | let | 
| 210 | val (res, _) = | |
| 211 | fold (fn s => fn (res, p) => ((s, p) :: res, Position.advance s p)) | |
| 212 | (Symbol.explode str) ([], Position.reset_range pos); | |
| 213 | in fold (fn (s, p) => if s = Symbol.DEL then I else cons (s, p)) res [] end; | |
| 27763 | 214 | |
| 50239 | 215 | |
| 216 | (* identifiers *) | |
| 217 | ||
| 50242 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 218 | local | 
| 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 219 | |
| 52616 
3ac2878764f9
more robust identifier syntax: sub/superscript counts as modifier of LETDIG part instead of LETTER, both isub/isup and sub/sup are allowed;
 wenzelm parents: 
50493diff
changeset | 220 | val letter = Scan.one (symbol #> Symbol.is_letter); | 
| 
3ac2878764f9
more robust identifier syntax: sub/superscript counts as modifier of LETDIG part instead of LETTER, both isub/isup and sub/sup are allowed;
 wenzelm parents: 
50493diff
changeset | 221 | val letdigs1 = Scan.many1 (symbol #> Symbol.is_letdig); | 
| 53016 
fa9c38891cf2
disable old identifier syntax by default, legacy_isub_isup := true may be used temporarily as fall-back;
 wenzelm parents: 
52920diff
changeset | 222 | |
| 
fa9c38891cf2
disable old identifier syntax by default, legacy_isub_isup := true may be used temporarily as fall-back;
 wenzelm parents: 
52920diff
changeset | 223 | val sub = | 
| 
fa9c38891cf2
disable old identifier syntax by default, legacy_isub_isup := true may be used temporarily as fall-back;
 wenzelm parents: 
52920diff
changeset | 224 | Scan.one (symbol #> (fn s => | 
| 
fa9c38891cf2
disable old identifier syntax by default, legacy_isub_isup := true may be used temporarily as fall-back;
 wenzelm parents: 
52920diff
changeset | 225 | if ! legacy_isub_isup then s = "\\<^sub>" orelse s = "\\<^isub>" orelse s = "\\<^isup>" | 
| 
fa9c38891cf2
disable old identifier syntax by default, legacy_isub_isup := true may be used temporarily as fall-back;
 wenzelm parents: 
52920diff
changeset | 226 | else s = "\\<^sub>")); | 
| 50242 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 227 | |
| 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 228 | in | 
| 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 229 | |
| 52920 
4539e4a06339
more strict identifier syntax: disallow superscripts, which tend to be used in notation such as \<^sup>\<omega>;
 wenzelm parents: 
52616diff
changeset | 230 | val scan_ident = letter ::: (Scan.repeat (letdigs1 || sub ::: letdigs1) >> flat); | 
| 50242 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 231 | |
| 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 232 | end; | 
| 
56b9c792a98b
support for sub-structured identifier syntax (inactive);
 wenzelm parents: 
50239diff
changeset | 233 | |
| 50239 | 234 | fun is_identifier s = | 
| 50295 
3d6a4135a54f
eliminated redundant is_ident -- more official is_identifier;
 wenzelm parents: 
50253diff
changeset | 235 | Symbol.is_ascii_identifier s orelse | 
| 
3d6a4135a54f
eliminated redundant is_ident -- more official is_identifier;
 wenzelm parents: 
50253diff
changeset | 236 | (case try (Scan.finite stopper scan_ident) (explode (s, Position.none)) of | 
| 
3d6a4135a54f
eliminated redundant is_ident -- more official is_identifier;
 wenzelm parents: 
50253diff
changeset | 237 | SOME (_, []) => true | 
| 
3d6a4135a54f
eliminated redundant is_ident -- more official is_identifier;
 wenzelm parents: 
50253diff
changeset | 238 | | _ => false); | 
| 50239 | 239 | |
| 27763 | 240 | end; | 
| 241 | ||
| 36957 | 242 | structure Basic_Symbol_Pos = (*not open by default*) | 
| 243 | struct | |
| 244 | val $$$ = Symbol_Pos.$$$; | |
| 245 | val ~$$$ = Symbol_Pos.~$$$; | |
| 246 | end; | |
| 27763 | 247 |