src/Pure/Syntax/syntax.ML
changeset 42242 39261908e12f
parent 42225 cf48af306290
child 42245 29e3967550d5
equal deleted inserted replaced
42241:dd8029f71e1c 42242:39261908e12f
    93   val string_of_term_global: theory -> term -> string
    93   val string_of_term_global: theory -> term -> string
    94   val string_of_typ_global: theory -> typ -> string
    94   val string_of_typ_global: theory -> typ -> string
    95   val string_of_sort_global: theory -> sort -> string
    95   val string_of_sort_global: theory -> sort -> string
    96   val pp: Proof.context -> Pretty.pp
    96   val pp: Proof.context -> Pretty.pp
    97   val pp_global: theory -> Pretty.pp
    97   val pp_global: theory -> Pretty.pp
       
    98   type ruletab
    98   type syntax
    99   type syntax
       
   100   val rep_syntax: syntax ->
       
   101    {input: Syn_Ext.xprod list,
       
   102     lexicon: Scan.lexicon,
       
   103     gram: Parser.gram,
       
   104     consts: string list,
       
   105     prmodes: string list,
       
   106     parse_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) Symtab.table,
       
   107     parse_ruletab: ruletab,
       
   108     parse_trtab: ((Proof.context -> term list -> term) * stamp) Symtab.table,
       
   109     print_trtab: ((Proof.context -> bool -> typ -> term list -> term) * stamp) list Symtab.table,
       
   110     print_ruletab: ruletab,
       
   111     print_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) list Symtab.table,
       
   112     tokentrtab: (string * (string * ((Proof.context -> string -> Pretty.T) * stamp)) list) list,
       
   113     prtabs: Printer.prtabs}
    99   val eq_syntax: syntax * syntax -> bool
   114   val eq_syntax: syntax * syntax -> bool
   100   val is_keyword: syntax -> string -> bool
   115   val is_keyword: syntax -> string -> bool
   101   type mode
   116   type mode
   102   val mode_default: mode
   117   val mode_default: mode
   103   val mode_input: mode
   118   val mode_input: mode
   112   val positions: bool Config.T
   127   val positions: bool Config.T
   113   val ambiguity_enabled: bool Config.T
   128   val ambiguity_enabled: bool Config.T
   114   val ambiguity_level_raw: Config.raw
   129   val ambiguity_level_raw: Config.raw
   115   val ambiguity_level: int Config.T
   130   val ambiguity_level: int Config.T
   116   val ambiguity_limit: int Config.T
   131   val ambiguity_limit: int Config.T
   117   val standard_parse_sort: Proof.context -> type_context -> syntax ->
       
   118     Symbol_Pos.T list * Position.T -> sort
       
   119   val standard_parse_typ: Proof.context -> type_context -> syntax ->
       
   120     ((indexname * sort) list -> indexname -> sort) -> Symbol_Pos.T list * Position.T -> typ
       
   121   val standard_parse_term: (term -> term Exn.result) ->
       
   122     Proof.context -> type_context -> term_context -> syntax ->
       
   123     string -> Symbol_Pos.T list * Position.T -> term
       
   124   datatype 'a trrule =
   132   datatype 'a trrule =
   125     Parse_Rule of 'a * 'a |
   133     Parse_Rule of 'a * 'a |
   126     Print_Rule of 'a * 'a |
   134     Print_Rule of 'a * 'a |
   127     Parse_Print_Rule of 'a * 'a
   135     Parse_Print_Rule of 'a * 'a
   128   val map_trrule: ('a -> 'b) -> 'a trrule -> 'b trrule
   136   val map_trrule: ('a -> 'b) -> 'a trrule -> 'b trrule
   129   val is_const: syntax -> string -> bool
   137   val is_const: syntax -> string -> bool
   130   val read_rule_pattern: Proof.context -> type_context -> syntax -> string * string -> Ast.ast
       
   131   val standard_unparse_sort: {extern_class: string -> xstring} ->
   138   val standard_unparse_sort: {extern_class: string -> xstring} ->
   132     Proof.context -> syntax -> sort -> Pretty.T
   139     Proof.context -> syntax -> sort -> Pretty.T
   133   val standard_unparse_typ: {extern_class: string -> xstring, extern_type: string -> xstring} ->
   140   val standard_unparse_typ: {extern_class: string -> xstring, extern_type: string -> xstring} ->
   134     Proof.context -> syntax -> typ -> Pretty.T
   141     Proof.context -> syntax -> typ -> Pretty.T
   135   val standard_unparse_term: {structs: string list, fixes: string list} ->
   142   val standard_unparse_term: {structs: string list, fixes: string list} ->
   392 
   399 
   393 (** tables of translation functions **)
   400 (** tables of translation functions **)
   394 
   401 
   395 (* parse (ast) translations *)
   402 (* parse (ast) translations *)
   396 
   403 
   397 fun lookup_tr tab c = Option.map fst (Symtab.lookup tab c);
       
   398 
       
   399 fun err_dup_trfun name c =
   404 fun err_dup_trfun name c =
   400   error ("More than one " ^ name ^ " for " ^ quote c);
   405   error ("More than one " ^ name ^ " for " ^ quote c);
   401 
   406 
   402 fun remove_trtab trfuns = fold (Symtab.remove Syn_Ext.eq_trfun) trfuns;
   407 fun remove_trtab trfuns = fold (Symtab.remove Syn_Ext.eq_trfun) trfuns;
   403 
   408 
   482     print_ruletab: ruletab,
   487     print_ruletab: ruletab,
   483     print_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) list Symtab.table,
   488     print_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) list Symtab.table,
   484     tokentrtab: (string * (string * ((Proof.context -> string -> Pretty.T) * stamp)) list) list,
   489     tokentrtab: (string * (string * ((Proof.context -> string -> Pretty.T) * stamp)) list) list,
   485     prtabs: Printer.prtabs} * stamp;
   490     prtabs: Printer.prtabs} * stamp;
   486 
   491 
       
   492 fun rep_syntax (Syntax (tabs, _)) = tabs;
   487 fun eq_syntax (Syntax (_, s1), Syntax (_, s2)) = s1 = s2;
   493 fun eq_syntax (Syntax (_, s1), Syntax (_, s2)) = s1 = s2;
   488 
   494 
   489 fun is_keyword (Syntax ({lexicon, ...}, _)) = Scan.is_literal lexicon o Symbol.explode;
   495 fun is_keyword (Syntax ({lexicon, ...}, _)) = Scan.is_literal lexicon o Symbol.explode;
   490 
   496 
   491 type mode = string * bool;
   497 type mode = string * bool;
   698 val ambiguity_level = Config.int ambiguity_level_raw;
   704 val ambiguity_level = Config.int ambiguity_level_raw;
   699 
   705 
   700 val ambiguity_limit =
   706 val ambiguity_limit =
   701   Config.int (Config.declare "syntax_ambiguity_limit" (fn _ => Config.Int 10));
   707   Config.int (Config.declare "syntax_ambiguity_limit" (fn _ => Config.Int 10));
   702 
   708 
   703 fun ambiguity_msg pos = "Parse error: ambiguous syntax" ^ Position.str_of pos;
       
   704 
       
   705 
       
   706 (* results *)
       
   707 
       
   708 fun proper_results results = map_filter (fn (y, Exn.Result x) => SOME (y, x) | _ => NONE) results;
       
   709 fun failed_results results = map_filter (fn (y, Exn.Exn e) => SOME (y, e) | _ => NONE) results;
       
   710 
       
   711 fun report ctxt = List.app (fn (pos, m) => Context_Position.report ctxt pos m);
       
   712 
       
   713 fun report_result ctxt pos results =
       
   714   (case (proper_results results, failed_results results) of
       
   715     ([], (reports, exn) :: _) => (report ctxt reports; reraise exn)
       
   716   | ([(reports, x)], _) => (report ctxt reports; x)
       
   717   | _ => error (ambiguity_msg pos));
       
   718 
       
   719 
       
   720 (* read_asts *)
       
   721 
       
   722 fun read_asts ctxt type_ctxt (Syntax (tabs, _)) raw root (syms, pos) =
       
   723   let
       
   724     val {lexicon, gram, parse_ast_trtab, ...} = tabs;
       
   725     val toks = Lexicon.tokenize lexicon raw syms;
       
   726     val _ = List.app (Lexicon.report_token ctxt) toks;
       
   727 
       
   728     val pts = Parser.parse ctxt gram root (filter Lexicon.is_proper toks)
       
   729       handle ERROR msg =>
       
   730         error (msg ^
       
   731           implode (map (Markup.markup Markup.report o Lexicon.reported_token_range ctxt) toks));
       
   732     val len = length pts;
       
   733 
       
   734     val limit = Config.get ctxt ambiguity_limit;
       
   735     val _ =
       
   736       if len <= Config.get ctxt ambiguity_level then ()
       
   737       else if not (Config.get ctxt ambiguity_enabled) then error (ambiguity_msg pos)
       
   738       else
       
   739         (Context_Position.if_visible ctxt warning (cat_lines
       
   740           (("Ambiguous input" ^ Position.str_of pos ^
       
   741             "\nproduces " ^ string_of_int len ^ " parse trees" ^
       
   742             (if len <= limit then "" else " (" ^ string_of_int limit ^ " displayed)") ^ ":") ::
       
   743             map (Pretty.string_of o Parser.pretty_parsetree) (take limit pts))));
       
   744 
       
   745     val constrain_pos = not raw andalso Config.get ctxt positions;
       
   746     val parsetree_to_ast =
       
   747       Syn_Trans.parsetree_to_ast ctxt type_ctxt constrain_pos (lookup_tr parse_ast_trtab);
       
   748   in map parsetree_to_ast pts end;
       
   749 
       
   750 
       
   751 (* read_raw *)
       
   752 
       
   753 fun read_raw ctxt type_ctxt (syn as Syntax (tabs, _)) root input =
       
   754   let
       
   755     val {parse_ruletab, parse_trtab, ...} = tabs;
       
   756     val norm = Ast.normalize ctxt (Symtab.lookup_list parse_ruletab);
       
   757     val ast_to_term = Syn_Trans.ast_to_term ctxt (lookup_tr parse_trtab);
       
   758   in
       
   759     read_asts ctxt type_ctxt syn false root input
       
   760     |> (map o apsnd o Exn.maps_result) (norm #> Exn.interruptible_capture ast_to_term)
       
   761   end;
       
   762 
       
   763 
       
   764 (* read sorts *)
       
   765 
       
   766 fun standard_parse_sort ctxt type_ctxt syn (syms, pos) =
       
   767   read_raw ctxt type_ctxt syn (Syn_Ext.typ_to_nonterm Type_Ext.sortT) (syms, pos)
       
   768   |> report_result ctxt pos
       
   769   |> Type_Ext.sort_of_term;
       
   770 
       
   771 
       
   772 (* read types *)
       
   773 
       
   774 fun standard_parse_typ ctxt type_ctxt syn get_sort (syms, pos) =
       
   775   read_raw ctxt type_ctxt syn (Syn_Ext.typ_to_nonterm Syn_Ext.typeT) (syms, pos)
       
   776   |> report_result ctxt pos
       
   777   |> (fn t => Type_Ext.typ_of_term (get_sort (Type_Ext.term_sorts t)) t);
       
   778 
       
   779 
       
   780 (* read terms -- brute-force disambiguation via type-inference *)
       
   781 
       
   782 fun standard_parse_term check ctxt type_ctxt term_ctxt syn root (syms, pos) =
       
   783   let
       
   784     val results =
       
   785       read_raw ctxt type_ctxt syn root (syms, pos)
       
   786       |> map (Type_Ext.decode_term term_ctxt);
       
   787 
       
   788     val level = Config.get ctxt ambiguity_level;
       
   789     val limit = Config.get ctxt ambiguity_limit;
       
   790 
       
   791     val ambiguity = length (proper_results results);
       
   792 
       
   793     fun ambig_msg () =
       
   794       if ambiguity > 1 andalso ambiguity <= level then
       
   795         "Got more than one parse tree.\n\
       
   796         \Retry with smaller syntax_ambiguity_level for more information."
       
   797       else "";
       
   798 
       
   799     val results' =
       
   800       if ambiguity > 1 then
       
   801         (Par_List.map_name "Syntax.disambig" o apsnd o Exn.maps_result) check results
       
   802       else results;
       
   803     val reports' = fst (hd results');
       
   804 
       
   805     val errs = map snd (failed_results results');
       
   806     val checked = map snd (proper_results results');
       
   807     val len = length checked;
       
   808 
       
   809     val show_term = string_of_term (Config.put Printer.show_brackets true ctxt);
       
   810   in
       
   811     if len = 0 then
       
   812       report_result ctxt pos
       
   813         [(reports', Exn.Exn (Exn.EXCEPTIONS (ERROR (ambig_msg ()) :: errs)))]
       
   814     else if len = 1 then
       
   815       (if ambiguity > level then
       
   816         Context_Position.if_visible ctxt warning
       
   817           "Fortunately, only one parse tree is type correct.\n\
       
   818           \You may still want to disambiguate your grammar or your input."
       
   819       else (); report_result ctxt pos results')
       
   820     else
       
   821       report_result ctxt pos
       
   822         [(reports', Exn.Exn (ERROR (cat_lines (ambig_msg () ::
       
   823           (("Ambiguous input, " ^ string_of_int len ^ " terms are type correct" ^
       
   824             (if len <= limit then "" else " (" ^ string_of_int limit ^ " displayed)") ^ ":") ::
       
   825             map show_term (take limit checked))))))]
       
   826   end;
       
   827 
       
   828 
   709 
   829 
   710 
   830 (** prepare translation rules **)
   711 (** prepare translation rules **)
   831 
   712 
   832 (* rules *)
   713 (* rules *)
   868 fun check_rules rules =
   749 fun check_rules rules =
   869  (map check_rule (map_filter parse_rule rules),
   750  (map check_rule (map_filter parse_rule rules),
   870   map check_rule (map_filter print_rule rules));
   751   map check_rule (map_filter print_rule rules));
   871 
   752 
   872 end;
   753 end;
   873 
       
   874 
       
   875 (* read_rule_pattern *)
       
   876 
       
   877 fun read_rule_pattern ctxt type_ctxt syn (root, str) =
       
   878   let
       
   879     fun constify (ast as Ast.Constant _) = ast
       
   880       | constify (ast as Ast.Variable x) =
       
   881           if is_const syn x orelse Long_Name.is_qualified x then Ast.Constant x
       
   882           else ast
       
   883       | constify (Ast.Appl asts) = Ast.Appl (map constify asts);
       
   884 
       
   885     val (syms, pos) = read_token str;
       
   886   in
       
   887     read_asts ctxt type_ctxt syn true root (syms, pos)
       
   888     |> report_result ctxt pos
       
   889     |> constify
       
   890   end;
       
   891 
   754 
   892 
   755 
   893 
   756 
   894 (** unparse terms, typs, sorts **)
   757 (** unparse terms, typs, sorts **)
   895 
   758