src/Pure/Thy/thy_syntax.ML
changeset 51225 3fe0d8d55975
parent 50238 98d35a7368bd
child 51267 c68c1b89a0f1
equal deleted inserted replaced
51224:c3e99efacb67 51225:3fe0d8d55975
    13   datatype span = Span of span_kind * Token.T list
    13   datatype span = Span of span_kind * Token.T list
    14   val span_kind: span -> span_kind
    14   val span_kind: span -> span_kind
    15   val span_content: span -> Token.T list
    15   val span_content: span -> Token.T list
    16   val present_span: span -> Output.output
    16   val present_span: span -> Output.output
    17   val parse_spans: Token.T list -> span list
    17   val parse_spans: Token.T list -> span list
    18   type element = {head: span, proof: span list, proper_proof: bool}
    18   datatype 'a element = Element of 'a * ('a element list * 'a) option
    19   val parse_elements: span list -> element list
    19   val map_element: ('a -> 'b) -> 'a element -> 'b element
       
    20   val flat_element: 'a element -> 'a list
       
    21   val parse_elements: span list -> span element list
    20 end;
    22 end;
    21 
    23 
    22 structure Thy_Syntax: THY_SYNTAX =
    24 structure Thy_Syntax: THY_SYNTAX =
    23 struct
    25 struct
    24 
    26 
   132 
   134 
   133 
   135 
   134 
   136 
   135 (** specification elements: commands with optional proof **)
   137 (** specification elements: commands with optional proof **)
   136 
   138 
   137 type element = {head: span, proof: span list, proper_proof: bool};
   139 datatype 'a element = Element of 'a * ('a element list * 'a) option;
   138 
   140 
   139 fun make_element head proof proper_proof =
   141 fun element (a, b) = Element (a, SOME b);
   140   {head = head, proof = proof, proper_proof = proper_proof};
   142 fun atom a = Element (a, NONE);
       
   143 
       
   144 fun map_element f (Element (a, NONE)) = Element (f a, NONE)
       
   145   | map_element f (Element (a, SOME (elems, b))) =
       
   146       Element (f a, SOME ((map o map_element) f elems, f b));
       
   147 
       
   148 fun flat_element (Element (a, NONE)) = [a]
       
   149   | flat_element (Element (a, SOME (elems, b))) = a :: maps flat_element elems @ [b];
   141 
   150 
   142 
   151 
   143 (* scanning spans *)
   152 (* scanning spans *)
   144 
   153 
   145 val eof = Span (Command ("", Position.none), []);
   154 val eof = Span (Command ("", Position.none), []);
   157 local
   166 local
   158 
   167 
   159 fun command_with pred =
   168 fun command_with pred =
   160   Scan.one (fn (Span (Command (name, _), _)) => pred name | _ => false);
   169   Scan.one (fn (Span (Command (name, _), _)) => pred name | _ => false);
   161 
   170 
   162 val proof = Scan.pass 1 (Scan.repeat (Scan.depend (fn d =>
   171 val proof_atom =
   163   if d <= 0 then Scan.fail
   172   Scan.one (fn (Span (Command (name, _), _)) => Keyword.is_proof_body name | _ => true) >> atom;
   164   else
       
   165     command_with Keyword.is_qed_global >> pair ~1 ||
       
   166     command_with Keyword.is_proof_goal >> pair (d + 1) ||
       
   167     (if d = 0 then Scan.fail else command_with Keyword.is_qed >> pair (d - 1)) ||
       
   168     Scan.unless (command_with Keyword.is_theory) (Scan.one not_eof) >> pair d)) -- Scan.state);
       
   169 
   173 
   170 val element =
   174 fun proof_element x = (command_with Keyword.is_proof_goal -- proof_rest >> element || proof_atom) x
   171   command_with Keyword.is_theory_goal -- proof
   175 and proof_rest x = (Scan.repeat proof_element -- command_with Keyword.is_qed) x;
   172     >> (fn (a, (bs, d)) => make_element a bs (d >= 0)) ||
   176 
   173   Scan.one not_eof >> (fn a => make_element a [] true);
   177 val other_element =
       
   178   command_with Keyword.is_theory_goal -- proof_rest >> element ||
       
   179   Scan.one not_eof >> atom;
   174 
   180 
   175 in
   181 in
   176 
   182 
   177 val parse_elements =
   183 val parse_elements =
   178   Source.of_list #>
   184   Source.of_list #>
   179   Source.source stopper (Scan.bulk element) NONE #>
   185   Source.source stopper (Scan.bulk other_element) NONE #>
   180   Source.exhaust;
   186   Source.exhaust;
   181 
   187 
   182 end;
   188 end;
   183 
   189 
   184 end;
   190 end;