318 |
318 |
319 fun parse_failed ctxt pos msg kind = |
319 fun parse_failed ctxt pos msg kind = |
320 cat_error msg ("Failed to parse " ^ kind ^ |
320 cat_error msg ("Failed to parse " ^ kind ^ |
321 Markup.markup Markup.report (Context_Position.reported_text ctxt pos Markup.bad "")); |
321 Markup.markup Markup.report (Context_Position.reported_text ctxt pos Markup.bad "")); |
322 |
322 |
323 fun parse_sort ctxt text = |
323 fun parse_sort ctxt = |
324 let |
324 Syntax.parse_token ctxt Term_XML.Decode.sort Markup.sort |
325 val (syms, pos) = Syntax.parse_token ctxt Markup.sort text; |
325 (fn (syms, pos) => |
326 val S = |
|
327 parse_raw ctxt "sort" (syms, pos) |
326 parse_raw ctxt "sort" (syms, pos) |
328 |> report_result ctxt pos |
327 |> report_result ctxt pos |
329 |> sort_of_term |
328 |> sort_of_term |
330 handle ERROR msg => parse_failed ctxt pos msg "sort"; |
329 |> Type.minimize_sort (Proof_Context.tsig_of ctxt) |
331 in Type.minimize_sort (Proof_Context.tsig_of ctxt) S end; |
330 handle ERROR msg => parse_failed ctxt pos msg "sort"); |
332 |
331 |
333 fun parse_typ ctxt text = |
332 fun parse_typ ctxt = |
334 let |
333 Syntax.parse_token ctxt Term_XML.Decode.typ Markup.typ |
335 val (syms, pos) = Syntax.parse_token ctxt Markup.typ text; |
334 (fn (syms, pos) => |
336 val T = |
|
337 parse_raw ctxt "type" (syms, pos) |
335 parse_raw ctxt "type" (syms, pos) |
338 |> report_result ctxt pos |
336 |> report_result ctxt pos |
339 |> (fn t => typ_of_term (Proof_Context.get_sort ctxt (term_sorts t)) t) |
337 |> (fn t => typ_of_term (Proof_Context.get_sort ctxt (term_sorts t)) t) |
340 handle ERROR msg => parse_failed ctxt pos msg "type"; |
338 handle ERROR msg => parse_failed ctxt pos msg "type"); |
341 in T end; |
339 |
342 |
340 fun parse_term is_prop ctxt = |
343 fun parse_term is_prop ctxt text = |
|
344 let |
341 let |
345 val (markup, kind, root, constrain) = |
342 val (markup, kind, root, constrain) = |
346 if is_prop |
343 if is_prop |
347 then (Markup.prop, "proposition", "prop", Type.constraint propT) |
344 then (Markup.prop, "proposition", "prop", Type.constraint propT) |
348 else (Markup.term, "term", Config.get ctxt Syntax.root, I); |
345 else (Markup.term, "term", Config.get ctxt Syntax.root, I); |
349 val (syms, pos) = Syntax.parse_token ctxt markup text; |
346 val decode = constrain o Term_XML.Decode.term; |
350 in |
347 in |
351 let |
348 Syntax.parse_token ctxt decode markup |
352 val results = parse_raw ctxt root (syms, pos) |> map (decode_term ctxt); |
349 (fn (syms, pos) => |
353 val ambiguity = length (proper_results results); |
350 let |
354 |
351 val results = parse_raw ctxt root (syms, pos) |> map (decode_term ctxt); |
355 val level = Config.get ctxt Syntax.ambiguity_level; |
352 val ambiguity = length (proper_results results); |
356 val limit = Config.get ctxt Syntax.ambiguity_limit; |
353 |
357 |
354 val level = Config.get ctxt Syntax.ambiguity_level; |
358 val ambig_msg = |
355 val limit = Config.get ctxt Syntax.ambiguity_limit; |
359 if ambiguity > 1 andalso ambiguity <= level then |
356 |
360 ["Got more than one parse tree.\n\ |
357 val ambig_msg = |
361 \Retry with smaller syntax_ambiguity_level for more information."] |
358 if ambiguity > 1 andalso ambiguity <= level then |
362 else []; |
359 ["Got more than one parse tree.\n\ |
363 |
360 \Retry with smaller syntax_ambiguity_level for more information."] |
364 (*brute-force disambiguation via type-inference*) |
361 else []; |
365 fun check t = (Syntax.check_term ctxt (constrain t); Exn.Result t) |
362 |
366 handle exn as ERROR _ => Exn.Exn exn; |
363 (*brute-force disambiguation via type-inference*) |
367 |
364 fun check t = (Syntax.check_term ctxt (constrain t); Exn.Result t) |
368 val results' = |
365 handle exn as ERROR _ => Exn.Exn exn; |
369 if ambiguity > 1 then |
366 |
370 (Par_List.map_name "Syntax_Phases.parse_term" o apsnd o Exn.maps_result) |
367 val results' = |
371 check results |
368 if ambiguity > 1 then |
372 else results; |
369 (Par_List.map_name "Syntax_Phases.parse_term" o apsnd o Exn.maps_result) |
373 val reports' = fst (hd results'); |
370 check results |
374 |
371 else results; |
375 val errs = map snd (failed_results results'); |
372 val reports' = fst (hd results'); |
376 val checked = map snd (proper_results results'); |
373 |
377 val len = length checked; |
374 val errs = map snd (failed_results results'); |
378 |
375 val checked = map snd (proper_results results'); |
379 val show_term = Syntax.string_of_term (Config.put Printer.show_brackets true ctxt); |
376 val len = length checked; |
380 in |
377 |
381 if len = 0 then |
378 val show_term = Syntax.string_of_term (Config.put Printer.show_brackets true ctxt); |
382 report_result ctxt pos |
379 in |
383 [(reports', Exn.Exn (Exn.EXCEPTIONS (map ERROR ambig_msg @ errs)))] |
380 if len = 0 then |
384 else if len = 1 then |
381 report_result ctxt pos |
385 (if ambiguity > level then |
382 [(reports', Exn.Exn (Exn.EXCEPTIONS (map ERROR ambig_msg @ errs)))] |
386 Context_Position.if_visible ctxt warning |
383 else if len = 1 then |
387 "Fortunately, only one parse tree is type correct.\n\ |
384 (if ambiguity > level then |
388 \You may still want to disambiguate your grammar or your input." |
385 Context_Position.if_visible ctxt warning |
389 else (); report_result ctxt pos results') |
386 "Fortunately, only one parse tree is type correct.\n\ |
390 else |
387 \You may still want to disambiguate your grammar or your input." |
391 report_result ctxt pos |
388 else (); report_result ctxt pos results') |
392 [(reports', Exn.Exn (ERROR (cat_lines (ambig_msg @ |
389 else |
393 (("Ambiguous input, " ^ string_of_int len ^ " terms are type correct" ^ |
390 report_result ctxt pos |
394 (if len <= limit then "" else " (" ^ string_of_int limit ^ " displayed)") ^ ":") :: |
391 [(reports', Exn.Exn (ERROR (cat_lines (ambig_msg @ |
395 map show_term (take limit checked))))))] |
392 (("Ambiguous input, " ^ string_of_int len ^ " terms are type correct" ^ |
396 end handle ERROR msg => parse_failed ctxt pos msg kind |
393 (if len <= limit then "" else " (" ^ string_of_int limit ^ " displayed)") ^ ":") :: |
|
394 map show_term (take limit checked))))))] |
|
395 end handle ERROR msg => parse_failed ctxt pos msg kind) |
397 end; |
396 end; |
398 |
397 |
399 |
398 |
400 (* parse_ast_pattern *) |
399 (* parse_ast_pattern *) |
401 |
400 |