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