src/Pure/Syntax/parser.ML
changeset 67545 26a6af52f1f9
parent 67544 f686e756badb
child 67549 7b399522d6c1
equal deleted inserted replaced
67544:f686e756badb 67545:26a6af52f1f9
     1 (*  Title:      Pure/Syntax/parser.ML
     1 (*  Title:      Pure/Syntax/parser.ML
     2     Author:     Carsten Clasohm, Sonia Mahjoub, and Markus Wenzel, TU Muenchen
     2     Author:     Carsten Clasohm, Sonia Mahjoub
     3 
     3     Author:     Makarius
     4 General context-free parser for the inner syntax of terms, types, etc.
     4 
       
     5 General context-free parser for the inner syntax of terms and types.
     5 *)
     6 *)
     6 
     7 
     7 signature PARSER =
     8 signature PARSER =
     8 sig
     9 sig
     9   type gram
    10   type gram
    26 
    27 
    27 (** datatype gram **)
    28 (** datatype gram **)
    28 
    29 
    29 (* nonterminals *)
    30 (* nonterminals *)
    30 
    31 
    31 (*production for the NTs are stored in a vector
    32 (*production for the NTs are stored in a vector, indexed by the NT tag*)
    32   so we can identify NTs by their index*)
       
    33 type nt = int;
    33 type nt = int;
       
    34 
       
    35 type tags = nt Symtab.table;
       
    36 val tags_empty: tags = Symtab.empty;
       
    37 fun tags_content (tags: tags) = sort_by #1 (Symtab.dest tags);
       
    38 fun tags_lookup (tags: tags) = Symtab.lookup tags;
       
    39 fun tags_insert tag (tags: tags) = Symtab.update_new tag tags;
       
    40 fun tags_name (tags: tags) = the o Inttab.lookup (Inttab.make (map swap (Symtab.dest tags)));
    34 
    41 
    35 type nts = Inttab.set;
    42 type nts = Inttab.set;
    36 val nts_empty: nts = Inttab.empty;
    43 val nts_empty: nts = Inttab.empty;
    37 val nts_merge: nts * nts -> nts = Inttab.merge (K true);
    44 val nts_merge: nts * nts -> nts = Inttab.merge (K true);
    38 fun nts_insert nt : nts -> nts = Inttab.insert_set nt;
    45 fun nts_insert nt : nts -> nts = Inttab.insert_set nt;
    70 fun tokens_find P (tokens: tokens) =
    77 fun tokens_find P (tokens: tokens) =
    71   Tokens.get_first (fn (tok, ()) => if P tok then SOME tok else NONE) tokens;
    78   Tokens.get_first (fn (tok, ()) => if P tok then SOME tok else NONE) tokens;
    72 fun tokens_add (nt: nt, tokens) = if tokens_is_empty tokens then I else cons (nt, tokens);
    79 fun tokens_add (nt: nt, tokens) = if tokens_is_empty tokens then I else cons (nt, tokens);
    73 
    80 
    74 
    81 
       
    82 (* productions *)
       
    83 
    75 datatype symb =
    84 datatype symb =
    76   Terminal of Lexicon.token
    85   Terminal of Lexicon.token |
    77 | Nonterminal of nt * int;  (*(tag, precedence)*)
    86   Nonterminal of nt * int;  (*(tag, prio)*)
    78 
    87 
    79 type prods = (symb list * string * int) list Tokens.table;  (*start_token ~> [(rhs, name, prio)]*)
    88 type prods = (symb list * string * int) list Tokens.table;  (*start_token ~> [(rhs, name, prio)]*)
    80 
    89 
    81 val prods_empty: prods = Tokens.empty;
    90 val prods_empty: prods = Tokens.empty;
    82 fun prods_lookup (prods: prods) = Tokens.lookup_list prods;
    91 fun prods_lookup (prods: prods) = Tokens.lookup_list prods;
    83 fun prods_update entry : prods -> prods = Tokens.update entry;
    92 fun prods_update entry : prods -> prods = Tokens.update entry;
    84 fun prods_content (prods: prods) = distinct (op =) (maps #2 (Tokens.dest prods));
    93 fun prods_content (prods: prods) = distinct (op =) (maps #2 (Tokens.dest prods));
    85 
    94 
    86 type nt_gram =
    95 type nt_gram = (nts * tokens) * prods; (*dependent_nts, start_tokens, prods*)
    87   ((nts * tokens) * prods);
    96   (*depent_nts is a set of all NTs whose lookahead depends on this NT's lookahead*)
    88   (*(([dependent_nts], [start_tokens]), prods)*)
       
    89   (*depent_nts is a list of all NTs whose lookahead depends on this NT's lookahead*)
       
    90 
    97 
    91 val nt_gram_empty: nt_gram = ((nts_empty, tokens_empty), prods_empty);
    98 val nt_gram_empty: nt_gram = ((nts_empty, tokens_empty), prods_empty);
    92 
       
    93 type tags = nt Symtab.table;
       
    94 val tags_empty: tags = Symtab.empty;
       
    95 fun tags_content (tags: tags) = sort_by #1 (Symtab.dest tags);
       
    96 fun tags_lookup (tags: tags) = Symtab.lookup tags;
       
    97 fun tags_insert tag (tags: tags) = Symtab.update_new tag tags;
       
    98 fun tags_name (tags: tags) = the o Inttab.lookup (Inttab.make (map swap (Symtab.dest tags)));
       
    99 
    99 
   100 type chains = unit Int_Graph.T;
   100 type chains = unit Int_Graph.T;
   101 fun chains_preds (chains: chains) = Int_Graph.immediate_preds chains;
   101 fun chains_preds (chains: chains) = Int_Graph.immediate_preds chains;
   102 fun chains_all_preds (chains: chains) = Int_Graph.all_preds chains;
   102 fun chains_all_preds (chains: chains) = Int_Graph.all_preds chains;
   103 fun chains_all_succs (chains: chains) = Int_Graph.all_succs chains;
   103 fun chains_all_succs (chains: chains) = Int_Graph.all_succs chains;
   429             (Pretty.str (name ^ print_pri p ^ " =") :: map pretty_symb symbs @ pretty_const const)));
   429             (Pretty.str (name ^ print_pri p ^ " =") :: map pretty_symb symbs @ pretty_const const)));
   430   in maps pretty_prod (tags_content tags) end;
   430   in maps pretty_prod (tags_content tags) end;
   431 
   431 
   432 
   432 
   433 
   433 
   434 (** Operations on gramars **)
   434 (** operations on grammars **)
   435 
   435 
   436 val empty_gram =
   436 val empty_gram =
   437   Gram
   437   Gram
   438    {nt_count = 0,
   438    {nt_count = 0,
   439     prod_count = 0,
   439     prod_count = 0,