(* Title: Pure/Isar/parse.ML Author: Markus Wenzel, TU Muenchen
Generic parsers for Isabelle/Isar outer syntax.
*)
signature PARSE = sig val group: (unit -> string) -> (Token.T list -> 'a) -> Token.T list -> 'a val !!! : (Token.T list -> 'a) -> Token.T list -> 'a val !!!! : (Context.generic * Token.src -> 'a) -> Context.generic * Token.src -> 'a val not_eof: Token.T parser val token: 'a parser -> Token.T parser val range: 'a parser -> ('a * Position.range) parser val position: 'a parser -> ('a * Position.T) parser val input: 'a parser -> Input.source parser val inner_syntax: 'a parser -> string parser val command: string parser val keyword: string parser val short_ident: string parser val long_ident: string parser val sym_ident: string parser val dots: string parser val minus: string parser val term_var: string parser val type_ident: string parser val type_var: string parser val number: string parser val float_number: string parser valstring: string parser val string_position: (string * Position.T) parser val alt_string: string parser val cartouche: string parser val control: Antiquote.control parser val eof: string parser val command_name: string -> string parser val keyword_with: (string -> bool) -> string parser val keyword_markup: bool * Markup.T -> string -> string parser val keyword_improper: string -> string parser val $$$ : string -> string parser val reserved: string -> string parser val underscore: string parser val maybe: 'a parser -> 'a option parser val maybe_position: ('a * Position.T) parser -> ('a option * Position.T) parser val opt_keyword: string -> bool parser val opt_bang: bool parser valbegin: string parser val opt_begin: bool parser val nat: int parser val int: int parser val real: real parser val enum_positions: string -> 'a parser -> ('a list * Position.T list) parser val enum1_positions: string -> 'a parser -> ('a list * Position.T list) parser val enum: string -> 'a parser -> 'a list parser val enum1: string -> 'a parser -> 'a list parser val and_list: 'a parser -> 'a list parser val and_list1: 'a parser -> 'a list parser val enum': string -> 'a context_parser -> 'a list context_parser val enum1': string -> 'a context_parser -> 'a list context_parser val and_list': 'a context_parser -> 'a list context_parser val and_list1': 'a context_parser -> 'a list context_parser vallist: 'a parser -> 'a list parser val list1: 'a parser -> 'a list parser val name: string parser val name_range: (string * Position.range) parser val name_position: (string * Position.T) parser val binding: binding parser val embedded: string parser val embedded_inner_syntax: string parser val embedded_input: Input.source parser val embedded_position: (string * Position.T) parser val path_input: Input.source parser val path: string parser val path_binding: (string * Position.T) parser val in_path: string -> Input.source parser val in_path_parens: string -> Input.source parser val chapter_name: (string * Position.T) parser val session_name: (string * Position.T) parser val theory_name: (string * Position.T) parser val liberal_name: string parser val parname: string parser val parbinding: binding parser val class: string parser val sort: string parser val type_const: string parser val arity: (string * stringlist * string) parser val multi_arity: (stringlist * stringlist * string) parser val type_args: stringlist parser val type_args_constrained: (string * stringoption) list parser val typ: string parser val mixfix: mixfix parser val mixfix': mixfix parser val opt_mixfix: mixfix parser val opt_mixfix': mixfix parser val syntax_mode: Syntax.mode parser val where_: string parser val const_decl: (string * string * mixfix) parser val const_binding: (binding * string * mixfix) parser val params: (binding * stringoption * mixfix) list parser val vars: (binding * stringoption * mixfix) list parser val for_fixes: (binding * stringoption * mixfix) list parser val ML_source: Input.source parser val document_source: Input.source parser val document_marker: Input.source parser valconst: string parser val term: string parser val prop: string parser val literal_fact: string parser val propp: (string * stringlist) parser val termp: (string * stringlist) parser val private: Position.T parser val qualified: Position.T parser val target: (string * Position.T) parser val opt_target: (string * Position.T) option parser val args: Token.T list parser val args1: (string -> bool) -> Token.T list parser val attribs: Token.src list parser val opt_attribs: Token.src list parser val thm_sel: Facts.interval list parser val thm: (Facts.ref * Token.src list) parser val thms1: (Facts.ref * Token.src list) list parser val options: ((string * Position.T) * (string * Position.T)) list parser val embedded_ml: ML_Lex.token Antiquote.antiquote list parser val read_antiq: Keyword.keywords -> 'a parser -> Symbol_Pos.T list * Position.T -> 'a val read_embedded: Proof.context -> Keyword.keywords -> 'a parser -> Input.source -> 'a end;
structure Parse: PARSE = struct
(** error handling **)
(* group atomic parsers (no cuts!) *)
fun group s scan = scan || Scan.fail_with
(fn [] => (fn () => s () ^ " expected,\nbut end-of-input was found")
| tok :: _ =>
(fn () =>
(case Token.text_of tok of
(txt, "") =>
s () ^ " expected,\nbut " ^ txt ^ Position.here (Token.pos_of tok) ^ " was found"
| (txt1, txt2) =>
s () ^ " expected,\nbut " ^ txt1 ^ Position.here (Token.pos_of tok) ^ " was found:\n" ^ txt2)));
(* cut *)
val err_prefix = "Outer syntax error";
fun !!! scan = Scan.!!! err_prefix Token.input_position scan; fun !!!! scan = Scan.!!! err_prefix Token.context_input_position scan;
(** basic parsers **)
(* tokens *)
fun RESET_VALUE atom = (*required for all primitive parsers*)
Scan.ahead (Scan.one (K true)) -- atom >> (fn (arg, x) => (Token.assign NONE arg; x));
val not_eof = RESET_VALUE (Scan.one Token.not_eof);
fun token atom = Scan.ahead not_eof --| atom;
fun range scan = (Scan.ahead not_eof >> (Token.range_of o single)) -- scan >> Library.swap; fun position scan = (Scan.ahead not_eof >> Token.pos_of) -- scan >> Library.swap; fun input atom = Scan.ahead atom |-- not_eof >> Token.input_of; fun inner_syntax atom = Scan.ahead atom |-- not_eof >> Token.inner_syntax_of;
fun kind k =
group (fn () => Token.str_of_kind k)
(RESET_VALUE (Scan.one (Token.is_kind k) >> Token.content_of));
val command = kind Token.Command; val keyword = kind Token.Keyword; val short_ident = kind Token.Ident; val long_ident = kind Token.Long_Ident; val sym_ident = kind Token.Sym_Ident; val term_var = kind Token.Var; val type_ident = kind Token.Type_Ident; val type_var = kind Token.Type_Var; val number = kind Token.Nat; val float_number = kind Token.Float; valstring = kind Token.String; val alt_string = kind Token.Alt_String; val cartouche = kind Token.Cartouche; val control = token (kind Token.control_kind) >> (the o Token.get_control); val eof = kind Token.EOF;
fun command_name x =
group (fn () => Token.str_of_kind Token.Command ^ " " ^ quote x)
(RESET_VALUE (Scan.one (fn tok => Token.is_command tok andalso Token.content_of tok = x)))
>> Token.content_of;
fun keyword_with pred = RESET_VALUE (Scan.one (Token.keyword_with pred) >> Token.content_of);
fun keyword_markup markup x =
group (fn () => Token.str_of_kind Token.Keyword ^ " " ^ quote x)
(Scan.ahead not_eof -- keyword_with (fn y => x = y))
>> (fn (tok, x) => (Token.assign (SOME (Token.Literal markup)) tok; x));
val keyword_improper = keyword_markup (true, Markup.improper); val $$$ = keyword_markup (false, Markup.quasi_keyword);
fun reserved x =
group (fn () => "reserved identifier " ^ quote x)
(RESET_VALUE (Scan.one (Token.ident_with (fn y => x = y)) >> Token.content_of));
val minus = sym_ident :-- (fn "-" => Scan.succeed () | _ => Scan.fail) >> #1;
val underscore = sym_ident :-- (fn "_" => Scan.succeed () | _ => Scan.fail) >> #1; fun maybe scan = underscore >> K NONE || scan >> SOME; fun maybe_position scan = position (underscore >> K NONE) || scan >> apfst SOME;
val nat = number >> (#1 o Library.read_int o Symbol.explode); val int = Scan.optional (minus >> K ~1) 1 -- nat >> op *; val real = float_number >> Value.parse_real || int >> Real.fromInt;
fun opt_keyword s = Scan.optional ($$$ "(" |-- !!! (($$$ s >> K true) --| $$$ ")")) false; val opt_bang = Scan.optional ($$$ "!" >> K true) false;
valbegin = $$$ "begin"; val opt_begin = Scan.optional (begin >> K true) false;
val chapter_name = group (fn () => "chapter name") name_position; val session_name = group (fn () => "session name") name_position; val theory_name = group (fn () => "theory name") name_position;
val liberal_name = keyword_with Token.ident_or_symbolic || name;
val parname = Scan.optional ($$$ "(" |-- name --| $$$ ")") ""; val parbinding = Scan.optional ($$$ "(" |-- binding --| $$$ ")") Binding.empty;
(* type classes *)
val class = group (fn () => "type class") (inner_syntax embedded);
val sort = group (fn () => "sort") (inner_syntax embedded);
val type_const = group (fn () => "type constructor") (inner_syntax embedded);
fun opt_annotation guard body = Scan.optional (annotation guard body) NoSyn;
in
val mixfix = annotation !!! mixfix_body; val mixfix' = annotation I mixfix_body; val opt_mixfix = opt_annotation !!! mixfix_body; val opt_mixfix' = opt_annotation I mixfix_body;
end;
(* syntax mode *)
val syntax_mode_spec =
($$$ "output" >> K ("", false)) || name -- Scan.optional ($$$ "output" >> K false) true;
val document_marker =
group (fn () => "document marker")
(RESET_VALUE (Scan.one Token.is_document_marker >> Token.input_of));
(* terms *)
valconst = group (fn () => "constant") (inner_syntax embedded); val term = group (fn () => "term") (inner_syntax embedded); val prop = group (fn () => "proposition") (inner_syntax embedded);
fun arguments is_symid = let fun argument blk =
group (fn () => "argument")
(Scan.one (fn tok => letval kind = Token.kind_of tok in
member (op =) argument_kinds kind orelse
Token.keyword_with is_symid tok orelse
(blk andalso Token.keyword_with (fn s => s = ",") tok) end));
fun args blk x = Scan.optional (args1 blk) [] x and args1 blk x =
(Scan.repeats1 (Scan.repeat1 (argument blk) || argsp "("")" || argsp "[""]")) x and argsp l r x = (token ($$$ l) ::: !!! (args true @@@ (token ($$$ r) >> single))) x; in (args, args1) end;
in
val args = #1 (arguments Token.ident_or_symbolic) false; fun args1 is_symid = #2 (arguments is_symid) false;
end;
(* attributes *)
val attrib = token liberal_name ::: !!! args; val attribs = $$$ "[" |-- list attrib --| $$$ "]"; val opt_attribs = Scan.optional attribs [];
(* theorem references *)
val thm_sel = $$$ "(" |-- list1
(nat --| minus -- nat >> Facts.FromTo ||
nat --| minus >> Facts.From ||
nat >> Facts.Single) --| $$$ ")";
fun read_antiq keywords scan (syms, pos) =
(case Scan.read Token.stopper scan (tokenize (Keyword.no_major_keywords keywords) syms) of
SOME res => res
| NONE => error ("Malformed antiquotation" ^ Position.here pos));
fun read_embedded ctxt keywords parse input = let val toks = tokenize keywords (Input.source_explode input); val _ = Context_Position.reports_text ctxt (maps (Token.reports keywords) toks); in
(case Scan.read Token.stopper parse toks of
SOME res => res
| NONE => error ("Bad input" ^ Position.here (Input.pos_of input))) end;
end;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.