src/Pure/Syntax/syntax.ML
changeset 45632 b23c42b9f78a
parent 45490 20c8c0cca555
child 45641 20ef9135a9fb
equal deleted inserted replaced
45631:6bdf8b926f50 45632:b23c42b9f78a
    72   val string_of_term_global: theory -> term -> string
    72   val string_of_term_global: theory -> term -> string
    73   val string_of_typ_global: theory -> typ -> string
    73   val string_of_typ_global: theory -> typ -> string
    74   val string_of_sort_global: theory -> sort -> string
    74   val string_of_sort_global: theory -> sort -> string
    75   type syntax
    75   type syntax
    76   val eq_syntax: syntax * syntax -> bool
    76   val eq_syntax: syntax * syntax -> bool
    77   val join_syntax: syntax -> unit
    77   val force_syntax: syntax -> unit
    78   val lookup_const: syntax -> string -> string option
    78   val lookup_const: syntax -> string -> string option
    79   val is_keyword: syntax -> string -> bool
    79   val is_keyword: syntax -> string -> bool
    80   val tokenize: syntax -> bool -> Symbol_Pos.T list -> Lexicon.token list
    80   val tokenize: syntax -> bool -> Symbol_Pos.T list -> Lexicon.token list
    81   val parse: Proof.context -> syntax -> string -> Lexicon.token list -> Parser.parsetree list
    81   val parse: Proof.context -> syntax -> string -> Lexicon.token list -> Parser.parsetree list
    82   val parse_ast_translation: syntax -> string -> (Proof.context -> Ast.ast list -> Ast.ast) option
    82   val parse_ast_translation: syntax -> string -> (Proof.context -> Ast.ast list -> Ast.ast) option
    90   val prtabs: syntax -> Printer.prtabs
    90   val prtabs: syntax -> Printer.prtabs
    91   type mode
    91   type mode
    92   val mode_default: mode
    92   val mode_default: mode
    93   val mode_input: mode
    93   val mode_input: mode
    94   val empty_syntax: syntax
    94   val empty_syntax: syntax
    95   val merge_syntaxes: syntax -> syntax -> syntax
    95   val merge_syntax: syntax * syntax -> syntax
    96   val token_markers: string list
    96   val token_markers: string list
    97   val basic_nonterms: string list
    97   val basic_nonterms: string list
    98   val print_gram: syntax -> unit
    98   val print_gram: syntax -> unit
    99   val print_trans: syntax -> unit
    99   val print_trans: syntax -> unit
   100   val print_syntax: syntax -> unit
   100   val print_syntax: syntax -> unit
   377 
   377 
   378 
   378 
   379 
   379 
   380 (** datatype syntax **)
   380 (** datatype syntax **)
   381 
   381 
   382 fun future_gram deps e =
       
   383   singleton
       
   384     (Future.cond_forks {name = "Syntax.gram", group = NONE,
       
   385       deps = map Future.task_of deps, pri = 0, interrupts = true}) e;
       
   386 
       
   387 datatype syntax =
   382 datatype syntax =
   388   Syntax of {
   383   Syntax of {
   389     input: Syntax_Ext.xprod list,
   384     input: Syntax_Ext.xprod list,
   390     lexicon: Scan.lexicon,
   385     lexicon: Scan.lexicon,
   391     gram: Parser.gram future,
   386     gram: Parser.gram lazy,
   392     consts: string Symtab.table,
   387     consts: string Symtab.table,
   393     prmodes: string list,
   388     prmodes: string list,
   394     parse_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) Symtab.table,
   389     parse_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) Symtab.table,
   395     parse_ruletab: ruletab,
   390     parse_ruletab: ruletab,
   396     parse_trtab: ((Proof.context -> term list -> term) * stamp) Symtab.table,
   391     parse_trtab: ((Proof.context -> term list -> term) * stamp) Symtab.table,
   399     print_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) list Symtab.table,
   394     print_ast_trtab: ((Proof.context -> Ast.ast list -> Ast.ast) * stamp) list Symtab.table,
   400     prtabs: Printer.prtabs} * stamp;
   395     prtabs: Printer.prtabs} * stamp;
   401 
   396 
   402 fun eq_syntax (Syntax (_, s1), Syntax (_, s2)) = s1 = s2;
   397 fun eq_syntax (Syntax (_, s1), Syntax (_, s2)) = s1 = s2;
   403 
   398 
   404 fun join_syntax (Syntax ({gram, ...}, _)) = ignore (Future.join gram);
   399 fun force_syntax (Syntax ({gram, ...}, _)) = ignore (Lazy.force gram);
   405 
   400 
   406 fun lookup_const (Syntax ({consts, ...}, _)) = Symtab.lookup consts;
   401 fun lookup_const (Syntax ({consts, ...}, _)) = Symtab.lookup consts;
   407 fun is_keyword (Syntax ({lexicon, ...}, _)) = Scan.is_literal lexicon o Symbol.explode;
   402 fun is_keyword (Syntax ({lexicon, ...}, _)) = Scan.is_literal lexicon o Symbol.explode;
   408 fun tokenize (Syntax ({lexicon, ...}, _)) = Lexicon.tokenize lexicon;
   403 fun tokenize (Syntax ({lexicon, ...}, _)) = Lexicon.tokenize lexicon;
   409 fun parse ctxt (Syntax ({gram, ...}, _)) = Parser.parse ctxt (Future.join gram);
   404 fun parse ctxt (Syntax ({gram, ...}, _)) = Parser.parse ctxt (Lazy.force gram);
   410 
   405 
   411 fun parse_ast_translation (Syntax ({parse_ast_trtab, ...}, _)) = lookup_tr parse_ast_trtab;
   406 fun parse_ast_translation (Syntax ({parse_ast_trtab, ...}, _)) = lookup_tr parse_ast_trtab;
   412 fun parse_translation (Syntax ({parse_trtab, ...}, _)) = lookup_tr parse_trtab;
   407 fun parse_translation (Syntax ({parse_trtab, ...}, _)) = lookup_tr parse_trtab;
   413 fun parse_rules (Syntax ({parse_ruletab, ...}, _)) = Symtab.lookup_list parse_ruletab;
   408 fun parse_rules (Syntax ({parse_ruletab, ...}, _)) = Symtab.lookup_list parse_ruletab;
   414 fun print_translation (Syntax ({print_trtab, ...}, _)) = apply_tr' print_trtab;
   409 fun print_translation (Syntax ({print_trtab, ...}, _)) = apply_tr' print_trtab;
   425 (* empty_syntax *)
   420 (* empty_syntax *)
   426 
   421 
   427 val empty_syntax = Syntax
   422 val empty_syntax = Syntax
   428   ({input = [],
   423   ({input = [],
   429     lexicon = Scan.empty_lexicon,
   424     lexicon = Scan.empty_lexicon,
   430     gram = Future.value Parser.empty_gram,
   425     gram = Lazy.value Parser.empty_gram,
   431     consts = Symtab.empty,
   426     consts = Symtab.empty,
   432     prmodes = [],
   427     prmodes = [],
   433     parse_ast_trtab = Symtab.empty,
   428     parse_ast_trtab = Symtab.empty,
   434     parse_ruletab = Symtab.empty,
   429     parse_ruletab = Symtab.empty,
   435     parse_trtab = Symtab.empty,
   430     parse_trtab = Symtab.empty,
   458     fun if_inout xs = if inout then xs else [];
   453     fun if_inout xs = if inout then xs else [];
   459   in
   454   in
   460     Syntax
   455     Syntax
   461     ({input = new_xprods @ input,
   456     ({input = new_xprods @ input,
   462       lexicon = fold Scan.extend_lexicon (Syntax_Ext.delims_of new_xprods) lexicon,
   457       lexicon = fold Scan.extend_lexicon (Syntax_Ext.delims_of new_xprods) lexicon,
   463       gram = Future.value (Parser.extend_gram new_xprods (Future.join gram)),
   458       gram = Lazy.value (Parser.extend_gram new_xprods (Lazy.force gram)),
   464       consts = fold update_const consts2 consts1,
   459       consts = fold update_const consts2 consts1,
   465       prmodes = insert (op =) mode prmodes,
   460       prmodes = insert (op =) mode prmodes,
   466       parse_ast_trtab =
   461       parse_ast_trtab =
   467         update_trtab "parse ast translation" (if_inout parse_ast_translation) parse_ast_trtab,
   462         update_trtab "parse ast translation" (if_inout parse_ast_translation) parse_ast_trtab,
   468       parse_ruletab = update_ruletab (if_inout parse_rules) parse_ruletab,
   463       parse_ruletab = update_ruletab (if_inout parse_rules) parse_ruletab,
   487     fun if_inout xs = if inout then xs else [];
   482     fun if_inout xs = if inout then xs else [];
   488   in
   483   in
   489     Syntax
   484     Syntax
   490     ({input = input',
   485     ({input = input',
   491       lexicon = if changed then Scan.make_lexicon (Syntax_Ext.delims_of input') else lexicon,
   486       lexicon = if changed then Scan.make_lexicon (Syntax_Ext.delims_of input') else lexicon,
   492       gram = if changed then Future.value (Parser.extend_gram input' Parser.empty_gram) else gram,
   487       gram = if changed then Lazy.value (Parser.make_gram input') else gram,
   493       consts = consts,
   488       consts = consts,
   494       prmodes = prmodes,
   489       prmodes = prmodes,
   495       parse_ast_trtab = remove_trtab (if_inout parse_ast_translation) parse_ast_trtab,
   490       parse_ast_trtab = remove_trtab (if_inout parse_ast_translation) parse_ast_trtab,
   496       parse_ruletab = remove_ruletab (if_inout parse_rules) parse_ruletab,
   491       parse_ruletab = remove_ruletab (if_inout parse_rules) parse_ruletab,
   497       parse_trtab = remove_trtab (if_inout parse_translation) parse_trtab,
   492       parse_trtab = remove_trtab (if_inout parse_translation) parse_trtab,
   500       print_ast_trtab = remove_tr'tab print_ast_translation print_ast_trtab,
   495       print_ast_trtab = remove_tr'tab print_ast_translation print_ast_trtab,
   501       prtabs = Printer.remove_prtabs mode xprods prtabs}, stamp ())
   496       prtabs = Printer.remove_prtabs mode xprods prtabs}, stamp ())
   502   end;
   497   end;
   503 
   498 
   504 
   499 
   505 (* merge_syntaxes *)
   500 (* merge_syntax *)
   506 
   501 
   507 fun merge_syntaxes (Syntax (tabs1, _)) (Syntax (tabs2, _)) =
   502 fun merge_syntax (Syntax (tabs1, _), Syntax (tabs2, _)) =
   508   let
   503   let
   509     val {input = input1, lexicon = lexicon1, gram = gram1, consts = consts1,
   504     val {input = input1, lexicon = lexicon1, gram = gram1, consts = consts1,
   510       prmodes = prmodes1, parse_ast_trtab = parse_ast_trtab1, parse_ruletab = parse_ruletab1,
   505       prmodes = prmodes1, parse_ast_trtab = parse_ast_trtab1, parse_ruletab = parse_ruletab1,
   511       parse_trtab = parse_trtab1, print_trtab = print_trtab1, print_ruletab = print_ruletab1,
   506       parse_trtab = parse_trtab1, print_trtab = print_trtab1, print_ruletab = print_ruletab1,
   512       print_ast_trtab = print_ast_trtab1, prtabs = prtabs1} = tabs1;
   507       print_ast_trtab = print_ast_trtab1, prtabs = prtabs1} = tabs1;
   513 
   508 
   514     val {input = input2, lexicon = lexicon2, gram = gram2, consts = consts2,
   509     val {input = input2, lexicon = lexicon2, gram = gram2, consts = consts2,
   515       prmodes = prmodes2, parse_ast_trtab = parse_ast_trtab2, parse_ruletab = parse_ruletab2,
   510       prmodes = prmodes2, parse_ast_trtab = parse_ast_trtab2, parse_ruletab = parse_ruletab2,
   516       parse_trtab = parse_trtab2, print_trtab = print_trtab2, print_ruletab = print_ruletab2,
   511       parse_trtab = parse_trtab2, print_trtab = print_trtab2, print_ruletab = print_ruletab2,
   517       print_ast_trtab = print_ast_trtab2, prtabs = prtabs2} = tabs2;
   512       print_ast_trtab = print_ast_trtab2, prtabs = prtabs2} = tabs2;
       
   513 
       
   514     val (input', gram') =
       
   515       (case subtract (op =) input1 input2 of
       
   516         [] => (input1, gram1)
       
   517       | new_xprods2 =>
       
   518           if subset (op =) (input1, input2) then (input2, gram2)
       
   519           else
       
   520             let
       
   521               val input' = new_xprods2 @ input1;
       
   522               val gram' = Lazy.lazy (fn () => Parser.make_gram input');
       
   523             in (input', gram') end);
   518   in
   524   in
   519     Syntax
   525     Syntax
   520     ({input = Library.merge (op =) (input1, input2),
   526     ({input = input',
   521       lexicon = Scan.merge_lexicons (lexicon1, lexicon2),
   527       lexicon = Scan.merge_lexicons (lexicon1, lexicon2),
   522       gram = future_gram [gram1, gram2] (fn () =>
   528       gram = gram',
   523         Parser.merge_gram (Future.join gram1, Future.join gram2)),
       
   524       consts = Symtab.merge (K true) (consts1, consts2),
   529       consts = Symtab.merge (K true) (consts1, consts2),
   525       prmodes = Library.merge (op =) (prmodes1, prmodes2),
   530       prmodes = Library.merge (op =) (prmodes1, prmodes2),
   526       parse_ast_trtab =
   531       parse_ast_trtab =
   527         merge_trtabs "parse ast translation" parse_ast_trtab1 parse_ast_trtab2,
   532         merge_trtabs "parse ast translation" parse_ast_trtab1 parse_ast_trtab2,
   528       parse_ruletab = merge_ruletabs parse_ruletab1 parse_ruletab2,
   533       parse_ruletab = merge_ruletabs parse_ruletab1 parse_ruletab2,
   558   let
   563   let
   559     val {lexicon, prmodes, gram, ...} = tabs;
   564     val {lexicon, prmodes, gram, ...} = tabs;
   560     val prmodes' = sort_strings (filter_out (fn s => s = "") prmodes);
   565     val prmodes' = sort_strings (filter_out (fn s => s = "") prmodes);
   561   in
   566   in
   562     [pretty_strs_qs "lexicon:" (Scan.dest_lexicon lexicon),
   567     [pretty_strs_qs "lexicon:" (Scan.dest_lexicon lexicon),
   563       Pretty.big_list "prods:" (Parser.pretty_gram (Future.join gram)),
   568       Pretty.big_list "prods:" (Parser.pretty_gram (Lazy.force gram)),
   564       pretty_strs_qs "print modes:" prmodes']
   569       pretty_strs_qs "print modes:" prmodes']
   565   end;
   570   end;
   566 
   571 
   567 fun pretty_trans (Syntax (tabs, _)) =
   572 fun pretty_trans (Syntax (tabs, _)) =
   568   let
   573   let
   594 
   599 
   595 
   600 
   596 (* reconstructing infixes -- educated guessing *)
   601 (* reconstructing infixes -- educated guessing *)
   597 
   602 
   598 fun guess_infix (Syntax ({gram, ...}, _)) c =
   603 fun guess_infix (Syntax ({gram, ...}, _)) c =
   599   (case Parser.guess_infix_lr (Future.join gram) c of
   604   (case Parser.guess_infix_lr (Lazy.force gram) c of
   600     SOME (s, l, r, j) => SOME
   605     SOME (s, l, r, j) => SOME
   601      (if l then Mixfix.Infixl (s, j)
   606      (if l then Mixfix.Infixl (s, j)
   602       else if r then Mixfix.Infixr (s, j)
   607       else if r then Mixfix.Infixr (s, j)
   603       else Mixfix.Infix (s, j))
   608       else Mixfix.Infix (s, j))
   604   | NONE => NONE);
   609   | NONE => NONE);