equal
deleted
inserted
replaced
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; |