src/Pure/ProofGeneral/pgip_parser.ML
author wenzelm
Thu May 27 18:10:37 2010 +0200 (2010-05-27)
changeset 37146 f652333bbf8e
parent 36950 75b8f26f2f07
child 37216 3165bc303f66
permissions -rw-r--r--
renamed structure PrintMode to Print_Mode, keeping the old name as legacy alias for some time;
wenzelm@23797
     1
(*  Title:      Pure/ProofGeneral/pgip_parser.ML
wenzelm@23797
     2
    Author:     David Aspinall and Makarius
wenzelm@23797
     3
wenzelm@23797
     4
Parsing theory sources without execution (via keyword classification).
wenzelm@23797
     5
*)
wenzelm@23797
     6
wenzelm@23797
     7
signature PGIP_PARSER =
wenzelm@23797
     8
sig
wenzelm@23797
     9
  val pgip_parser: Position.T -> string -> PgipMarkup.pgipdocument
wenzelm@23797
    10
end
wenzelm@23797
    11
wenzelm@23797
    12
structure PgipParser: PGIP_PARSER =
wenzelm@23797
    13
struct
wenzelm@23797
    14
wenzelm@23797
    15
structure D = PgipMarkup;
wenzelm@23797
    16
structure I = PgipIsabelle;
wenzelm@23797
    17
wenzelm@23797
    18
wenzelm@23797
    19
fun badcmd text = [D.Badcmd {text = text}];
wenzelm@23797
    20
wenzelm@23797
    21
fun thy_begin text =
wenzelm@32466
    22
  (case try (Thy_Header.read Position.none) (Source.of_string text) of
aspinall@24192
    23
    NONE => D.Opentheory {thyname = NONE, parentnames = [], text = text}
wenzelm@23797
    24
  | SOME (name, imports, _) =>
aspinall@24192
    25
       D.Opentheory {thyname = SOME name, parentnames = imports, text = text})
aspinall@24192
    26
  :: [D.Openblock {metavarid = NONE, name = NONE, objtype = SOME I.ObjTheoryBody}];
wenzelm@23797
    27
wenzelm@23797
    28
fun thy_heading text =
wenzelm@23797
    29
  [D.Closeblock {},
wenzelm@23797
    30
   D.Doccomment {text = text},
wenzelm@23797
    31
   D.Openblock {metavarid = NONE, name = NONE, objtype = SOME I.ObjTheoryBody}];
wenzelm@23797
    32
wenzelm@23797
    33
fun thy_decl text =
wenzelm@23797
    34
  [D.Theoryitem {name = NONE, objtype = SOME I.ObjTheoryDecl, text = text}];
wenzelm@23797
    35
wenzelm@23797
    36
fun goal text =
wenzelm@23797
    37
  [D.Opengoal {thmname = NONE, text = text},
wenzelm@23797
    38
   D.Openblock {metavarid = NONE, name = NONE, objtype = SOME I.ObjProofBody}];
wenzelm@23797
    39
wenzelm@23797
    40
fun prf_block text =
wenzelm@23797
    41
  [D.Closeblock {},
wenzelm@23797
    42
   D.Proofstep {text = text},
wenzelm@23797
    43
   D.Openblock {metavarid = NONE, name = NONE, objtype = SOME I.ObjProofBody}];
wenzelm@23797
    44
wenzelm@23797
    45
fun prf_open text =
wenzelm@23797
    46
 [D.Openblock {metavarid = NONE, name = NONE, objtype = SOME I.ObjProofBody},
wenzelm@23797
    47
  D.Proofstep {text = text}];
wenzelm@23797
    48
wenzelm@23797
    49
fun proofstep text = [D.Proofstep {text = text}];
wenzelm@23797
    50
fun closegoal text = [D.Closegoal {text = text}, D.Closeblock {}];
wenzelm@23797
    51
wenzelm@23797
    52
wenzelm@36950
    53
fun command k f = Symtab.update_new (Keyword.kind_of k, f);
wenzelm@23797
    54
wenzelm@23797
    55
val command_keywords = Symtab.empty
wenzelm@36950
    56
  |> command Keyword.control          badcmd
wenzelm@36950
    57
  |> command Keyword.diag             (fn text => [D.Spuriouscmd {text = text}])
wenzelm@36950
    58
  |> command Keyword.thy_begin        thy_begin
wenzelm@36950
    59
  |> command Keyword.thy_switch       badcmd
wenzelm@36950
    60
  |> command Keyword.thy_end          (fn text => [D.Closeblock {}, D.Closetheory {text = text}])
wenzelm@36950
    61
  |> command Keyword.thy_heading      thy_heading
wenzelm@36950
    62
  |> command Keyword.thy_decl         thy_decl
wenzelm@36950
    63
  |> command Keyword.thy_script       thy_decl
wenzelm@36950
    64
  |> command Keyword.thy_goal         goal
wenzelm@36950
    65
  |> command Keyword.thy_schematic_goal goal
wenzelm@36950
    66
  |> command Keyword.qed              closegoal
wenzelm@36950
    67
  |> command Keyword.qed_block        closegoal
wenzelm@36950
    68
  |> command Keyword.qed_global       (fn text => [D.Giveupgoal {text = text}])
wenzelm@36950
    69
  |> command Keyword.prf_heading      (fn text => [D.Doccomment {text = text}])
wenzelm@36950
    70
  |> command Keyword.prf_goal         goal
wenzelm@36950
    71
  |> command Keyword.prf_block        prf_block
wenzelm@36950
    72
  |> command Keyword.prf_open         prf_open
wenzelm@36950
    73
  |> command Keyword.prf_close        (fn text => [D.Proofstep {text = text}, D.Closeblock {}])
wenzelm@36950
    74
  |> command Keyword.prf_chain        proofstep
wenzelm@36950
    75
  |> command Keyword.prf_decl         proofstep
wenzelm@36950
    76
  |> command Keyword.prf_asm          proofstep
wenzelm@36950
    77
  |> command Keyword.prf_asm_goal     goal
wenzelm@36950
    78
  |> command Keyword.prf_script       proofstep;
wenzelm@23797
    79
wenzelm@36950
    80
val _ = subset (op =) (Keyword.kinds, Symtab.keys command_keywords)
wenzelm@23797
    81
  orelse sys_error "Incomplete coverage of command keywords";
wenzelm@23797
    82
wenzelm@23797
    83
fun parse_command "sorry" text = [D.Postponegoal {text = text}, D.Closeblock {}]
wenzelm@23797
    84
  | parse_command name text =
wenzelm@36950
    85
      (case Keyword.command_keyword name of
wenzelm@23797
    86
        NONE => [D.Unparseable {text = text}]
wenzelm@23797
    87
      | SOME k =>
wenzelm@36950
    88
          (case Symtab.lookup command_keywords (Keyword.kind_of k) of
wenzelm@23797
    89
            NONE => [D.Unparseable {text = text}]
wenzelm@23797
    90
          | SOME f => f text));
wenzelm@23797
    91
wenzelm@27841
    92
fun parse_span span =
wenzelm@27841
    93
  let
wenzelm@29315
    94
    val kind = ThySyntax.span_kind span;
wenzelm@29315
    95
    val toks = ThySyntax.span_content span;
wenzelm@37146
    96
    val text = implode (map (Print_Mode.setmp [] ThySyntax.present_token) toks);
wenzelm@27841
    97
  in
wenzelm@23797
    98
    (case kind of
wenzelm@29315
    99
      ThySyntax.Command name => parse_command name text
wenzelm@29315
   100
    | ThySyntax.Ignored => [D.Whitespace {text = text}]
wenzelm@29315
   101
    | ThySyntax.Malformed => [D.Unparseable {text = text}])
wenzelm@23797
   102
  end;
wenzelm@23797
   103
wenzelm@23797
   104
wenzelm@23797
   105
fun pgip_parser pos str =
wenzelm@36950
   106
  maps parse_span (ThySyntax.parse_spans (Keyword.get_lexicons ()) pos str);
wenzelm@23797
   107
wenzelm@23797
   108
end;