| author | wenzelm | 
| Fri, 28 Apr 2017 11:50:31 +0200 | |
| changeset 65602 | d9533e9615ad | 
| parent 63806 | c54a53ef1873 | 
| child 67136 | 1368cfa92b7a | 
| 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 | 
| 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 12 | val not_eof: Token.T parser | 
| 56201 | 13 | val token: 'a parser -> Token.T parser | 
| 59029 
c907cbe36713
more careful ML source positions, for improved PIDE markup;
 wenzelm parents: 
58908diff
changeset | 14 |   val range: 'a parser -> ('a * Position.range) parser
 | 
| 42326 | 15 |   val position: 'a parser -> ('a * Position.T) parser
 | 
| 59809 | 16 | val input: 'a parser -> Input.source parser | 
| 42326 | 17 | val inner_syntax: 'a parser -> string parser | 
| 58908 | 18 | val command_: string parser | 
| 29310 | 19 | val keyword: string parser | 
| 20 | val short_ident: string parser | |
| 21 | val long_ident: string parser | |
| 22 | val sym_ident: string parser | |
| 60629 | 23 | val dots: string parser | 
| 29310 | 24 | val minus: string parser | 
| 25 | val term_var: string parser | |
| 26 | val type_ident: string parser | |
| 27 | val type_var: string parser | |
| 28 | val number: string parser | |
| 40290 
47f572aff50a
support for floating-point tokens in outer syntax (coinciding with inner syntax version);
 wenzelm parents: 
36959diff
changeset | 29 | val float_number: string parser | 
| 29310 | 30 | val string: string parser | 
| 31 | val alt_string: string parser | |
| 32 | val verbatim: string parser | |
| 55033 | 33 | val cartouche: string parser | 
| 29310 | 34 | val eof: string parser | 
| 58908 | 35 | val command: string -> string parser | 
| 29310 | 36 | val keyword_with: (string -> bool) -> string parser | 
| 56202 | 37 | val keyword_markup: bool * Markup.T -> string -> string parser | 
| 38 | val keyword_improper: string -> string parser | |
| 29310 | 39 | val $$$ : string -> string parser | 
| 40 | val reserved: string -> string parser | |
| 41 | val underscore: string parser | |
| 42 | val maybe: 'a parser -> 'a option parser | |
| 43 | val tag_name: string parser | |
| 44 | val tags: string list parser | |
| 45 | val opt_keyword: string -> bool parser | |
| 59917 
9830c944670f
more uniform "verbose" option to print name space;
 wenzelm parents: 
59809diff
changeset | 46 | val opt_bang: bool parser | 
| 29310 | 47 | val begin: string parser | 
| 48 | val opt_begin: bool parser | |
| 49 | val nat: int parser | |
| 50 | val int: int parser | |
| 40290 
47f572aff50a
support for floating-point tokens in outer syntax (coinciding with inner syntax version);
 wenzelm parents: 
36959diff
changeset | 51 | val real: real parser | 
| 55764 | 52 |   val enum_positions: string -> 'a parser -> ('a list * Position.T list) parser
 | 
| 53 |   val enum1_positions: string -> 'a parser -> ('a list * Position.T list) parser
 | |
| 29310 | 54 | val enum: string -> 'a parser -> 'a list parser | 
| 55 | val enum1: string -> 'a parser -> 'a list parser | |
| 56 | val and_list: 'a parser -> 'a list parser | |
| 57 | val and_list1: 'a parser -> 'a list parser | |
| 30511 | 58 | val enum': string -> 'a context_parser -> 'a list context_parser | 
| 59 | val enum1': string -> 'a context_parser -> 'a list context_parser | |
| 60 | val and_list': 'a context_parser -> 'a list context_parser | |
| 61 | val and_list1': 'a context_parser -> 'a list context_parser | |
| 29310 | 62 | val list: 'a parser -> 'a list parser | 
| 63 | 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 | 64 | val properties: Properties.T parser | 
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 65 | val name: string parser | 
| 29581 | 66 | val binding: binding parser | 
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 67 | val embedded: string parser | 
| 29310 | 68 | val text: string parser | 
| 48881 
46e053eda5dd
clarified Parse.path vs. Parse.explode -- prefer errors in proper transaction context;
 wenzelm parents: 
46922diff
changeset | 69 | val path: string parser | 
| 62969 | 70 | val theory_name: string parser | 
| 71 | val liberal_name: string parser | |
| 29310 | 72 | val parname: string parser | 
| 29581 | 73 | val parbinding: binding parser | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 74 | val class: string parser | 
| 29310 | 75 | val sort: string parser | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 76 | val type_const: string parser | 
| 29310 | 77 | val arity: (string * string list * string) parser | 
| 78 | val multi_arity: (string list * string list * string) parser | |
| 79 | val type_args: string list parser | |
| 35838 | 80 | val type_args_constrained: (string * string option) list parser | 
| 29310 | 81 | val typ: string parser | 
| 82 | val mixfix: mixfix parser | |
| 83 | val mixfix': mixfix parser | |
| 84 | val opt_mixfix: mixfix parser | |
| 85 | val opt_mixfix': mixfix parser | |
| 62856 | 86 | val syntax_mode: Syntax.mode parser | 
| 29310 | 87 | val where_: string parser | 
| 42299 | 88 | val const_decl: (string * string * mixfix) parser | 
| 30339 | 89 | val const_binding: (binding * string * mixfix) parser | 
| 60448 | 90 | val params: (binding * string option * mixfix) list parser | 
| 63285 | 91 | val vars: (binding * string option * mixfix) list parser | 
| 29581 | 92 | val for_fixes: (binding * string option * mixfix) list parser | 
| 59064 | 93 | val ML_source: Input.source parser | 
| 94 | val document_source: Input.source parser | |
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 95 | val const: string parser | 
| 29310 | 96 | val term: string parser | 
| 97 | val prop: string parser | |
| 40793 
d21aedaa91e7
added Parse.literal_fact with proper inner_syntax markup (source position);
 wenzelm parents: 
40296diff
changeset | 98 | val literal_fact: string parser | 
| 29310 | 99 | val propp: (string * string list) parser | 
| 100 | val termp: (string * string list) parser | |
| 59924 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 101 | val private: Position.T parser | 
| 59990 
a81dc82ecba3
clarified keyword 'qualified' in accordance to a similar keyword from Haskell (despite unrelated Binding.qualified in Isabelle/ML);
 wenzelm parents: 
59939diff
changeset | 102 | val qualified: Position.T parser | 
| 62969 | 103 | val target: (string * Position.T) parser | 
| 104 | val opt_target: (string * Position.T) option parser | |
| 56201 | 105 | val args: Token.T list parser | 
| 106 | val args1: (string -> bool) -> Token.T list parser | |
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 107 | val attribs: Token.src list parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 108 | val opt_attribs: Token.src list parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 109 | val thm_sel: Facts.interval list parser | 
| 62969 | 110 | val thm: (Facts.ref * Token.src list) parser | 
| 111 | val thms1: (Facts.ref * Token.src list) list parser | |
| 5826 | 112 | end; | 
| 113 | ||
| 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 | 114 | structure Parse: PARSE = | 
| 5826 | 115 | struct | 
| 116 | ||
| 117 | (** error handling **) | |
| 118 | ||
| 119 | (* group atomic parsers (no cuts!) *) | |
| 120 | ||
| 44357 | 121 | 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 | 122 | (fn [] => (fn () => s () ^ " expected,\nbut end-of-input was found") | 
| 42519 | 123 | | 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 | 124 | (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 | 125 | (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 | 126 | (txt, "") => | 
| 55708 | 127 | s () ^ " expected,\nbut " ^ txt ^ Position.here (Token.pos_of tok) ^ | 
| 128 | " 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 | 129 | | (txt1, txt2) => | 
| 55708 | 130 | s () ^ " expected,\nbut " ^ txt1 ^ Position.here (Token.pos_of tok) ^ | 
| 131 | " was found:\n" ^ txt2))); | |
| 5826 | 132 | |
| 133 | ||
| 5877 | 134 | (* cut *) | 
| 5826 | 135 | |
| 8581 
5c7ed2af8bfb
!!!! = cut "Corrupted outer syntax in presentation";
 wenzelm parents: 
8350diff
changeset | 136 | fun cut kind scan = | 
| 5826 | 137 | let | 
| 48911 
5debc3e4fa81
tuned messages: end-of-input rarely means physical end-of-file from the past;
 wenzelm parents: 
48881diff
changeset | 138 | fun get_pos [] = " (end-of-input)" | 
| 55708 | 139 | | get_pos (tok :: _) = Position.here (Token.pos_of tok); | 
| 5826 | 140 | |
| 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 | 141 | fun err (toks, NONE) = (fn () => kind ^ get_pos toks) | 
| 25625 | 142 | | 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 | 143 | (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 | 144 | 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 | 145 | 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 | 146 | 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 | 147 | end); | 
| 5826 | 148 | in Scan.!! err scan end; | 
| 149 | ||
| 8586 | 150 | fun !!! scan = cut "Outer syntax error" scan; | 
| 151 | fun !!!! scan = cut "Corrupted outer syntax in presentation" scan; | |
| 8581 
5c7ed2af8bfb
!!!! = cut "Corrupted outer syntax in presentation";
 wenzelm parents: 
8350diff
changeset | 152 | |
| 5826 | 153 | |
| 154 | ||
| 155 | (** basic parsers **) | |
| 156 | ||
| 157 | (* tokens *) | |
| 158 | ||
| 27815 | 159 | 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 | 160 | Scan.ahead (Scan.one (K true)) -- atom >> (fn (arg, x) => (Token.assign NONE arg; x)); | 
| 27815 | 161 | |
| 162 | ||
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 163 | val not_eof = RESET_VALUE (Scan.one Token.not_eof); | 
| 15703 | 164 | |
| 56201 | 165 | fun token atom = Scan.ahead not_eof --| atom; | 
| 166 | ||
| 59029 
c907cbe36713
more careful ML source positions, for improved PIDE markup;
 wenzelm parents: 
58908diff
changeset | 167 | fun range scan = (Scan.ahead not_eof >> (Token.range_of o single)) -- scan >> Library.swap; | 
| 55708 | 168 | fun position scan = (Scan.ahead not_eof >> Token.pos_of) -- scan >> Library.swap; | 
| 59809 | 169 | fun input atom = Scan.ahead atom |-- not_eof >> Token.input_of; | 
| 55111 | 170 | fun inner_syntax atom = Scan.ahead atom |-- not_eof >> Token.inner_syntax_of; | 
| 5826 | 171 | |
| 172 | fun kind k = | |
| 44357 | 173 | group (fn () => Token.str_of_kind k) | 
| 174 | (RESET_VALUE (Scan.one (Token.is_kind k) >> Token.content_of)); | |
| 5826 | 175 | |
| 58908 | 176 | 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 | 177 | 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 | 178 | val short_ident = kind Token.Ident; | 
| 59081 | 179 | val long_ident = kind Token.Long_Ident; | 
| 180 | 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 | 181 | val term_var = kind Token.Var; | 
| 59081 | 182 | val type_ident = kind Token.Type_Ident; | 
| 183 | 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 | 184 | val number = kind Token.Nat; | 
| 40290 
47f572aff50a
support for floating-point tokens in outer syntax (coinciding with inner syntax version);
 wenzelm parents: 
36959diff
changeset | 185 | 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 | 186 | val string = kind Token.String; | 
| 59081 | 187 | 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 | 188 | val verbatim = kind Token.Verbatim; | 
| 55033 | 189 | 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 | 190 | val eof = kind Token.EOF; | 
| 5826 | 191 | |
| 58908 | 192 | fun command x = | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 193 | group (fn () => Token.str_of_kind Token.Command ^ " " ^ quote x) | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 194 | (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 | 195 | >> Token.content_of; | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 196 | |
| 56202 | 197 | fun keyword_with pred = RESET_VALUE (Scan.one (Token.keyword_with pred) >> Token.content_of); | 
| 198 | ||
| 199 | fun keyword_markup markup x = | |
| 44357 | 200 | group (fn () => Token.str_of_kind Token.Keyword ^ " " ^ quote x) | 
| 56063 | 201 | (Scan.ahead not_eof -- keyword_with (fn y => x = y)) | 
| 56202 | 202 | >> (fn (tok, x) => (Token.assign (SOME (Token.Literal markup)) tok; x)); | 
| 203 | ||
| 204 | val keyword_improper = keyword_markup (true, Markup.improper); | |
| 205 | val $$$ = keyword_markup (false, Markup.quasi_keyword); | |
| 9131 | 206 | |
| 16030 | 207 | fun reserved x = | 
| 44357 | 208 | 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 | 209 | (RESET_VALUE (Scan.one (Token.ident_with (fn y => x = y)) >> Token.content_of)); | 
| 16030 | 210 | |
| 62529 
8b7bdfc09f3b
clarified treatment of fragments of Isabelle symbols during bootstrap;
 wenzelm parents: 
61814diff
changeset | 211 | val dots = sym_ident :-- (fn "\<dots>" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 60629 | 212 | |
| 15703 | 213 | val minus = sym_ident :-- (fn "-" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 60629 | 214 | |
| 11792 
311eee3d63b6
parser for underscore (actually a symbolic identifier!);
 wenzelm parents: 
11651diff
changeset | 215 | val underscore = sym_ident :-- (fn "_" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 15703 | 216 | fun maybe scan = underscore >> K NONE || scan >> SOME; | 
| 11792 
311eee3d63b6
parser for underscore (actually a symbolic identifier!);
 wenzelm parents: 
11651diff
changeset | 217 | |
| 14835 | 218 | val nat = number >> (#1 o Library.read_int o Symbol.explode); | 
| 27815 | 219 | val int = Scan.optional (minus >> K ~1) 1 -- nat >> op *; | 
| 63806 | 220 | val real = float_number >> Value.parse_real || int >> Real.fromInt; | 
| 5826 | 221 | |
| 44357 | 222 | val tag_name = group (fn () => "tag name") (short_ident || string); | 
| 17070 | 223 | val tags = Scan.repeat ($$$ "%" |-- !!! tag_name); | 
| 224 | ||
| 14646 | 225 | fun opt_keyword s = Scan.optional ($$$ "(" |-- !!! (($$$ s >> K true) --| $$$ ")")) false;
 | 
| 59917 
9830c944670f
more uniform "verbose" option to print name space;
 wenzelm parents: 
59809diff
changeset | 226 | val opt_bang = Scan.optional ($$$ "!" >> K true) false; | 
| 14646 | 227 | |
| 20983 | 228 | val begin = $$$ "begin"; | 
| 229 | val opt_begin = Scan.optional (begin >> K true) false; | |
| 20961 | 230 | |
| 5826 | 231 | |
| 232 | (* enumerations *) | |
| 233 | ||
| 55764 | 234 | fun enum1_positions sep scan = | 
| 235 | scan -- Scan.repeat (position ($$$ sep) -- !!! scan) >> | |
| 236 | (fn (x, ys) => (x :: map #2 ys, map (#2 o #1) ys)); | |
| 237 | fun enum_positions sep scan = | |
| 238 | enum1_positions sep scan || Scan.succeed ([], []); | |
| 239 | ||
| 25999 | 240 | fun enum1 sep scan = scan ::: Scan.repeat ($$$ sep |-- !!! scan); | 
| 5826 | 241 | fun enum sep scan = enum1 sep scan || Scan.succeed []; | 
| 242 | ||
| 27815 | 243 | fun enum1' sep scan = scan ::: Scan.repeat (Scan.lift ($$$ sep) |-- scan); | 
| 244 | fun enum' sep scan = enum1' sep scan || Scan.succeed []; | |
| 5826 | 245 | |
| 6013 | 246 | fun and_list1 scan = enum1 "and" scan; | 
| 247 | fun and_list scan = enum "and" scan; | |
| 248 | ||
| 27815 | 249 | fun and_list1' scan = enum1' "and" scan; | 
| 250 | fun and_list' scan = enum' "and" scan; | |
| 251 | ||
| 252 | fun list1 scan = enum1 "," scan; | |
| 253 | fun list scan = enum "," scan; | |
| 254 | ||
| 43775 
b361c7d184e7
added Parse.properties (again) -- allow empty list like Parse_Value.properties but unlike Parse.properties of ef86de9c98aa;
 wenzelm parents: 
42657diff
changeset | 255 | 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 | 256 | |
| 5826 | 257 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 258 | (* names and embedded content *) | 
| 5826 | 259 | |
| 62969 | 260 | val name = | 
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 261 | group (fn () => "name") | 
| 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 262 | (short_ident || long_ident || sym_ident || number || string); | 
| 44357 | 263 | |
| 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 | 264 | val binding = position name >> Binding.make; | 
| 44357 | 265 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 266 | val embedded = | 
| 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 267 | group (fn () => "embedded content") | 
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 268 | (cartouche || string || short_ident || long_ident || sym_ident || | 
| 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 269 | term_var || type_ident || type_var || number); | 
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 270 | |
| 63139 | 271 | val text = group (fn () => "text") (embedded || verbatim); | 
| 44357 | 272 | |
| 63672 | 273 | val path = group (fn () => "file name/path specification") embedded; | 
| 6553 | 274 | |
| 59693 | 275 | val theory_name = group (fn () => "theory name") name; | 
| 276 | ||
| 62969 | 277 | val liberal_name = keyword_with Token.ident_or_symbolic || name; | 
| 40800 
330eb65c9469
Parse.liberal_name for document antiquotations and attributes;
 wenzelm parents: 
40793diff
changeset | 278 | |
| 18898 | 279 | val parname = Scan.optional ($$$ "(" |-- name --| $$$ ")") "";
 | 
| 28965 | 280 | val parbinding = Scan.optional ($$$ "(" |-- binding --| $$$ ")") Binding.empty;
 | 
| 18898 | 281 | |
| 6553 | 282 | |
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 283 | (* type classes *) | 
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 284 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 285 | val class = group (fn () => "type class") (inner_syntax embedded); | 
| 5826 | 286 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 287 | val sort = group (fn () => "sort") (inner_syntax embedded); | 
| 5826 | 288 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 289 | val type_const = group (fn () => "type constructor") (inner_syntax embedded); | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 290 | |
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 291 | val arity = type_const -- ($$$ "::" |-- !!! | 
| 61466 | 292 |   (Scan.optional ($$$ "(" |-- !!! (list1 sort --| $$$ ")")) [] -- sort)) >> Scan.triple2;
 | 
| 5826 | 293 | |
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 294 | val multi_arity = and_list1 type_const -- ($$$ "::" |-- !!! | 
| 61466 | 295 |   (Scan.optional ($$$ "(" |-- !!! (list1 sort --| $$$ ")")) [] -- sort)) >> Scan.triple2;
 | 
| 25541 | 296 | |
| 5826 | 297 | |
| 298 | (* types *) | |
| 299 | ||
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 300 | val typ = group (fn () => "type") (inner_syntax embedded); | 
| 27753 
94b672153b49
sort/typ/term/prop: inner_syntax markup encodes original source position;
 wenzelm parents: 
27737diff
changeset | 301 | |
| 35838 | 302 | fun type_arguments arg = | 
| 303 | arg >> single || | |
| 304 |   $$$ "(" |-- !!! (list1 arg --| $$$ ")") ||
 | |
| 5826 | 305 | Scan.succeed []; | 
| 306 | ||
| 35838 | 307 | val type_args = type_arguments type_ident; | 
| 308 | val type_args_constrained = type_arguments (type_ident -- Scan.option ($$$ "::" |-- !!! sort)); | |
| 309 | ||
| 5826 | 310 | |
| 311 | (* mixfix annotations *) | |
| 312 | ||
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 313 | local | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 314 | |
| 62752 | 315 | val mfix = | 
| 316 | input string -- | |
| 317 | !!! (Scan.optional ($$$ "[" |-- !!! (list nat --| $$$ "]")) [] -- Scan.optional nat 1000) | |
| 62760 | 318 | >> (fn (sy, (ps, p)) => fn range => Mixfix (sy, ps, p, range)); | 
| 62752 | 319 | |
| 320 | val infx = | |
| 62760 | 321 | $$$ "infix" |-- !!! (input string -- nat >> (fn (sy, p) => fn range => Infix (sy, p, range))); | 
| 18669 | 322 | |
| 62752 | 323 | val infxl = | 
| 62760 | 324 | $$$ "infixl" |-- !!! (input string -- nat >> (fn (sy, p) => fn range => Infixl (sy, p, range))); | 
| 62752 | 325 | |
| 326 | val infxr = | |
| 62760 | 327 | $$$ "infixr" |-- !!! (input string -- nat >> (fn (sy, p) => fn range => Infixr (sy, p, range))); | 
| 5826 | 328 | |
| 62760 | 329 | val strcture = $$$ "structure" >> K Structure; | 
| 62752 | 330 | |
| 331 | val binder = | |
| 332 | $$$ "binder" |-- | |
| 333 | !!! (input string -- ($$$ "[" |-- nat --| $$$ "]" -- nat || nat >> (fn n => (n, n)))) | |
| 62760 | 334 | >> (fn (sy, (p, q)) => fn range => Binder (sy, p, q, range)); | 
| 18669 | 335 | |
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 336 | val mixfix_body = mfix || strcture || binder || infxl || infxr || infx; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 337 | |
| 62752 | 338 | fun annotation guard body = | 
| 339 |   Scan.trace ($$$ "(" |-- guard (body --| $$$ ")"))
 | |
| 62760 | 340 | >> (fn (mx, toks) => mx (Token.range_of toks)); | 
| 62752 | 341 | |
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 342 | 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 | 343 | |
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 344 | in | 
| 18669 | 345 | |
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 346 | val mixfix = annotation !!! mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 347 | val mixfix' = annotation I mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 348 | val opt_mixfix = opt_annotation !!! mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 349 | val opt_mixfix' = opt_annotation I mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 350 | |
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 351 | end; | 
| 5826 | 352 | |
| 353 | ||
| 62856 | 354 | (* syntax mode *) | 
| 355 | ||
| 356 | val syntax_mode_spec = | |
| 357 |   ($$$ "output" >> K ("", false)) || name -- Scan.optional ($$$ "output" >> K false) true;
 | |
| 358 | ||
| 359 | val syntax_mode = | |
| 360 |   Scan.optional ($$$ "(" |-- !!! (syntax_mode_spec --| $$$ ")")) Syntax.mode_default;
 | |
| 361 | ||
| 362 | ||
| 18669 | 363 | (* fixes *) | 
| 5826 | 364 | |
| 21400 | 365 | val where_ = $$$ "where"; | 
| 366 | ||
| 61466 | 367 | val const_decl = name -- ($$$ "::" |-- !!! typ) -- opt_mixfix >> Scan.triple1; | 
| 368 | val const_binding = binding -- ($$$ "::" |-- !!! typ) -- opt_mixfix >> Scan.triple1; | |
| 18669 | 369 | |
| 61466 | 370 | val param_mixfix = binding -- Scan.option ($$$ "::" |-- typ) -- mixfix' >> (single o Scan.triple1); | 
| 63230 | 371 | |
| 60448 | 372 | val params = | 
| 63230 | 373 | (binding -- Scan.repeat binding) -- Scan.option ($$$ "::" |-- !!! (Scan.ahead typ -- embedded)) | 
| 374 | >> (fn ((x, ys), T) => | |
| 375 | (x, Option.map #1 T, NoSyn) :: map (fn y => (y, Option.map #2 T, NoSyn)) ys); | |
| 18669 | 376 | |
| 63285 | 377 | val vars = and_list1 (param_mixfix || params) >> flat; | 
| 378 | ||
| 379 | val for_fixes = Scan.optional ($$$ "for" |-- !!! vars) []; | |
| 19845 | 380 | |
| 5826 | 381 | |
| 27877 | 382 | (* embedded source text *) | 
| 27872 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 383 | |
| 59809 | 384 | val ML_source = input (group (fn () => "ML source") text); | 
| 385 | val document_source = input (group (fn () => "document source") text); | |
| 27872 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 386 | |
| 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 387 | |
| 5826 | 388 | (* terms *) | 
| 389 | ||
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 390 | val const = group (fn () => "constant") (inner_syntax embedded); | 
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 391 | val term = group (fn () => "term") (inner_syntax embedded); | 
| 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 392 | val prop = group (fn () => "proposition") (inner_syntax embedded); | 
| 42300 
0d1cbc1fe579
notation: proper markup for type constructor / constant;
 wenzelm parents: 
42299diff
changeset | 393 | |
| 56499 
7e0178c84994
allow text cartouches in regular outer syntax categories "text" and "altstring";
 wenzelm parents: 
56202diff
changeset | 394 | 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 | 395 | |
| 5826 | 396 | |
| 6949 | 397 | (* patterns *) | 
| 6935 | 398 | |
| 6949 | 399 | val is_terms = Scan.repeat1 ($$$ "is" |-- term); | 
| 6935 | 400 | val is_props = Scan.repeat1 ($$$ "is" |-- prop); | 
| 401 | ||
| 19585 | 402 | val propp = prop -- Scan.optional ($$$ "(" |-- !!! (is_props --| $$$ ")")) [];
 | 
| 6949 | 403 | val termp = term -- Scan.optional ($$$ "(" |-- !!! (is_terms --| $$$ ")")) [];
 | 
| 6935 | 404 | |
| 405 | ||
| 59924 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 406 | (* target information *) | 
| 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 407 | |
| 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 408 | val private = position ($$$ "private") >> #2; | 
| 59990 
a81dc82ecba3
clarified keyword 'qualified' in accordance to a similar keyword from Haskell (despite unrelated Binding.qualified in Isabelle/ML);
 wenzelm parents: 
59939diff
changeset | 409 | val qualified = position ($$$ "qualified") >> #2; | 
| 19811 | 410 | |
| 62969 | 411 | val target = ($$$ "(" -- $$$ "in") |-- !!! (position name --| $$$ ")");
 | 
| 22119 | 412 | val opt_target = Scan.option target; | 
| 12272 | 413 | |
| 56201 | 414 | |
| 415 | (* arguments within outer syntax *) | |
| 416 | ||
| 417 | local | |
| 418 | ||
| 419 | val argument_kinds = | |
| 59081 | 420 | [Token.Ident, Token.Long_Ident, Token.Sym_Ident, Token.Var, Token.Type_Ident, Token.Type_Var, | 
| 421 | Token.Nat, Token.Float, Token.String, Token.Alt_String, Token.Cartouche, Token.Verbatim]; | |
| 56201 | 422 | |
| 423 | fun arguments is_symid = | |
| 424 | let | |
| 425 | fun argument blk = | |
| 426 | group (fn () => "argument") | |
| 427 | (Scan.one (fn tok => | |
| 428 | let val kind = Token.kind_of tok in | |
| 429 | member (op =) argument_kinds kind orelse | |
| 430 | Token.keyword_with is_symid tok orelse | |
| 431 | (blk andalso Token.keyword_with (fn s => s = ",") tok) | |
| 432 | end)); | |
| 433 | ||
| 434 | fun args blk x = Scan.optional (args1 blk) [] x | |
| 435 | and args1 blk x = | |
| 61476 | 436 |       (Scan.repeats1 (Scan.repeat1 (argument blk) || argsp "(" ")" || argsp "[" "]")) x
 | 
| 56201 | 437 | and argsp l r x = (token ($$$ l) ::: !!! (args true @@@ (token ($$$ r) >> single))) x; | 
| 438 | in (args, args1) end; | |
| 439 | ||
| 440 | in | |
| 441 | ||
| 442 | val args = #1 (arguments Token.ident_or_symbolic) false; | |
| 443 | fun args1 is_symid = #2 (arguments is_symid) false; | |
| 444 | ||
| 445 | end; | |
| 446 | ||
| 58028 
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 | (* attributes *) | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 449 | |
| 61814 
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
 wenzelm parents: 
61476diff
changeset | 450 | val attrib = token liberal_name ::: !!! args; | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 451 | val attribs = $$$ "[" |-- list attrib --| $$$ "]"; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 452 | val opt_attribs = Scan.optional attribs []; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 453 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 454 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 455 | (* theorem references *) | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 456 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 457 | val thm_sel = $$$ "(" |-- list1
 | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 458 | (nat --| minus -- nat >> Facts.FromTo || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 459 | nat --| minus >> Facts.From || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 460 | nat >> Facts.Single) --| $$$ ")"; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 461 | |
| 62969 | 462 | val thm = | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 463 | $$$ "[" |-- attribs --| $$$ "]" >> pair (Facts.named "") || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 464 | (literal_fact >> Facts.Fact || | 
| 62969 | 465 | position name -- Scan.option thm_sel >> Facts.Named) -- opt_attribs; | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 466 | |
| 62969 | 467 | val thms1 = Scan.repeat1 thm; | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 468 | |
| 12272 | 469 | end; |