# HG changeset patch # User wenzelm # Date 939162833 -7200 # Node ID e634168295388846ef2ff05d96259168f014845a # Parent dfb8beddbefedb3baffe53af0f3f104b5e9ce4b4 added markup_command; diff -r dfb8beddbefe -r e63416829538 src/Pure/Isar/outer_syntax.ML --- a/src/Pure/Isar/outer_syntax.ML Wed Oct 06 00:32:53 1999 +0200 +++ b/src/Pure/Isar/outer_syntax.ML Wed Oct 06 00:33:53 1999 +0200 @@ -42,6 +42,8 @@ type parser val command: string -> string -> string -> (token list -> (Toplevel.transition -> Toplevel.transition) * token list) -> parser + val markup_command: string -> string -> string -> + (token list -> (Toplevel.transition -> Toplevel.transition) * token list) -> parser val improper_command: string -> string -> string -> (token list -> (Toplevel.transition -> Toplevel.transition) * token list) -> parser val dest_keywords: unit -> string list @@ -59,6 +61,7 @@ structure OuterSyntax: OUTER_SYNTAX = struct +structure T = OuterLex; structure P = OuterParse; @@ -93,13 +96,14 @@ (* parsers *) -type token = OuterLex.token; +type token = T.token; type parser_fn = token list -> (Toplevel.transition -> Toplevel.transition) * token list; datatype parser = - Parser of string * (string * string) * bool * parser_fn; + Parser of string * (string * string * bool) * bool * parser_fn; -fun parser int_only name comment kind parse = Parser (name, (comment, kind), int_only, parse); +fun parser int_only markup name comment kind parse = + Parser (name, (comment, kind, markup), int_only, parse); (* parse command *) @@ -133,7 +137,9 @@ local val global_lexicons = ref (Scan.empty_lexicon, Scan.empty_lexicon); -val global_parsers = ref (Symtab.empty: ((string * string) * (bool * parser_fn)) Symtab.table); +val global_parsers = + ref (Symtab.empty: (((string * string) * (bool * parser_fn)) * bool) Symtab.table); +val global_markups = ref ([]: string list); fun change_lexicons f = let val lexs = f (! global_lexicons) in @@ -142,18 +148,24 @@ | bads => error ("Clash of outer syntax commands and keywords: " ^ commas_quote bads)) end; -fun change_parsers f = global_parsers := f (! global_parsers); +fun get_markup (names, (name, (_, true))) = name :: names + | get_markup (names, _) = names; + +fun make_markups () = global_markups := Symtab.foldl get_markup ([], ! global_parsers); +fun change_parsers f = (global_parsers := f (! global_parsers); make_markups ()); in -(* get current lexers / parsers *) + +(* get current syntax *) (*Note: the syntax for files is statically determined at the very beginning; for interactive processing it may change dynamically.*) fun get_lexicons () = ! global_lexicons; fun get_parsers () = ! global_parsers; -fun get_parser () = apsome snd o curry Symtab.lookup (! global_parsers); +fun get_parser () = apsome (#2 o #1) o curry Symtab.lookup (! global_parsers); +fun is_markup name = name mem_string ! global_markups; (* augment syntax *) @@ -161,10 +173,10 @@ fun add_keywords keywords = change_lexicons (apfst (fn lex => (Scan.extend_lexicon lex (map Symbol.explode keywords)))); -fun add_parser (tab, Parser (name, comment, int_only, parse)) = +fun add_parser (tab, Parser (name, (comment, kind, markup), int_only, parse)) = (if is_none (Symtab.lookup (tab, name)) then () else warning ("Redefined outer syntax command " ^ quote name); - Symtab.update ((name, (comment, (int_only, parse))), tab)); + Symtab.update ((name, (((comment, kind), (int_only, parse)), markup)), tab)); fun add_parsers parsers = (change_parsers (fn tab => foldl add_parser (tab, parsers)); @@ -179,7 +191,7 @@ fun dest_keywords () = Scan.dest_lexicon (#1 (get_lexicons ())); fun dest_parsers () = - map (fn (name, ((cmt, kind), (int_only, _))) => (name, cmt, kind, int_only)) + map (fn (name, (((cmt, kind), (int_only, _)), _)) => (name, cmt, kind, int_only)) (Symtab.dest (get_parsers ())); fun print_outer_syntax () = @@ -211,8 +223,8 @@ val headerN = "header"; val theoryN = "theory"; -val theory_keyword = OuterParse.$$$ theoryN; -val header_keyword = OuterParse.$$$ headerN; +val theory_keyword = P.$$$ theoryN; +val header_keyword = P.$$$ headerN; val semicolon = P.$$$ ";"; @@ -221,7 +233,7 @@ local val no_terminator = - Scan.unless semicolon (Scan.one (OuterLex.not_sync andf OuterLex.not_eof)); + Scan.unless semicolon (Scan.one (T.not_sync andf T.not_eof)); val recover = Scan.prompt "recover# " (Scan.repeat no_terminator); @@ -229,8 +241,8 @@ fun source term do_recover cmd src = src - |> Source.source OuterLex.stopper - (Scan.bulk (fn xs => OuterParse.!!! (command term (cmd ())) xs)) + |> Source.source T.stopper + (Scan.bulk (fn xs => P.!!! (command term (cmd ())) xs)) (if do_recover then Some recover else None) |> Source.mapfilter I; @@ -239,11 +251,11 @@ fun token_source (src, pos) = src |> Symbol.source false - |> OuterLex.source false (K (get_lexicons ())) pos; + |> T.source false (K (get_lexicons ())) pos; fun filter_proper src = src - |> Source.filter OuterLex.is_proper; + |> Source.filter T.is_proper; (* scan header *) @@ -251,9 +263,9 @@ fun scan_header get_lex scan (src, pos) = src |> Symbol.source false - |> OuterLex.source false (fn () => (get_lex (), Scan.empty_lexicon)) pos + |> T.source false (fn () => (get_lex (), Scan.empty_lexicon)) pos |> filter_proper - |> Source.source OuterLex.stopper (Scan.single scan) None + |> Source.source T.stopper (Scan.single scan) None |> (fst o the o Source.get_single); @@ -317,6 +329,35 @@ end; +(* present theory source *) + +local + +val scan_markup = + Scan.one T.not_eof :-- (fn tok => + if T.is_kind T.Command tok andalso is_markup (T.val_of tok) then + (Scan.any (not o T.is_proper) |-- P.text) >> Some + else Scan.succeed None); + +fun invisible_token (tok, arg) = + is_none arg andalso T.keyword_with (equal ";") tok orelse T.is_kind T.Comment tok; + +in + +(*note: lazy evaluation ahead*) + +fun present_toks text pos () = + token_source (Source.of_list (Library.untabify text), pos) + |> Source.source T.stopper (Scan.bulk scan_markup) None + |> Source.exhaust + |> filter_out invisible_token; + +fun present_text text () = + Source.exhaust (Symbol.source false (Source.of_list (Library.untabify text))); + +end; + + (* load_thy --- read text (including header) *) local @@ -343,16 +384,13 @@ val text = explode (File.read path); val src = Source.of_list text; val pos = Path.position path; - - fun present_toks () = - Source.exhaust (token_source (Source.of_list (Library.untabify text), pos)); - fun present_text () = - Source.exhaust (Symbol.source false (Source.of_list (Library.untabify text))); in Present.init_theory name; if is_old_theory (src, pos) then ThySyn.load_thy name text - else (Toplevel.excursion_error (parse_thy (src, pos)); Present.token_source name present_toks); - Present.verbatim_source name present_text + else + (Toplevel.excursion_error (parse_thy (src, pos)); + Present.token_source name (present_toks text pos)); + Present.verbatim_source name (present_text text) end; in @@ -375,7 +413,7 @@ fun isar term no_pos = Source.tty |> Symbol.source true - |> OuterLex.source true get_lexicons + |> T.source true get_lexicons (if no_pos then Position.none else Position.line_name 1 "stdin") |> filter_proper |> source term true get_parser; @@ -410,8 +448,9 @@ (*final declarations of this structure!*) -val command = parser false; -val improper_command = parser true; +val command = parser false false; +val markup_command = parser false true; +val improper_command = parser true false; end;