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); |