71 ((lhs, new_prod as (rhs, name, pri)) :: ps) = |
71 ((lhs, new_prod as (rhs, name, pri)) :: ps) = |
72 let |
72 let |
73 val chain_from = case (pri, rhs) of (~1, [Nonterminal (id, ~1)]) => SOME id | _ => NONE; |
73 val chain_from = case (pri, rhs) of (~1, [Nonterminal (id, ~1)]) => SOME id | _ => NONE; |
74 |
74 |
75 (*store chain if it does not already exist*) |
75 (*store chain if it does not already exist*) |
76 val (new_chain, chains') = case chain_from of NONE => (NONE, chains) | SOME from_ => |
76 val (new_chain, chains') = case chain_from of NONE => (NONE, chains) | SOME from => |
77 let val old_tos = these (AList.lookup (op =) chains from_) in |
77 let val old_tos = these (AList.lookup (op =) chains from) in |
78 if member (op =) old_tos lhs then (NONE, chains) |
78 if member (op =) old_tos lhs then (NONE, chains) |
79 else (SOME from_, AList.update (op =) (from_, insert (op =) lhs old_tos) chains) |
79 else (SOME from, AList.update (op =) (from, insert (op =) lhs old_tos) chains) |
80 end; |
80 end; |
81 |
81 |
82 (*propagate new chain in lookahead and lambda lists; |
82 (*propagate new chain in lookahead and lambda lists; |
83 added_starts is used later to associate existing |
83 added_starts is used later to associate existing |
84 productions with new starting tokens*) |
84 productions with new starting tokens*) |
408 Pretty.block (Pretty.breaks (pretty_name name @ |
408 Pretty.block (Pretty.breaks (pretty_name name @ |
409 map pretty_symb symbs @ pretty_const const @ pretty_pri pri)); |
409 map pretty_symb symbs @ pretty_const const @ pretty_pri pri)); |
410 |
410 |
411 fun pretty_nt (name, tag) = |
411 fun pretty_nt (name, tag) = |
412 let |
412 let |
413 fun prod_of_chain from_ = ([Nonterminal (from_, ~1)], "", ~1); |
413 fun prod_of_chain from = ([Nonterminal (from, ~1)], "", ~1); |
414 |
414 |
415 val nt_prods = |
415 val nt_prods = |
416 Library.foldl (gen_union op =) ([], map snd (snd (Array.sub (prods, tag)))) @ |
416 Library.foldl (gen_union op =) ([], map snd (snd (Array.sub (prods, tag)))) @ |
417 map prod_of_chain ((these o AList.lookup (op =) chains) tag); |
417 map prod_of_chain ((these o AList.lookup (op =) chains) tag); |
418 in map (pretty_prod name) nt_prods end; |
418 in map (pretty_prod name) nt_prods end; |
550 | mk_chain_prods ((to, froms) :: cs) result = |
550 | mk_chain_prods ((to, froms) :: cs) result = |
551 let |
551 let |
552 val to_tag = convert_tag to; |
552 val to_tag = convert_tag to; |
553 |
553 |
554 fun make [] result = result |
554 fun make [] result = result |
555 | make (from_ :: froms) result = make froms ((to_tag, |
555 | make (from :: froms) result = make froms ((to_tag, |
556 ([Nonterminal (convert_tag from_, ~1)], "", ~1)) :: result); |
556 ([Nonterminal (convert_tag from, ~1)], "", ~1)) :: result); |
557 in mk_chain_prods cs (make froms [] @ result) end; |
557 in mk_chain_prods cs (make froms [] @ result) end; |
558 |
558 |
559 val chain_prods = mk_chain_prods chains2 []; |
559 val chain_prods = mk_chain_prods chains2 []; |
560 |
560 |
561 (*convert prods2 array to productions*) |
561 (*convert prods2 array to productions*) |