src/Pure/Syntax/parser.ML
changeset 80972 7c1e73540990
parent 80970 74ba8ec496c1
child 80973 0326af18b7a7
equal deleted inserted replaced
80971:2c57002d98e4 80972:7c1e73540990
    59 
    59 
    60 (* productions *)
    60 (* productions *)
    61 
    61 
    62 datatype symb =
    62 datatype symb =
    63   Terminal of Lexicon.token |
    63   Terminal of Lexicon.token |
    64   Nonterminal of nt * int |  (*(tag, prio)*)
    64   Nonterminal of nt * int |  (*(tag, precedence)*)
    65   Markup of Markup.T list * symb list;
    65   Markup of Markup.T list * symb list;
    66 
    66 
    67 type prod = symb list * string * int;  (*rhs, name, prio*)
    67 type prod = symb list * string * int;  (*rhs, name, precedence*)
    68 
    68 
    69 fun make_chain_prod from : prod = ([Nonterminal (from, ~1)], "", ~1);
    69 fun make_chain_prod from : prod = ([Nonterminal (from, ~1)], "", ~1);
    70 
    70 
    71 fun dest_chain_prod (([Nonterminal (from, ~1)], _, ~1): prod) = SOME from
    71 fun dest_chain_prod (([Nonterminal (from, ~1)], _, ~1): prod) = SOME from
    72   | dest_chain_prod _ = NONE;
    72   | dest_chain_prod _ = NONE;
       
    73 
       
    74 val no_prec = ~1;
       
    75 
       
    76 fun until_prec min max ((_, _, p): prod) =
       
    77   (min = no_prec orelse p >= min) andalso (max = no_prec orelse p < max);
       
    78 
    73 
    79 
    74 structure Prods = Table(Tokens.Key);
    80 structure Prods = Table(Tokens.Key);
    75 type prods = prod list Prods.table;
    81 type prods = prod list Prods.table;
    76 
    82 
    77 val prods_empty: prods = Prods.empty;
    83 val prods_empty: prods = Prods.empty;
   591 
   597 
   592 fun process_states (Gram {prods = gram_prods, chains = gram_chains, ...}) stateset i c states =
   598 fun process_states (Gram {prods = gram_prods, chains = gram_chains, ...}) stateset i c states =
   593   let
   599   let
   594     (*get all productions of a NT and NTs chained to it which can
   600     (*get all productions of a NT and NTs chained to it which can
   595       be started by specified token*)
   601       be started by specified token*)
   596     fun prods_for tok nt =
   602     fun prods_for tok nt ok =
   597       let
   603       let
       
   604         fun add prod = ok prod ? cons prod;
   598         fun token_prods prods =
   605         fun token_prods prods =
   599           fold cons (prods_lookup prods tok) #>
   606           fold add (prods_lookup prods tok) #>
   600           fold cons (prods_lookup prods Lexicon.dummy);
   607           fold add (prods_lookup prods Lexicon.dummy);
   601         val nt_prods = #2 o Vector.nth gram_prods;
   608         val nt_prods = #2 o Vector.nth gram_prods;
   602       in fold (token_prods o nt_prods) (chains_all_preds gram_chains [nt]) [] end;
   609       in fold (token_prods o nt_prods) (chains_all_preds gram_chains [nt]) [] end;
   603 
   610 
   604     fun process _ [] (Si, Sii) = (Si, Sii)
   611     fun process _ [] (Si, Sii) = (Si, Sii)
   605       | process used ((S as (info, symbs, ts)) :: States) (Si, Sii) =
   612       | process used ((S as (info, symbs, ts)) :: States) (Si, Sii) =
   615                       if used_prec <= min_prec then
   622                       if used_prec <= min_prec then
   616                         (*wanted precedence has been processed*)
   623                         (*wanted precedence has been processed*)
   617                         (used, map_filter movedot_lambda l)
   624                         (used, map_filter movedot_lambda l)
   618                       else (*wanted precedence hasn't been parsed yet*)
   625                       else (*wanted precedence hasn't been parsed yet*)
   619                         let
   626                         let
   620                           val States2 = map mk_state (get_RHS' min_prec used_prec (prods_for c nt));
   627                           val States2 = map mk_state (prods_for c nt (until_prec min_prec used_prec));
   621                           val States1 = map_filter movedot_lambda l;
   628                           val States1 = map_filter movedot_lambda l;
   622                         in (update_prec (nt, min_prec) used, States1 @ States2) end
   629                         in (update_prec (nt, min_prec) used, States1 @ States2) end
   623                   | NONE => (*nonterminal is parsed for the first time*)
   630                   | NONE => (*nonterminal is parsed for the first time*)
   624                       let val States' = map mk_state (get_RHS min_prec (prods_for c nt))
   631                       let val States' = map mk_state (prods_for c nt (until_prec min_prec no_prec))
   625                       in (Inttab.update (nt, (min_prec, [])) used, States') end);
   632                       in (Inttab.update (nt, (min_prec, [])) used, States') end);
   626               in process used' (new_states @ States) (S :: Si, Sii) end
   633               in process used' (new_states @ States) (S :: Si, Sii) end
   627           | Terminal a :: sa => (*scanner operation*)
   634           | Terminal a :: sa => (*scanner operation*)
   628               let
   635               let
   629                 val (_, _, id, _) = info;
   636                 val (_, _, id, _) = info;