| author | wenzelm | 
| Mon, 01 Apr 2024 15:37:55 +0200 | |
| changeset 80064 | 0d94dd2fd2d0 | 
| parent 78819 | b8775a63cb35 | 
| 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 | 
| 78819 
b8775a63cb35
proper cut for Parse.enum1' and its derivatives (see also 769abc29bb8e);
 wenzelm parents: 
78818diff
changeset | 11 | val !!!! : (Context.generic * Token.src -> 'a) -> Context.generic * Token.src -> 'a | 
| 36959 
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 | 
| 67136 | 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 | 
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 31 | val string_position: (string * Position.T) parser | 
| 29310 | 32 | val alt_string: string parser | 
| 55033 | 33 | val cartouche: string parser | 
| 74373 
6e4093927dbb
outer syntax: support for control-cartouche tokens;
 wenzelm parents: 
73689diff
changeset | 34 | val control: Antiquote.control parser | 
| 29310 | 35 | val eof: string parser | 
| 67136 | 36 | val command_name: string -> string parser | 
| 29310 | 37 | val keyword_with: (string -> bool) -> string parser | 
| 56202 | 38 | val keyword_markup: bool * Markup.T -> string -> string parser | 
| 39 | val keyword_improper: string -> string parser | |
| 29310 | 40 | val $$$ : string -> string parser | 
| 41 | val reserved: string -> string parser | |
| 42 | val underscore: string parser | |
| 43 | val maybe: 'a parser -> 'a option parser | |
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 44 |   val maybe_position: ('a * Position.T) parser -> ('a option * Position.T) parser
 | 
| 29310 | 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 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 64 | val name: string parser | 
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 65 | val name_range: (string * Position.range) parser | 
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 66 | val name_position: (string * Position.T) parser | 
| 29581 | 67 | val binding: binding parser | 
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 68 | val embedded: string parser | 
| 74563 | 69 | val embedded_inner_syntax: string parser | 
| 70205 | 70 | val embedded_input: Input.source parser | 
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 71 | val embedded_position: (string * Position.T) parser | 
| 72840 | 72 | val path_input: Input.source parser | 
| 48881 
46e053eda5dd
clarified Parse.path vs. Parse.explode -- prefer errors in proper transaction context;
 wenzelm parents: 
46922diff
changeset | 73 | val path: string parser | 
| 70047 
96fe857a7a6f
clarified signature: more explicit operations for corresponding Isar commands;
 wenzelm parents: 
69891diff
changeset | 74 | val path_binding: (string * Position.T) parser | 
| 76614 | 75 | val in_path: string -> Input.source parser | 
| 76 | val in_path_parens: string -> Input.source parser | |
| 75986 
27d98da31985
support 'chapter_definition' with description for presentation purposes;
 wenzelm parents: 
74887diff
changeset | 77 | val chapter_name: (string * Position.T) parser | 
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 78 | val session_name: (string * Position.T) parser | 
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 79 | val theory_name: (string * Position.T) parser | 
| 62969 | 80 | val liberal_name: string parser | 
| 29310 | 81 | val parname: string parser | 
| 29581 | 82 | val parbinding: binding parser | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 83 | val class: string parser | 
| 29310 | 84 | val sort: string parser | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 85 | val type_const: string parser | 
| 29310 | 86 | val arity: (string * string list * string) parser | 
| 87 | val multi_arity: (string list * string list * string) parser | |
| 88 | val type_args: string list parser | |
| 35838 | 89 | val type_args_constrained: (string * string option) list parser | 
| 29310 | 90 | val typ: string parser | 
| 91 | val mixfix: mixfix parser | |
| 92 | val mixfix': mixfix parser | |
| 93 | val opt_mixfix: mixfix parser | |
| 94 | val opt_mixfix': mixfix parser | |
| 62856 | 95 | val syntax_mode: Syntax.mode parser | 
| 29310 | 96 | val where_: string parser | 
| 42299 | 97 | val const_decl: (string * string * mixfix) parser | 
| 30339 | 98 | val const_binding: (binding * string * mixfix) parser | 
| 60448 | 99 | val params: (binding * string option * mixfix) list parser | 
| 63285 | 100 | val vars: (binding * string option * mixfix) list parser | 
| 29581 | 101 | val for_fixes: (binding * string option * mixfix) list parser | 
| 59064 | 102 | val ML_source: Input.source parser | 
| 103 | val document_source: Input.source parser | |
| 69891 
def3ec9cdb7e
document markers are formal comments, and may thus occur anywhere in the command-span;
 wenzelm parents: 
69876diff
changeset | 104 | val document_marker: Input.source parser | 
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 105 | val const: string parser | 
| 29310 | 106 | val term: string parser | 
| 107 | val prop: string parser | |
| 40793 
d21aedaa91e7
added Parse.literal_fact with proper inner_syntax markup (source position);
 wenzelm parents: 
40296diff
changeset | 108 | val literal_fact: string parser | 
| 29310 | 109 | val propp: (string * string list) parser | 
| 110 | val termp: (string * string list) parser | |
| 59924 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 111 | 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 | 112 | val qualified: Position.T parser | 
| 62969 | 113 | val target: (string * Position.T) parser | 
| 114 | val opt_target: (string * Position.T) option parser | |
| 56201 | 115 | val args: Token.T list parser | 
| 116 | val args1: (string -> bool) -> Token.T list parser | |
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 117 | val attribs: Token.src list parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 118 | val opt_attribs: Token.src list parser | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 119 | val thm_sel: Facts.interval list parser | 
| 62969 | 120 | val thm: (Facts.ref * Token.src list) parser | 
| 121 | val thms1: (Facts.ref * Token.src list) list parser | |
| 67215 | 122 | val options: ((string * Position.T) * (string * Position.T)) list parser | 
| 74562 | 123 | val embedded_ml: ML_Lex.token Antiquote.antiquote list parser | 
| 74564 | 124 | val read_antiq: Keyword.keywords -> 'a parser -> Symbol_Pos.T list * Position.T -> 'a | 
| 125 | val read_embedded: Proof.context -> Keyword.keywords -> 'a parser -> Input.source -> 'a | |
| 5826 | 126 | end; | 
| 127 | ||
| 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 | 128 | structure Parse: PARSE = | 
| 5826 | 129 | struct | 
| 130 | ||
| 131 | (** error handling **) | |
| 132 | ||
| 133 | (* group atomic parsers (no cuts!) *) | |
| 134 | ||
| 44357 | 135 | 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 | 136 | (fn [] => (fn () => s () ^ " expected,\nbut end-of-input was found") | 
| 42519 | 137 | | 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 | 138 | (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 | 139 | (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 | 140 | (txt, "") => | 
| 55708 | 141 | s () ^ " expected,\nbut " ^ txt ^ Position.here (Token.pos_of tok) ^ | 
| 142 | " 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 | 143 | | (txt1, txt2) => | 
| 55708 | 144 | s () ^ " expected,\nbut " ^ txt1 ^ Position.here (Token.pos_of tok) ^ | 
| 145 | " was found:\n" ^ txt2))); | |
| 5826 | 146 | |
| 147 | ||
| 5877 | 148 | (* cut *) | 
| 5826 | 149 | |
| 78819 
b8775a63cb35
proper cut for Parse.enum1' and its derivatives (see also 769abc29bb8e);
 wenzelm parents: 
78818diff
changeset | 150 | val err_prefix = "Outer syntax error"; | 
| 
b8775a63cb35
proper cut for Parse.enum1' and its derivatives (see also 769abc29bb8e);
 wenzelm parents: 
78818diff
changeset | 151 | |
| 
b8775a63cb35
proper cut for Parse.enum1' and its derivatives (see also 769abc29bb8e);
 wenzelm parents: 
78818diff
changeset | 152 | fun !!! scan = Scan.!!! err_prefix Token.input_position scan; | 
| 
b8775a63cb35
proper cut for Parse.enum1' and its derivatives (see also 769abc29bb8e);
 wenzelm parents: 
78818diff
changeset | 153 | fun !!!! scan = Scan.!!! err_prefix Token.context_input_position scan; | 
| 8581 
5c7ed2af8bfb
!!!! = cut "Corrupted outer syntax in presentation";
 wenzelm parents: 
8350diff
changeset | 154 | |
| 5826 | 155 | |
| 156 | ||
| 157 | (** basic parsers **) | |
| 158 | ||
| 159 | (* tokens *) | |
| 160 | ||
| 27815 | 161 | 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 | 162 | Scan.ahead (Scan.one (K true)) -- atom >> (fn (arg, x) => (Token.assign NONE arg; x)); | 
| 27815 | 163 | |
| 164 | ||
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 165 | val not_eof = RESET_VALUE (Scan.one Token.not_eof); | 
| 15703 | 166 | |
| 56201 | 167 | fun token atom = Scan.ahead not_eof --| atom; | 
| 168 | ||
| 59029 
c907cbe36713
more careful ML source positions, for improved PIDE markup;
 wenzelm parents: 
58908diff
changeset | 169 | fun range scan = (Scan.ahead not_eof >> (Token.range_of o single)) -- scan >> Library.swap; | 
| 55708 | 170 | fun position scan = (Scan.ahead not_eof >> Token.pos_of) -- scan >> Library.swap; | 
| 59809 | 171 | fun input atom = Scan.ahead atom |-- not_eof >> Token.input_of; | 
| 55111 | 172 | fun inner_syntax atom = Scan.ahead atom |-- not_eof >> Token.inner_syntax_of; | 
| 5826 | 173 | |
| 174 | fun kind k = | |
| 44357 | 175 | group (fn () => Token.str_of_kind k) | 
| 176 | (RESET_VALUE (Scan.one (Token.is_kind k) >> Token.content_of)); | |
| 5826 | 177 | |
| 67136 | 178 | 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 | 179 | 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 | 180 | val short_ident = kind Token.Ident; | 
| 59081 | 181 | val long_ident = kind Token.Long_Ident; | 
| 182 | 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 | 183 | val term_var = kind Token.Var; | 
| 59081 | 184 | val type_ident = kind Token.Type_Ident; | 
| 185 | 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 | 186 | val number = kind Token.Nat; | 
| 40290 
47f572aff50a
support for floating-point tokens in outer syntax (coinciding with inner syntax version);
 wenzelm parents: 
36959diff
changeset | 187 | 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 | 188 | val string = kind Token.String; | 
| 59081 | 189 | val alt_string = kind Token.Alt_String; | 
| 55033 | 190 | val cartouche = kind Token.Cartouche; | 
| 74373 
6e4093927dbb
outer syntax: support for control-cartouche tokens;
 wenzelm parents: 
73689diff
changeset | 191 | val control = token (kind Token.control_kind) >> (the o Token.get_control); | 
| 36959 
f5417836dbea
renamed structure OuterLex to Token and type token to Token.T, keeping legacy aliases for some time;
 wenzelm parents: 
36955diff
changeset | 192 | val eof = kind Token.EOF; | 
| 5826 | 193 | |
| 67136 | 194 | fun command_name x = | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 195 | group (fn () => Token.str_of_kind Token.Command ^ " " ^ quote x) | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 196 | (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 | 197 | >> Token.content_of; | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48911diff
changeset | 198 | |
| 56202 | 199 | fun keyword_with pred = RESET_VALUE (Scan.one (Token.keyword_with pred) >> Token.content_of); | 
| 200 | ||
| 201 | fun keyword_markup markup x = | |
| 44357 | 202 | group (fn () => Token.str_of_kind Token.Keyword ^ " " ^ quote x) | 
| 56063 | 203 | (Scan.ahead not_eof -- keyword_with (fn y => x = y)) | 
| 56202 | 204 | >> (fn (tok, x) => (Token.assign (SOME (Token.Literal markup)) tok; x)); | 
| 205 | ||
| 206 | val keyword_improper = keyword_markup (true, Markup.improper); | |
| 207 | val $$$ = keyword_markup (false, Markup.quasi_keyword); | |
| 9131 | 208 | |
| 16030 | 209 | fun reserved x = | 
| 44357 | 210 | 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 | 211 | (RESET_VALUE (Scan.one (Token.ident_with (fn y => x = y)) >> Token.content_of)); | 
| 16030 | 212 | |
| 62529 
8b7bdfc09f3b
clarified treatment of fragments of Isabelle symbols during bootstrap;
 wenzelm parents: 
61814diff
changeset | 213 | val dots = sym_ident :-- (fn "\<dots>" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 60629 | 214 | |
| 15703 | 215 | val minus = sym_ident :-- (fn "-" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 60629 | 216 | |
| 11792 
311eee3d63b6
parser for underscore (actually a symbolic identifier!);
 wenzelm parents: 
11651diff
changeset | 217 | val underscore = sym_ident :-- (fn "_" => Scan.succeed () | _ => Scan.fail) >> #1; | 
| 15703 | 218 | fun maybe scan = underscore >> K NONE || scan >> SOME; | 
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 219 | fun maybe_position scan = position (underscore >> K NONE) || scan >> apfst SOME; | 
| 11792 
311eee3d63b6
parser for underscore (actually a symbolic identifier!);
 wenzelm parents: 
11651diff
changeset | 220 | |
| 14835 | 221 | val nat = number >> (#1 o Library.read_int o Symbol.explode); | 
| 27815 | 222 | val int = Scan.optional (minus >> K ~1) 1 -- nat >> op *; | 
| 63806 | 223 | val real = float_number >> Value.parse_real || int >> Real.fromInt; | 
| 5826 | 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 | ||
| 78819 
b8775a63cb35
proper cut for Parse.enum1' and its derivatives (see also 769abc29bb8e);
 wenzelm parents: 
78818diff
changeset | 243 | fun enum1' sep scan = scan ::: Scan.repeat (Scan.lift ($$$ sep) |-- !!!! scan); | 
| 27815 | 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 | ||
| 5826 | 255 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 256 | (* names and embedded content *) | 
| 5826 | 257 | |
| 62969 | 258 | val name = | 
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 259 | group (fn () => "name") | 
| 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 260 | (short_ident || long_ident || sym_ident || number || string); | 
| 44357 | 261 | |
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 262 | val name_range = input name >> Input.source_content_range; | 
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 263 | val name_position = input name >> Input.source_content; | 
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 264 | |
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 265 | val string_position = input string >> Input.source_content; | 
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 266 | |
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 267 | val binding = name_position >> Binding.make; | 
| 44357 | 268 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 269 | val embedded = | 
| 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 270 | group (fn () => "embedded content") | 
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 271 | (cartouche || string || short_ident || long_ident || sym_ident || | 
| 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 272 | term_var || type_ident || type_var || number); | 
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 273 | |
| 74563 | 274 | val embedded_inner_syntax = inner_syntax embedded; | 
| 70205 | 275 | val embedded_input = input embedded; | 
| 276 | val embedded_position = embedded_input >> Input.source_content; | |
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 277 | |
| 72840 | 278 | val path_input = group (fn () => "file name/path specification") embedded_input; | 
| 279 | val path = path_input >> Input.string_of; | |
| 70047 
96fe857a7a6f
clarified signature: more explicit operations for corresponding Isar commands;
 wenzelm parents: 
69891diff
changeset | 280 | val path_binding = group (fn () => "path binding (strict file name)") (position embedded); | 
| 6553 | 281 | |
| 76614 | 282 | fun in_path default = | 
| 283 | Scan.optional ($$$ "in" |-- !!! path_input) (Input.string default); | |
| 284 | ||
| 285 | fun in_path_parens default = | |
| 286 |   Scan.optional ($$$ "(" |-- !!! ($$$ "in" |-- path_input --| $$$ ")")) (Input.string default);
 | |
| 287 | ||
| 75986 
27d98da31985
support 'chapter_definition' with description for presentation purposes;
 wenzelm parents: 
74887diff
changeset | 288 | val chapter_name = group (fn () => "chapter name") name_position; | 
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 289 | val session_name = group (fn () => "session name") name_position; | 
| 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 290 | val theory_name = group (fn () => "theory name") name_position; | 
| 59693 | 291 | |
| 62969 | 292 | val liberal_name = keyword_with Token.ident_or_symbolic || name; | 
| 40800 
330eb65c9469
Parse.liberal_name for document antiquotations and attributes;
 wenzelm parents: 
40793diff
changeset | 293 | |
| 18898 | 294 | val parname = Scan.optional ($$$ "(" |-- name --| $$$ ")") "";
 | 
| 28965 | 295 | val parbinding = Scan.optional ($$$ "(" |-- binding --| $$$ ")") Binding.empty;
 | 
| 18898 | 296 | |
| 6553 | 297 | |
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 298 | (* type classes *) | 
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 299 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 300 | val class = group (fn () => "type class") (inner_syntax embedded); | 
| 5826 | 301 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 302 | val sort = group (fn () => "sort") (inner_syntax embedded); | 
| 5826 | 303 | |
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 304 | val type_const = group (fn () => "type constructor") (inner_syntax embedded); | 
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 305 | |
| 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 306 | val arity = type_const -- ($$$ "::" |-- !!! | 
| 61466 | 307 |   (Scan.optional ($$$ "(" |-- !!! (list1 sort --| $$$ ")")) [] -- sort)) >> Scan.triple2;
 | 
| 5826 | 308 | |
| 46922 
3717f3878714
source positions for locale and class expressions;
 wenzelm parents: 
45596diff
changeset | 309 | val multi_arity = and_list1 type_const -- ($$$ "::" |-- !!! | 
| 61466 | 310 |   (Scan.optional ($$$ "(" |-- !!! (list1 sort --| $$$ ")")) [] -- sort)) >> Scan.triple2;
 | 
| 25541 | 311 | |
| 5826 | 312 | |
| 313 | (* types *) | |
| 314 | ||
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 315 | 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 | 316 | |
| 35838 | 317 | fun type_arguments arg = | 
| 318 | arg >> single || | |
| 319 |   $$$ "(" |-- !!! (list1 arg --| $$$ ")") ||
 | |
| 5826 | 320 | Scan.succeed []; | 
| 321 | ||
| 35838 | 322 | val type_args = type_arguments type_ident; | 
| 323 | val type_args_constrained = type_arguments (type_ident -- Scan.option ($$$ "::" |-- !!! sort)); | |
| 324 | ||
| 5826 | 325 | |
| 326 | (* mixfix annotations *) | |
| 327 | ||
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 328 | local | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 329 | |
| 69580 | 330 | val mfix = input (string || cartouche); | 
| 62752 | 331 | |
| 69579 | 332 | val mixfix_ = | 
| 333 | mfix -- !!! (Scan.optional ($$$ "[" |-- !!! (list nat --| $$$ "]")) [] -- Scan.optional nat 1000) | |
| 334 | >> (fn (sy, (ps, p)) => fn range => Mixfix (sy, ps, p, range)); | |
| 18669 | 335 | |
| 69579 | 336 | val structure_ = $$$ "structure" >> K Structure; | 
| 62752 | 337 | |
| 69579 | 338 | val binder_ = | 
| 339 | $$$ "binder" |-- !!! (mfix -- ($$$ "[" |-- nat --| $$$ "]" -- nat || nat >> (fn n => (n, n)))) | |
| 340 | >> (fn (sy, (p, q)) => fn range => Binder (sy, p, q, range)); | |
| 62752 | 341 | |
| 69579 | 342 | val infixl_ = $$$ "infixl" |-- !!! (mfix -- nat >> (fn (sy, p) => fn range => Infixl (sy, p, range))); | 
| 343 | val infixr_ = $$$ "infixr" |-- !!! (mfix -- nat >> (fn (sy, p) => fn range => Infixr (sy, p, range))); | |
| 344 | val infix_ = $$$ "infix" |-- !!! (mfix -- nat >> (fn (sy, p) => fn range => Infix (sy, p, range))); | |
| 18669 | 345 | |
| 69579 | 346 | val mixfix_body = mixfix_ || structure_ || binder_ || infixl_ || infixr_ || infix_; | 
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 347 | |
| 62752 | 348 | fun annotation guard body = | 
| 349 |   Scan.trace ($$$ "(" |-- guard (body --| $$$ ")"))
 | |
| 62760 | 350 | >> (fn (mx, toks) => mx (Token.range_of toks)); | 
| 62752 | 351 | |
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 352 | 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 | 353 | |
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 354 | in | 
| 18669 | 355 | |
| 51654 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 356 | val mixfix = annotation !!! mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 357 | val mixfix' = annotation I mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 358 | val opt_mixfix = opt_annotation !!! mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 359 | val opt_mixfix' = opt_annotation I mixfix_body; | 
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 360 | |
| 
8450b944e58a
just one syntax category "mixfix" -- check structure annotation semantically;
 wenzelm parents: 
51627diff
changeset | 361 | end; | 
| 5826 | 362 | |
| 363 | ||
| 62856 | 364 | (* syntax mode *) | 
| 365 | ||
| 366 | val syntax_mode_spec = | |
| 367 |   ($$$ "output" >> K ("", false)) || name -- Scan.optional ($$$ "output" >> K false) true;
 | |
| 368 | ||
| 369 | val syntax_mode = | |
| 370 |   Scan.optional ($$$ "(" |-- !!! (syntax_mode_spec --| $$$ ")")) Syntax.mode_default;
 | |
| 371 | ||
| 372 | ||
| 18669 | 373 | (* fixes *) | 
| 5826 | 374 | |
| 21400 | 375 | val where_ = $$$ "where"; | 
| 376 | ||
| 61466 | 377 | val const_decl = name -- ($$$ "::" |-- !!! typ) -- opt_mixfix >> Scan.triple1; | 
| 378 | val const_binding = binding -- ($$$ "::" |-- !!! typ) -- opt_mixfix >> Scan.triple1; | |
| 18669 | 379 | |
| 61466 | 380 | val param_mixfix = binding -- Scan.option ($$$ "::" |-- typ) -- mixfix' >> (single o Scan.triple1); | 
| 63230 | 381 | |
| 60448 | 382 | val params = | 
| 63230 | 383 | (binding -- Scan.repeat binding) -- Scan.option ($$$ "::" |-- !!! (Scan.ahead typ -- embedded)) | 
| 384 | >> (fn ((x, ys), T) => | |
| 385 | (x, Option.map #1 T, NoSyn) :: map (fn y => (y, Option.map #2 T, NoSyn)) ys); | |
| 18669 | 386 | |
| 63285 | 387 | val vars = and_list1 (param_mixfix || params) >> flat; | 
| 388 | ||
| 389 | val for_fixes = Scan.optional ($$$ "for" |-- !!! vars) []; | |
| 19845 | 390 | |
| 5826 | 391 | |
| 27877 | 392 | (* embedded source text *) | 
| 27872 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 393 | |
| 74887 | 394 | val ML_source = input (group (fn () => "ML source") embedded); | 
| 395 | val document_source = input (group (fn () => "document source") embedded); | |
| 27872 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 396 | |
| 69891 
def3ec9cdb7e
document markers are formal comments, and may thus occur anywhere in the command-span;
 wenzelm parents: 
69876diff
changeset | 397 | val document_marker = | 
| 
def3ec9cdb7e
document markers are formal comments, and may thus occur anywhere in the command-span;
 wenzelm parents: 
69876diff
changeset | 398 | group (fn () => "document marker") | 
| 
def3ec9cdb7e
document markers are formal comments, and may thus occur anywhere in the command-span;
 wenzelm parents: 
69876diff
changeset | 399 | (RESET_VALUE (Scan.one Token.is_document_marker >> Token.input_of)); | 
| 
def3ec9cdb7e
document markers are formal comments, and may thus occur anywhere in the command-span;
 wenzelm parents: 
69876diff
changeset | 400 | |
| 27872 
631371a02b8c
P.doc_source and P.ml_sorce for proper SymbolPos.text;
 wenzelm parents: 
27815diff
changeset | 401 | |
| 5826 | 402 | (* terms *) | 
| 403 | ||
| 63120 
629a4c5e953e
embedded content may be delimited via cartouches;
 wenzelm parents: 
62969diff
changeset | 404 | val const = group (fn () => "constant") (inner_syntax embedded); | 
| 63137 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 405 | val term = group (fn () => "term") (inner_syntax embedded); | 
| 
9553f11d67c4
simplified syntax: Parse.term corresponds to Args.term etc.;
 wenzelm parents: 
63120diff
changeset | 406 | val prop = group (fn () => "proposition") (inner_syntax embedded); | 
| 42300 
0d1cbc1fe579
notation: proper markup for type constructor / constant;
 wenzelm parents: 
42299diff
changeset | 407 | |
| 56499 
7e0178c84994
allow text cartouches in regular outer syntax categories "text" and "altstring";
 wenzelm parents: 
56202diff
changeset | 408 | 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 | 409 | |
| 5826 | 410 | |
| 6949 | 411 | (* patterns *) | 
| 6935 | 412 | |
| 6949 | 413 | val is_terms = Scan.repeat1 ($$$ "is" |-- term); | 
| 6935 | 414 | val is_props = Scan.repeat1 ($$$ "is" |-- prop); | 
| 415 | ||
| 19585 | 416 | val propp = prop -- Scan.optional ($$$ "(" |-- !!! (is_props --| $$$ ")")) [];
 | 
| 6949 | 417 | val termp = term -- Scan.optional ($$$ "(" |-- !!! (is_terms --| $$$ ")")) [];
 | 
| 6935 | 418 | |
| 419 | ||
| 59924 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 420 | (* target information *) | 
| 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 421 | |
| 
801b979ec0c2
more general notion of command span: command keyword not necessarily at start;
 wenzelm parents: 
59918diff
changeset | 422 | 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 | 423 | val qualified = position ($$$ "qualified") >> #2; | 
| 19811 | 424 | |
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 425 | val target = ($$$ "(" -- $$$ "in") |-- !!! (name_position --| $$$ ")");
 | 
| 22119 | 426 | val opt_target = Scan.option target; | 
| 12272 | 427 | |
| 56201 | 428 | |
| 429 | (* arguments within outer syntax *) | |
| 430 | ||
| 431 | local | |
| 432 | ||
| 433 | val argument_kinds = | |
| 59081 | 434 | [Token.Ident, Token.Long_Ident, Token.Sym_Ident, Token.Var, Token.Type_Ident, Token.Type_Var, | 
| 74887 | 435 | Token.Nat, Token.Float, Token.String, Token.Alt_String, Token.Cartouche]; | 
| 56201 | 436 | |
| 437 | fun arguments is_symid = | |
| 438 | let | |
| 439 | fun argument blk = | |
| 440 | group (fn () => "argument") | |
| 441 | (Scan.one (fn tok => | |
| 442 | let val kind = Token.kind_of tok in | |
| 443 | member (op =) argument_kinds kind orelse | |
| 444 | Token.keyword_with is_symid tok orelse | |
| 445 | (blk andalso Token.keyword_with (fn s => s = ",") tok) | |
| 446 | end)); | |
| 447 | ||
| 448 | fun args blk x = Scan.optional (args1 blk) [] x | |
| 449 | and args1 blk x = | |
| 61476 | 450 |       (Scan.repeats1 (Scan.repeat1 (argument blk) || argsp "(" ")" || argsp "[" "]")) x
 | 
| 56201 | 451 | and argsp l r x = (token ($$$ l) ::: !!! (args true @@@ (token ($$$ r) >> single))) x; | 
| 452 | in (args, args1) end; | |
| 453 | ||
| 454 | in | |
| 455 | ||
| 456 | val args = #1 (arguments Token.ident_or_symbolic) false; | |
| 457 | fun args1 is_symid = #2 (arguments is_symid) false; | |
| 458 | ||
| 459 | end; | |
| 460 | ||
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 461 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 462 | (* attributes *) | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 463 | |
| 61814 
1ca1142e1711
clarified type Token.src: plain token list, with usual implicit value assignment;
 wenzelm parents: 
61476diff
changeset | 464 | val attrib = token liberal_name ::: !!! args; | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 465 | val attribs = $$$ "[" |-- list attrib --| $$$ "]"; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 466 | val opt_attribs = Scan.optional attribs []; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 467 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 468 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 469 | (* theorem references *) | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 470 | |
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 471 | val thm_sel = $$$ "(" |-- list1
 | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 472 | (nat --| minus -- nat >> Facts.FromTo || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 473 | nat --| minus >> Facts.From || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 474 | nat >> Facts.Single) --| $$$ ")"; | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 475 | |
| 62969 | 476 | val thm = | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 477 | $$$ "[" |-- attribs --| $$$ "]" >> pair (Facts.named "") || | 
| 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 478 | (literal_fact >> Facts.Fact || | 
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 479 | name_position -- Scan.option thm_sel >> Facts.Named) -- opt_attribs; | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 480 | |
| 62969 | 481 | val thms1 = Scan.repeat1 thm; | 
| 58028 
e4250d370657
tuned signature -- define some elementary operations earlier;
 wenzelm parents: 
58011diff
changeset | 482 | |
| 67215 | 483 | |
| 484 | (* options *) | |
| 485 | ||
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 486 | val option_name = group (fn () => "option name") name_position; | 
| 67215 | 487 | val option_value = group (fn () => "option value") ((token real || token name) >> Token.content_of); | 
| 488 | ||
| 489 | val option = | |
| 69349 
7cef9e386ffe
more accurate positions for "name" (quoted string) and "embedded" (cartouche): refer to content without delimiters, which is e.g. relevant for systematic selection/renaming of scope groups;
 wenzelm parents: 
67215diff
changeset | 490 | option_name :-- (fn (_, pos) => | 
| 67215 | 491 |     Scan.optional ($$$ "=" |-- !!! (position option_value)) ("true", pos));
 | 
| 492 | ||
| 493 | val options = $$$ "[" |-- list1 option --| $$$ "]"; | |
| 494 | ||
| 74562 | 495 | |
| 496 | (* embedded ML *) | |
| 497 | ||
| 498 | val embedded_ml = | |
| 74879 
89c7f74b5ae1
clarified Parse.embedded_ml: follow documentation (8baf2e8b16e2);
 wenzelm parents: 
74567diff
changeset | 499 | input underscore >> ML_Lex.read_source || | 
| 74562 | 500 | embedded_input >> ML_Lex.read_source || | 
| 501 | control >> (ML_Lex.read_symbols o Antiquote.control_symbols); | |
| 502 | ||
| 74564 | 503 | |
| 504 | (* read embedded source, e.g. for antiquotations *) | |
| 505 | ||
| 74565 | 506 | fun tokenize keywords = Token.tokenize keywords {strict = true} #> filter Token.is_proper;
 | 
| 507 | ||
| 74564 | 508 | fun read_antiq keywords scan (syms, pos) = | 
| 74567 | 509 | (case Scan.read Token.stopper scan (tokenize (Keyword.no_major_keywords keywords) syms) of | 
| 74565 | 510 | SOME res => res | 
| 511 |   | NONE => error ("Malformed antiquotation" ^ Position.here pos));
 | |
| 74564 | 512 | |
| 513 | fun read_embedded ctxt keywords parse input = | |
| 514 | let | |
| 74565 | 515 | val toks = tokenize keywords (Input.source_explode input); | 
| 74564 | 516 | val _ = Context_Position.reports_text ctxt (maps (Token.reports keywords) toks); | 
| 517 | in | |
| 518 | (case Scan.read Token.stopper parse toks of | |
| 519 | SOME res => res | |
| 520 |     | NONE => error ("Bad input" ^ Position.here (Input.pos_of input)))
 | |
| 521 | end; | |
| 522 | ||
| 12272 | 523 | end; |