| author | wenzelm | 
| Sun, 18 Jan 2015 22:20:48 +0100 | |
| changeset 59400 | d833cba5cce5 | 
| parent 59081 | 2ceb05ee0331 | 
| child 59693 | d96cb03caf9e | 
| permissions | -rw-r--r-- | 
| 36949 
080e85d46108
renamed structure OuterKeyword to Keyword and OuterParse to Parse, keeping the old names as legacy aliases for some time;
 wenzelm parents: 
35838diff
changeset | 1 | (* Title: Pure/Isar/parse.ML | 
| 5826 | 2 | Author: Markus Wenzel, TU Muenchen | 
| 3 | ||
| 4 | Generic parsers for Isabelle/Isar outer syntax. | |
| 5 | *) | |
| 6 | ||
| 36949 
080e85d46108
renamed structure OuterKeyword to Keyword and OuterParse to Parse, keeping the old names as legacy aliases for some time;
 wenzelm parents: 
35838diff
changeset | 7 | signature PARSE = | 
| 5826 | 8 | sig | 
| 44357 | 9 | val group: (unit -> string) -> (Token.T list -> 'a) -> Token.T list -> 'a | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 10 | val !!! : (Token.T list -> 'a) -> Token.T list -> 'a | 
| 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 11 | val !!!! : (Token.T list -> 'a) -> Token.T list -> 'a | 
| 12047 | 12 |   val triple1: ('a * 'b) * 'c -> 'a * 'b * 'c
 | 
| 13 |   val triple2: 'a * ('b * 'c) -> 'a * 'b * 'c
 | |
| 14 |   val triple_swap: ('a * 'b) * 'c -> ('a * 'c) * 'b
 | |
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 15 | val not_eof: Token.T parser | 
| 56201 | 16 | val token: 'a parser -> Token.T parser | 
| 59029 
c907cbe36713
more careful ML source positions, for improved PIDE markup;
 wenzelm parents: 
58908diff
changeset | 17 |   val range: 'a parser -> ('a * Position.range) parser
 | 
| 42326 | 18 |   val position: 'a parser -> ('a * Position.T) parser
 | 
| 59064 | 19 | val source_position: 'a parser -> Input.source parser | 
| 42326 | 20 | val inner_syntax: 'a parser -> string parser | 
| 58908 | 21 | val command_: string parser | 
| 29310 | 22 | val keyword: string parser | 
| 23 | val short_ident: string parser | |
| 24 | val long_ident: string parser | |
| 25 | val sym_ident: string parser | |
| 26 | val minus: string parser | |
| 27 | val term_var: string parser | |
| 28 | val type_ident: string parser | |
| 29 | val type_var: string parser | |
| 30 | val number: string parser | |
| 40290 
47f572aff50a
support for floating-point tokens in outer syntax (coinciding with inner syntax version);
 wenzelm parents: 
36959diff
changeset | 31 | val float_number: string parser | 
| 29310 | 32 | val string: string parser | 
| 33 | val alt_string: string parser | |
| 34 | val verbatim: string parser | |
| 55033 | 35 | val cartouche: string parser | 
| 29310 | 36 | val eof: string parser | 
| 58908 | 37 | val command: string -> string parser | 
| 29310 | 38 | val keyword_with: (string -> bool) -> string parser | 
| 56202 | 39 | val keyword_markup: bool * Markup.T -> string -> string parser | 
| 40 | val keyword_improper: string -> string parser | |
| 29310 | 41 | val $$$ : string -> string parser | 
| 42 | val reserved: string -> string parser | |
| 43 | val underscore: string parser | |
| 44 | val maybe: 'a parser -> 'a option parser | |
| 45 | val tag_name: string parser | |
| 46 | val tags: string list parser | |
| 47 | val opt_unit: unit parser | |
| 48 | val opt_keyword: string -> bool parser | |
| 49 | val begin: string parser | |
| 50 | val opt_begin: bool parser | |
| 51 | val nat: int parser | |
| 52 | val int: int parser | |
| 40290 
47f572aff50a
support for floating-point tokens in outer syntax (coinciding with inner syntax version);
 wenzelm parents: 
36959diff
changeset | 53 | val real: real parser | 
| 55764 | 54 |   val enum_positions: string -> 'a parser -> ('a list * Position.T list) parser
 | 
| 55 |   val enum1_positions: string -> 'a parser -> ('a list * Position.T list) parser
 | |
| 29310 | 56 | val enum: string -> 'a parser -> 'a list parser | 
| 57 | val enum1: string -> 'a parser -> 'a list parser | |
| 58 | val and_list: 'a parser -> 'a list parser | |
| 59 | val and_list1: 'a parser -> 'a list parser | |
| 30511 | 60 | val enum': string -> 'a context_parser -> 'a list context_parser | 
| 61 | val enum1': string -> 'a context_parser -> 'a list context_parser | |
| 62 | val and_list': 'a context_parser -> 'a list context_parser | |
| 63 | val and_list1': 'a context_parser -> 'a list context_parser | |
| 29310 | 64 | val list: 'a parser -> 'a list parser | 
| 65 | val list1: 'a parser -> 'a list parser | |
| 43775 
b361c7d184e7
added Parse.properties (again) -- allow empty list like Parse_Value.properties but unlike Parse.properties of ef86de9c98aa;
 wenzelm parents: 
42657diff
changeset | 66 | val properties: Properties.T parser | 
| 29310 | 67 | val name: bstring parser | 
| 29581 | 68 | val binding: binding parser | 
| 29310 | 69 | val xname: xstring parser | 
| 70 | val text: string parser | |
| 48881 
46e053eda5dd
clarified Parse.path vs. Parse.explode -- prefer errors in proper transaction context;
 wenzelm parents: 
46922diff
changeset | 71 | val path: string parser | 
| 40800 
330eb65c9469
Parse.liberal_name for document antiquotations and attributes;
 wenzelm parents: 
40793diff
changeset | 72 | val liberal_name: xstring parser | 
| 29310 | 73 | val parname: string parser | 
| 29581 | 74 | val parbinding: binding parser | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 75 | val class: string parser | 
| 29310 | 76 | val sort: string parser | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 77 | val type_const: string parser | 
| 29310 | 78 | val arity: (string * string list * string) parser | 
| 79 | val multi_arity: (string list * string list * string) parser | |
| 80 | val type_args: string list parser | |
| 35838 | 81 | val type_args_constrained: (string * string option) list parser | 
| 29310 | 82 | val typ_group: string parser | 
| 83 | val typ: string parser | |
| 84 | val mixfix: mixfix parser | |
| 85 | val mixfix': mixfix parser | |
| 86 | val opt_mixfix: mixfix parser | |
| 87 | val opt_mixfix': mixfix parser | |
| 88 | val where_: string parser | |
| 42299 | 89 | val const_decl: (string * string * mixfix) parser | 
| 30339 | 90 | val const_binding: (binding * string * mixfix) parser | 
| 29581 | 91 | val params: (binding * string option) list parser | 
| 92 | val simple_fixes: (binding * string option) list parser | |
| 93 | val fixes: (binding * string option * mixfix) list parser | |
| 94 | val for_fixes: (binding * string option * mixfix) list parser | |
| 59064 | 95 | val ML_source: Input.source parser | 
| 96 | val document_source: Input.source parser | |
| 29310 | 97 | val term_group: string parser | 
| 98 | val prop_group: string parser | |
| 99 | val term: string parser | |
| 100 | val prop: string parser | |
| 42300 
0d1cbc1fe579
notation: proper markup for type constructor / constant;
 wenzelm parents: 
42299diff
changeset | 101 | val const: string parser | 
| 40793 
d21aedaa91e7
added Parse.literal_fact with proper inner_syntax markup (source position);
 wenzelm parents: 
40296diff
changeset | 102 | val literal_fact: string parser | 
| 29310 | 103 | val propp: (string * string list) parser | 
| 104 | val termp: (string * string list) parser | |
| 45488 
6d71d9e52369
pass positions for named targets, for formal links in the document model;
 wenzelm parents: 
45331diff
changeset | 105 | val target: (xstring * Position.T) parser | 
| 
6d71d9e52369
pass positions for named targets, for formal links in the document model;
 wenzelm parents: 
45331diff
changeset | 106 | val opt_target: (xstring * Position.T) option parser | 
| 56201 | 107 | val args: Token.T list parser | 
| 108 | val args1: (string -> bool) -> Token.T list parser | |
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 109 | val attribs: Token.src list parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 110 | val opt_attribs: Token.src list parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 111 | val thm_sel: Facts.interval list parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 112 | val xthm: (Facts.ref * Token.src list) parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 113 | val xthms1: (Facts.ref * Token.src list) list parser | 
| 5826 | 114 | end; | 
| 115 | ||
| 36949 
080e85d46108
renamed structure OuterKeyword to Keyword and OuterParse to Parse, keeping the old names as legacy aliases for some time;
 wenzelm parents: 
35838diff
changeset | 116 | structure Parse: PARSE = | 
| 5826 | 117 | struct | 
| 118 | ||
| 119 | (** error handling **) | |
| 120 | ||
| 121 | (* group atomic parsers (no cuts!) *) | |
| 122 | ||
| 44357 | 123 | fun group s scan = scan || Scan.fail_with | 
| 48911 
5debc3e4fa81
tuned messages: end-of-input rarely means physical end-of-file from the past;
 wenzelm parents: 
48881diff
changeset | 124 | (fn [] => (fn () => s () ^ " expected,\nbut end-of-input was found") | 
| 42519 | 125 | | tok :: _ => | 
| 43947 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 126 | (fn () => | 
| 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 127 | (case Token.text_of tok of | 
| 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 128 | (txt, "") => | 
| 55708 | 129 | s () ^ " expected,\nbut " ^ txt ^ Position.here (Token.pos_of tok) ^ | 
| 130 | " was found" | |
| 43947 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 131 | | (txt1, txt2) => | 
| 55708 | 132 | s () ^ " expected,\nbut " ^ txt1 ^ Position.here (Token.pos_of tok) ^ | 
| 133 | " was found:\n" ^ txt2))); | |
| 5826 | 134 | |
| 135 | ||
| 5877 | 136 | (* cut *) | 
| 5826 | 137 | |
| 8581 
5c7ed2af8bfb
!!!! = cut "Corrupted outer syntax in presentation";
 wenzelm parents: 
8350diff
changeset | 138 | fun cut kind scan = | 
| 5826 | 139 | let | 
| 48911 
5debc3e4fa81
tuned messages: end-of-input rarely means physical end-of-file from the past;
 wenzelm parents: 
48881diff
changeset | 140 | fun get_pos [] = " (end-of-input)" | 
| 55708 | 141 | | get_pos (tok :: _) = Position.here (Token.pos_of tok); | 
| 5826 | 142 | |
| 43947 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 143 | fun err (toks, NONE) = (fn () => kind ^ get_pos toks) | 
| 25625 | 144 | | err (toks, SOME msg) = | 
| 43947 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 145 | (fn () => | 
| 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 146 | let val s = msg () in | 
| 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 147 | if String.isPrefix kind s then s | 
| 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 148 | else kind ^ get_pos toks ^ ": " ^ s | 
| 
9b00f09f7721
defer evaluation of Scan.message, for improved performance in the frequent situation where failure is handled later (e.g. via ||);
 wenzelm parents: 
43775diff
changeset | 149 | end); | 
| 5826 | 150 | in Scan.!! err scan end; | 
| 151 | ||
| 8586 | 152 | fun !!! scan = cut "Outer syntax error" scan; | 
| 153 | fun !!!! scan = cut "Corrupted outer syntax in presentation" scan; | |
| 8581 
5c7ed2af8bfb
!!!! = cut "Corrupted outer syntax in presentation";
 wenzelm parents: 
8350diff
changeset | 154 | |
| 5826 | 155 | |
| 156 | ||
| 157 | (** basic parsers **) | |
| 158 | ||
| 159 | (* utils *) | |
| 160 | ||
| 161 | fun triple1 ((x, y), z) = (x, y, z); | |
| 162 | fun triple2 (x, (y, z)) = (x, y, z); | |
| 6430 | 163 | fun triple_swap ((x, y), z) = ((x, z), y); | 
| 5826 | 164 | |
| 165 | ||
| 166 | (* tokens *) | |
| 167 | ||
| 27815 | 168 | fun RESET_VALUE atom = (*required for all primitive parsers*) | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 169 | Scan.ahead (Scan.one (K true)) -- atom >> (fn (arg, x) => (Token.assign NONE arg; x)); | 
| 27815 | 170 | |
| 171 | ||
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 172 | val not_eof = RESET_VALUE (Scan.one Token.not_eof); | 
| 15703 | 173 | |
| 56201 | 174 | fun token atom = Scan.ahead not_eof --| atom; | 
| 175 | ||
| 59029 
c907cbe36713
more careful ML source positions, for improved PIDE markup;
 wenzelm parents: 
58908diff
changeset | 176 | fun range scan = (Scan.ahead not_eof >> (Token.range_of o single)) -- scan >> Library.swap; | 
| 55708 | 177 | fun position scan = (Scan.ahead not_eof >> Token.pos_of) -- scan >> Library.swap; | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 178 | fun source_position atom = Scan.ahead atom |-- not_eof >> Token.source_position_of; | 
| 55111 | 179 | fun inner_syntax atom = Scan.ahead atom |-- not_eof >> Token.inner_syntax_of; | 
| 5826 | 180 | |
| 181 | fun kind k = | |
| 44357 | 182 | group (fn () => Token.str_of_kind k) | 
| 183 | (RESET_VALUE (Scan.one (Token.is_kind k) >> Token.content_of)); | |
| 5826 | 184 | |
| 58908 | 185 | val command_ = kind Token.Command; | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 186 | val keyword = kind Token.Keyword; | 
| 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 187 | val short_ident = kind Token.Ident; | 
| 59081 | 188 | val long_ident = kind Token.Long_Ident; | 
| 189 | val sym_ident = kind Token.Sym_Ident; | |
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 190 | val term_var = kind Token.Var; | 
| 59081 | 191 | val type_ident = kind Token.Type_Ident; | 
| 192 | val type_var = kind Token.Type_Var; | |
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 193 | val number = kind Token.Nat; | 
| 40290 
47f572aff50a
support for floating-point tokens in outer syntax (coinciding with inner syntax version);
 wenzelm parents: 
36959diff
changeset | 194 | val float_number = kind Token.Float; | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 195 | val string = kind Token.String; | 
| 59081 | 196 | val alt_string = kind Token.Alt_String; | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 197 | val verbatim = kind Token.Verbatim; | 
| 55033 | 198 | val cartouche = kind Token.Cartouche; | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 199 | val eof = kind Token.EOF; | 
| 5826 | 200 | |
| 58908 | 201 | fun command x = | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 202 | group (fn () => Token.str_of_kind Token.Command ^ " " ^ quote x) | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 203 | (RESET_VALUE (Scan.one (fn tok => Token.is_command tok andalso Token.content_of tok = x))) | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 204 | >> Token.content_of; | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 205 | |
| 56202 | 206 | fun keyword_with pred = RESET_VALUE (Scan.one (Token.keyword_with pred) >> Token.content_of); | 
| 207 | ||
| 208 | fun keyword_markup markup x = | |
| 44357 | 209 | group (fn () => Token.str_of_kind Token.Keyword ^ " " ^ quote x) | 
| 56063 | 210 | (Scan.ahead not_eof -- keyword_with (fn y => x = y)) | 
| 56202 | 211 | >> (fn (tok, x) => (Token.assign (SOME (Token.Literal markup)) tok; x)); | 
| 212 | ||
| 213 | val keyword_improper = keyword_markup (true, Markup.improper); | |
| 214 | val $$$ = keyword_markup (false, Markup.quasi_keyword); | |
| 9131 | 215 | |
| 16030 | 216 | fun reserved x = | 
| 44357 | 217 | group (fn () => "reserved identifier " ^ quote x) | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 218 | (RESET_VALUE (Scan.one (Token.ident_with (fn y => x = y)) >> Token.content_of)); | 
| 16030 | 219 | |
| 15703 | 220 | val minus = sym_ident :-- (fn "-" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 11792 
311eee3d63b6
parser for underscore (actually a symbolic identifier!);
 wenzelm parents: 
11651diff
changeset | 221 | val underscore = sym_ident :-- (fn "_" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 15703 | 222 | fun maybe scan = underscore >> K NONE || scan >> SOME; | 
| 11792 
311eee3d63b6
parser for underscore (actually a symbolic identifier!);
 wenzelm parents: 
11651diff
changeset | 223 | |
| 14835 | 224 | val nat = number >> (#1 o Library.read_int o Symbol.explode); | 
| 27815 | 225 | val int = Scan.optional (minus >> K ~1) 1 -- nat >> op *; | 
| 51988 | 226 | val real = float_number >> Markup.parse_real || int >> Real.fromInt; | 
| 5826 | 227 | |
| 44357 | 228 | val tag_name = group (fn () => "tag name") (short_ident || string); | 
| 17070 | 229 | val tags = Scan.repeat ($$$ "%" |-- !!! tag_name); | 
| 230 | ||
| 7930 | 231 | val opt_unit = Scan.optional ($$$ "(" -- $$$ ")" >> (K ())) ();
 | 
| 14646 | 232 | fun opt_keyword s = Scan.optional ($$$ "(" |-- !!! (($$$ s >> K true) --| $$$ ")")) false;
 | 
| 233 | ||
| 20983 | 234 | val begin = $$$ "begin"; | 
| 235 | val opt_begin = Scan.optional (begin >> K true) false; | |
| 20961 | 236 | |
| 5826 | 237 | |
| 238 | (* enumerations *) | |
| 239 | ||
| 55764 | 240 | fun enum1_positions sep scan = | 
| 241 | scan -- Scan.repeat (position ($$$ sep) -- !!! scan) >> | |
| 242 | (fn (x, ys) => (x :: map #2 ys, map (#2 o #1) ys)); | |
| 243 | fun enum_positions sep scan = | |
| 244 | enum1_positions sep scan || Scan.succeed ([], []); | |
| 245 | ||
| 25999 | 246 | fun enum1 sep scan = scan ::: Scan.repeat ($$$ sep |-- !!! scan); | 
| 5826 | 247 | fun enum sep scan = enum1 sep scan || Scan.succeed []; | 
| 248 | ||
| 27815 | 249 | fun enum1' sep scan = scan ::: Scan.repeat (Scan.lift ($$$ sep) |-- scan); | 
| 250 | fun enum' sep scan = enum1' sep scan || Scan.succeed []; | |
| 5826 | 251 | |
| 6013 | 252 | fun and_list1 scan = enum1 "and" scan; | 
| 253 | fun and_list scan = enum "and" scan; | |
| 254 | ||
| 27815 | 255 | fun and_list1' scan = enum1' "and" scan; | 
| 256 | fun and_list' scan = enum' "and" scan; | |
| 257 | ||
| 258 | fun list1 scan = enum1 "," scan; | |
| 259 | fun list scan = enum "," scan; | |
| 260 | ||
| 43775 
b361c7d184e7
added Parse.properties (again) -- allow empty list like Parse_Value.properties but unlike Parse.properties of ef86de9c98aa;
 wenzelm parents: 
42657diff
changeset | 261 | val properties = $$$ "(" |-- !!! (list (string -- ($$$ "=" |-- string)) --| $$$ ")");
 | 
| 
b361c7d184e7
added Parse.properties (again) -- allow empty list like Parse_Value.properties but unlike Parse.properties of ef86de9c98aa;
 wenzelm parents: 
42657diff
changeset | 262 | |
| 5826 | 263 | |
| 5960 | 264 | (* names and text *) | 
| 5826 | 265 | |
| 44357 | 266 | val name = group (fn () => "name declaration") (short_ident || sym_ident || string || number); | 
| 267 | ||
| 30223 
24d975352879
renamed Binding.name_pos to Binding.make, renamed Binding.base_name to Binding.name_of, renamed Binding.map_base to Binding.map_name, added mandatory flag to Binding.qualify;
 wenzelm parents: 
29581diff
changeset | 268 | val binding = position name >> Binding.make; | 
| 44357 | 269 | |
| 270 | val xname = group (fn () => "name reference") | |
| 271 | (short_ident || long_ident || sym_ident || string || number); | |
| 272 | ||
| 273 | val text = group (fn () => "text") | |
| 56499 
7e0178c84994
allow text cartouches in regular outer syntax categories "text" and "altstring";
 wenzelm parents: 
56202diff
changeset | 274 | (short_ident || long_ident || sym_ident || string || number || verbatim || cartouche); | 
| 44357 | 275 | |
| 48881 
46e053eda5dd
clarified Parse.path vs. Parse.explode -- prefer errors in proper transaction context;
 wenzelm parents: 
46922diff
changeset | 276 | val path = group (fn () => "file name/path specification") name; | 
| 6553 | 277 | |
| 56063 | 278 | val liberal_name = keyword_with Token.ident_or_symbolic || xname; | 
| 40800 
330eb65c9469
Parse.liberal_name for document antiquotations and attributes;
 wenzelm parents: 
40793diff
changeset | 279 | |
| 18898 | 280 | val parname = Scan.optional ($$$ "(" |-- name --| $$$ ")") "";
 | 
| 28965 | 281 | val parbinding = Scan.optional ($$$ "(" |-- binding --| $$$ ")") Binding.empty;
 | 
| 18898 | 282 | |
| 6553 | 283 | |
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 284 | (* type classes *) | 
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 285 | |
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 286 | val class = group (fn () => "type class") (inner_syntax xname); | 
| 5826 | 287 | |
| 44357 | 288 | val sort = group (fn () => "sort") (inner_syntax xname); | 
| 5826 | 289 | |
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 290 | val type_const = inner_syntax (group (fn () => "type constructor") xname); | 
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 291 | |
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 292 | val arity = type_const -- ($$$ "::" |-- !!! | 
| 22331 | 293 |   (Scan.optional ($$$ "(" |-- !!! (list1 sort --| $$$ ")")) [] -- sort)) >> triple2;
 | 
| 5826 | 294 | |
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 295 | val multi_arity = and_list1 type_const -- ($$$ "::" |-- !!! | 
| 25541 | 296 |   (Scan.optional ($$$ "(" |-- !!! (list1 sort --| $$$ ")")) [] -- sort)) >> triple2;
 | 
| 297 | ||
| 5826 | 298 | |
| 299 | (* types *) | |
| 300 | ||
| 44357 | 301 | val typ_group = | 
| 302 | group (fn () => "type") | |
| 303 | (short_ident || long_ident || sym_ident || type_ident || type_var || string || number); | |
| 5826 | 304 | |
| 27753 
94b672153b49
sort/typ/term/prop: inner_syntax markup encodes original source position;
 wenzelm parents: 
27737diff
changeset | 305 | val typ = inner_syntax typ_group; | 
| 
94b672153b49
sort/typ/term/prop: inner_syntax markup encodes original source position;
 wenzelm parents: 
27737diff
changeset | 306 | |
| 35838 | 307 | fun type_arguments arg = | 
| 308 | arg >> single || | |
| 309 |   $$$ "(" |-- !!! (list1 arg --| $$$ ")") ||
 | |
| 5826 | 310 | Scan.succeed []; | 
| 311 | ||
| 35838 | 312 | val type_args = type_arguments type_ident; | 
| 313 | val type_args_constrained = type_arguments (type_ident -- Scan.option ($$$ "::" |-- !!! sort)); | |
| 314 | ||
| 5826 | 315 | |
| 316 | (* mixfix annotations *) | |
| 317 | ||
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 318 | local | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 319 | |
| 18669 | 320 | val mfix = string -- | 
| 321 | !!! (Scan.optional ($$$ "[" |-- !!! (list nat --| $$$ "]")) [] -- | |
| 42297 
140f283266b7
discontinued Syntax.max_pri, which is not really a symbolic parameter;
 wenzelm parents: 
42287diff
changeset | 322 | Scan.optional nat 1000) >> (Mixfix o triple2); | 
| 18669 | 323 | |
| 35130 | 324 | val infx = $$$ "infix" |-- !!! (string -- nat >> Infix); | 
| 325 | val infxl = $$$ "infixl" |-- !!! (string -- nat >> Infixl); | |
| 326 | val infxr = $$$ "infixr" |-- !!! (string -- nat >> Infixr); | |
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 327 | val strcture = $$$ "structure" >> K Structure; | 
| 5826 | 328 | |
| 18669 | 329 | val binder = $$$ "binder" |-- | 
| 330 | !!! (string -- ($$$ "[" |-- nat --| $$$ "]" -- nat || nat >> (fn n => (n, n)))) | |
| 331 | >> (Binder o triple2); | |
| 332 | ||
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 333 | val mixfix_body = mfix || strcture || binder || infxl || infxr || infx; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 334 | |
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 335 | fun annotation guard body = $$$ "(" |-- guard (body --| $$$ ")");
 | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 336 | fun opt_annotation guard body = Scan.optional (annotation guard body) NoSyn; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 337 | |
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 338 | in | 
| 18669 | 339 | |
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 340 | val mixfix = annotation !!! mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 341 | val mixfix' = annotation I mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 342 | val opt_mixfix = opt_annotation !!! mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 343 | val opt_mixfix' = opt_annotation I mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 344 | |
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 345 | end; | 
| 5826 | 346 | |
| 347 | ||
| 18669 | 348 | (* fixes *) | 
| 5826 | 349 | |
| 21400 | 350 | val where_ = $$$ "where"; | 
| 351 | ||
| 42299 | 352 | val const_decl = name -- ($$$ "::" |-- !!! typ) -- opt_mixfix >> triple1; | 
| 30339 | 353 | val const_binding = binding -- ($$$ "::" |-- !!! typ) -- opt_mixfix >> triple1; | 
| 18669 | 354 | |
| 28081 
d664b2c1dfe6
explicit type Name.binding for higher-specification elements;
 wenzelm parents: 
28017diff
changeset | 355 | val params = Scan.repeat1 binding -- Scan.option ($$$ "::" |-- !!! typ) | 
| 18669 | 356 | >> (fn (xs, T) => map (rpair T) xs); | 
| 357 | ||
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19284diff
changeset | 358 | val simple_fixes = and_list1 params >> flat; | 
| 18669 | 359 | |
| 360 | val fixes = | |
| 45331 
6e0a8aba99ec
more liberal Parse.fixes, to avoid overlap of mixfix with is-pattern (notably in 'obtain' syntax);
 wenzelm parents: 
44357diff
changeset | 361 | and_list1 (binding -- Scan.option ($$$ "::" |-- typ) -- mixfix' >> (single o triple1) || | 
| 42287 
d98eb048a2e4
discontinued special treatment of structure Mixfix;
 wenzelm parents: 
40800diff
changeset | 362 | params >> map (fn (x, y) => (x, y, NoSyn))) >> flat; | 
| 5826 | 363 | |
| 19845 | 364 | val for_fixes = Scan.optional ($$$ "for" |-- !!! fixes) []; | 
| 365 | ||
| 5826 | 366 | |
| 27877 | 367 | (* embedded source text *) | 
| 27872 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 368 | |
| 44357 | 369 | val ML_source = source_position (group (fn () => "ML source") text); | 
| 51627 
589daaf48dba
tuned signature -- agree with markup terminology;
 wenzelm parents: 
48927diff
changeset | 370 | val document_source = source_position (group (fn () => "document source") text); | 
| 27872 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 371 | |
| 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 372 | |
| 5826 | 373 | (* terms *) | 
| 374 | ||
| 40793 
d21aedaa91e7
added Parse.literal_fact with proper inner_syntax markup (source position);
 wenzelm parents: 
40296diff
changeset | 375 | val tm = short_ident || long_ident || sym_ident || term_var || number || string; | 
| 5826 | 376 | |
| 44357 | 377 | val term_group = group (fn () => "term") tm; | 
| 378 | val prop_group = group (fn () => "proposition") tm; | |
| 27753 
94b672153b49
sort/typ/term/prop: inner_syntax markup encodes original source position;
 wenzelm parents: 
27737diff
changeset | 379 | |
| 
94b672153b49
sort/typ/term/prop: inner_syntax markup encodes original source position;
 wenzelm parents: 
27737diff
changeset | 380 | val term = inner_syntax term_group; | 
| 
94b672153b49
sort/typ/term/prop: inner_syntax markup encodes original source position;
 wenzelm parents: 
27737diff
changeset | 381 | val prop = inner_syntax prop_group; | 
| 5826 | 382 | |
| 44357 | 383 | val const = inner_syntax (group (fn () => "constant") xname); | 
| 42300 
0d1cbc1fe579
notation: proper markup for type constructor / constant;
 wenzelm parents: 
42299diff
changeset | 384 | |
| 56499 
7e0178c84994
allow text cartouches in regular outer syntax categories "text" and "altstring";
 wenzelm parents: 
56202diff
changeset | 385 | val literal_fact = inner_syntax (group (fn () => "literal fact") (alt_string || cartouche)); | 
| 40793 
d21aedaa91e7
added Parse.literal_fact with proper inner_syntax markup (source position);
 wenzelm parents: 
40296diff
changeset | 386 | |
| 5826 | 387 | |
| 6949 | 388 | (* patterns *) | 
| 6935 | 389 | |
| 6949 | 390 | val is_terms = Scan.repeat1 ($$$ "is" |-- term); | 
| 6935 | 391 | val is_props = Scan.repeat1 ($$$ "is" |-- prop); | 
| 392 | ||
| 19585 | 393 | val propp = prop -- Scan.optional ($$$ "(" |-- !!! (is_props --| $$$ ")")) [];
 | 
| 6949 | 394 | val termp = term -- Scan.optional ($$$ "(" |-- !!! (is_terms --| $$$ ")")) [];
 | 
| 6935 | 395 | |
| 396 | ||
| 22119 | 397 | (* targets *) | 
| 19811 | 398 | |
| 45488 
6d71d9e52369
pass positions for named targets, for formal links in the document model;
 wenzelm parents: 
45331diff
changeset | 399 | val target = ($$$ "(" -- $$$ "in") |-- !!! (position xname --| $$$ ")");
 | 
| 22119 | 400 | val opt_target = Scan.option target; | 
| 12272 | 401 | |
| 56201 | 402 | |
| 403 | (* arguments within outer syntax *) | |
| 404 | ||
| 405 | local | |
| 406 | ||
| 407 | val argument_kinds = | |
| 59081 | 408 | [Token.Ident, Token.Long_Ident, Token.Sym_Ident, Token.Var, Token.Type_Ident, Token.Type_Var, | 
| 409 | Token.Nat, Token.Float, Token.String, Token.Alt_String, Token.Cartouche, Token.Verbatim]; | |
| 56201 | 410 | |
| 411 | fun arguments is_symid = | |
| 412 | let | |
| 413 | fun argument blk = | |
| 414 | group (fn () => "argument") | |
| 415 | (Scan.one (fn tok => | |
| 416 | let val kind = Token.kind_of tok in | |
| 417 | member (op =) argument_kinds kind orelse | |
| 418 | Token.keyword_with is_symid tok orelse | |
| 419 | (blk andalso Token.keyword_with (fn s => s = ",") tok) | |
| 420 | end)); | |
| 421 | ||
| 422 | fun args blk x = Scan.optional (args1 blk) [] x | |
| 423 | and args1 blk x = | |
| 424 | ((Scan.repeat1 | |
| 425 | (Scan.repeat1 (argument blk) || | |
| 426 |           argsp "(" ")" ||
 | |
| 427 | argsp "[" "]")) >> flat) x | |
| 428 | and argsp l r x = (token ($$$ l) ::: !!! (args true @@@ (token ($$$ r) >> single))) x; | |
| 429 | in (args, args1) end; | |
| 430 | ||
| 431 | in | |
| 432 | ||
| 433 | val args = #1 (arguments Token.ident_or_symbolic) false; | |
| 434 | fun args1 is_symid = #2 (arguments is_symid) false; | |
| 435 | ||
| 436 | end; | |
| 437 | ||
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 438 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 439 | (* attributes *) | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 440 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 441 | val attrib = position liberal_name -- !!! args >> uncurry Token.src; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 442 | val attribs = $$$ "[" |-- list attrib --| $$$ "]"; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 443 | val opt_attribs = Scan.optional attribs []; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 444 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 445 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 446 | (* theorem references *) | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 447 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 448 | val thm_sel = $$$ "(" |-- list1
 | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 449 | (nat --| minus -- nat >> Facts.FromTo || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 450 | nat --| minus >> Facts.From || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 451 | nat >> Facts.Single) --| $$$ ")"; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 452 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 453 | val xthm = | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 454 | $$$ "[" |-- attribs --| $$$ "]" >> pair (Facts.named "") || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 455 | (literal_fact >> Facts.Fact || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 456 | position xname -- Scan.option thm_sel >> Facts.Named) -- opt_attribs; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 457 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 458 | val xthms1 = Scan.repeat1 xthm; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 459 | |
| 12272 | 460 | end; | 
| 30511 | 461 |