src/Pure/Syntax/syntax_phases.ML
changeset 43731 70072780e095
parent 43552 156c822f181a
child 43761 e72ba84ae58f
equal deleted inserted replaced
43730:a0ed7bc688b5 43731:70072780e095
   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