Annotation of researchv10no/cmd/sml/lib/mlyacc/mlyacc.hdr.sml, revision 1.1

1.1     ! root        1: (* ML-Yacc parser generator version 1.0
        !             2: Copyright (c) 1989 by Andrew W. Appel, David R. Tarditi
        !             3: 
        !             4: This software comes with ABSOLUTELY NO WARRANTY.
        !             5: This software is subject only to the PRINCETON STANDARD ML SOFTWARE LIBRARY
        !             6: COPYRIGHT NOTICE, LICENSE AND DISCLAIMER, (in the file "COPYRIGHT",
        !             7: distributed with this software). You may copy and distribute this software;
        !             8: see the COPYRIGHT NOTICE for details and restrictions.
        !             9: *)
        !            10: signature BASESET =
        !            11:    sig
        !            12:       type elem
        !            13:       type base_set
        !            14:       exception Select_arb
        !            15:       val empty: base_set
        !            16:           and insert: elem ->  base_set -> base_set
        !            17:          and exists: elem -> base_set -> bool
        !            18:          and find: elem -> base_set -> elem option
        !            19:          and setfold: ((elem * 'b) -> 'b) -> base_set -> 'b -> 'b
        !            20:          and revsetfold: ((elem * 'b) -> 'b) -> base_set -> 'b -> 'b
        !            21:          and elem_gt: (elem * elem -> bool)
        !            22:          and elem_eq: (elem * elem -> bool)
        !            23:           and select_arb: base_set -> elem
        !            24:          and set_eq: (base_set * base_set) -> bool
        !            25:          and set_gt: (base_set * base_set) -> bool
        !            26:          and app : (elem -> 'a) -> base_set -> unit
        !            27:    end;
        !            28: 
        !            29: signature FULLSET =
        !            30:    sig
        !            31:       type set
        !            32:       type elem
        !            33:       exception Select_arb
        !            34:       val card: set -> int
        !            35:          and app: (elem -> 'b) -> set -> unit
        !            36:          and set_eq: (set * set) -> bool
        !            37:          and set_gt: (set * set) -> bool
        !            38:          and find : elem -> set ->  elem option
        !            39:          and exists: elem -> set -> bool
        !            40:           and contained: elem -> (set -> bool)
        !            41:           and difference: set * set -> set
        !            42:           and elem_eq: (elem * elem -> bool)
        !            43:          and elem_gt : (elem * elem -> bool)
        !            44:           and empty: set
        !            45:           and insert: elem -> set -> set
        !            46:           and is_empty: set -> bool
        !            47:           and make_list: set -> elem list
        !            48:           and make_set: (elem list -> set)
        !            49:           and remove: (elem * set) -> set
        !            50:           and same_set: set * set -> bool
        !            51:           and partition: (elem -> bool) -> (set -> set * set)
        !            52:          and revsetfold: ((elem * 'b) -> 'b) -> set -> 'b -> 'b
        !            53:          and setfold: ((elem * 'b) -> 'b) -> set -> 'b -> 'b
        !            54:           and select_arb: set -> elem
        !            55:           and singleton: (elem -> set)
        !            56:           and union: set * set -> set
        !            57:           and closure: set * (elem -> set) -> set
        !            58:    end;
        !            59: 
        !            60: signature GRAPH =
        !            61:    sig
        !            62: 
        !            63:       type node
        !            64:       type edge
        !            65:       type graph
        !            66: 
        !            67:       val null_graph: graph
        !            68:       val nodes_of: graph -> node list
        !            69:       val num_nodes: graph -> int
        !            70:       val join: graph * node * edge * node -> graph
        !            71: 
        !            72:       (* drt(9/12/88) - new functions added because join is inefficient,
        !            73:          if one or both of the nodes already exist *)
        !            74: 
        !            75:       val add_edge : graph * node * edge * node -> graph
        !            76:       val add_node : graph * node -> graph
        !            77: 
        !            78:       (* set of graph edges: records of {From:node, Edge:edge, To:node} *)
        !            79: 
        !            80: 
        !            81:       structure EdgeSet : FULLSET
        !            82:         
        !            83:       val edges: graph * node -> EdgeSet.set  (* all edges from a node *)
        !            84:       val all_edges : graph -> EdgeSet.set
        !            85: 
        !            86:       val find_node : graph * node -> node option
        !            87: 
        !            88: end;
        !            89: 
        !            90: signature BUSY =
        !            91:    sig
        !            92:       val dot: unit -> unit
        !            93:       val star: unit -> unit
        !            94:       val print: string -> unit
        !            95:       val println: string -> unit
        !            96: 
        !            97:       val withSpace: ('a -> unit) -> ('a -> unit)
        !            98:       val withNewline: ('a -> unit) -> ('a -> unit)
        !            99: 
        !           100:       val withDot: ('a -> 'b) -> 'a -> 'b
        !           101: 
        !           102:       val sendto_list : unit -> unit
        !           103:       val sendto_file : outstream -> unit
        !           104: 
        !           105:       val get_list : unit -> string list
        !           106:    end;
        !           107: 
        !           108: signature MEMO =
        !           109:    sig
        !           110:       type Arg
        !           111: 
        !           112:       val memo_fn: ((Arg * Arg) -> bool) -> ((Arg -> '2a) -> (Arg -> '2a))
        !           113: 
        !           114:       exception Enum_memo_fn
        !           115: 
        !           116:       val enum_memo_fn: ((Arg -> int) * int) -> ((Arg -> '2a) -> (Arg -> '2a))
        !           117: 
        !           118:       exception Catalog
        !           119: 
        !           120:       val catalog: {tag: Arg -> 'tag,
        !           121:                     ordOfTag: 'tag -> int,
        !           122:                     items: Arg list
        !           123:                    } -> ('tag -> Arg list)
        !           124:    end;
        !           125: signature V2_LR_GRAMMAR =
        !           126:    sig
        !           127:       datatype Terminal = T of int
        !           128:       and Nonterminal = NT of int
        !           129: 
        !           130:       datatype Symbol = TERM of Terminal
        !           131:                       | NONTERM of Nonterminal
        !           132: 
        !           133:       datatype Attribute = ATTRIB of {lhs: Nonterminal,
        !           134:                                       rhsLength: int,
        !           135:                                       num : int
        !           136:                                      }
        !           137: 
        !           138:       datatype Rule = RULE of {lhs: Nonterminal,
        !           139:                                rhs: Symbol list,
        !           140:                                attribute: Attribute,
        !           141:                                precedence: int option
        !           142:                               }
        !           143: 
        !           144:       val termHash: Terminal -> int
        !           145:       val nontermHash: Nonterminal -> int
        !           146: 
        !           147:       val eqTerminal: Terminal * Terminal -> bool
        !           148:       val eqNonterminal: Nonterminal * Nonterminal -> bool
        !           149:        
        !           150:       val gtTerminal: Terminal * Terminal -> bool
        !           151:       val gtNonterminal: Nonterminal * Nonterminal -> bool
        !           152:    end;
        !           153: signature V2_LSET =
        !           154:    sig
        !           155:       structure G : V2_LR_GRAMMAR
        !           156:       type Lookahead 
        !           157:       val emptylookahead : Lookahead
        !           158: 
        !           159:       (* Sets the bool ref to true if lookahead arg 1
        !           160:         set - lookahead arg 2 set <> null, i.e. if merging the 2 lookahead
        !           161:         sets adds something to lookahead arg 1 set 
        !           162:       *)
        !           163: 
        !           164:       val mergelookahead : ((Lookahead * Lookahead) * bool ref) -> Lookahead
        !           165: 
        !           166:        (* returns true if any terminal in the terminal list is not in
        !           167:          was not already in the lookahead set
        !           168:        *)
        !           169: 
        !           170:       val addterms: Lookahead * G.Terminal list -> Lookahead
        !           171:       val makelookaheadlist : Lookahead -> G.Terminal list
        !           172:    end
        !           173: 
        !           174: signature V2_LR_UTILS =
        !           175:    sig
        !           176:       structure G: V2_LR_GRAMMAR
        !           177:       structure CoreSet : FULLSET
        !           178:       structure Lset : V2_LSET
        !           179: 
        !           180:       datatype Core = CORE of { I : {coreLHS: G.Nonterminal,
        !           181:                                     corePrecedence: int option,
        !           182:                                     coreAttribute: G.Attribute},
        !           183:                                coreRHSbefore: G.Symbol list,
        !           184:                                coreRHSafter: G.Symbol list,
        !           185:                               prop: bool ref,
        !           186:                               lookaheads : Lset. Lookahead ref
        !           187:                               }
        !           188: 
        !           189:       sharing type CoreSet.elem = Core
        !           190: 
        !           191:       val eqSymbol: G.Symbol * G.Symbol -> bool
        !           192:       val gtSymbol: G.Symbol * G.Symbol -> bool
        !           193: 
        !           194:       val eqCore: Core * Core -> bool
        !           195:       val gtCore: Core * Core -> bool
        !           196: 
        !           197:       val mkshowSymbol: {showTerminalClass : G.Terminal -> string,
        !           198:                         showNonterminal : G.Nonterminal -> string } ->
        !           199:                         G.Symbol -> string
        !           200: 
        !           201:       val printCore: {showSymbol : G.Symbol -> string,
        !           202:                      showNonterminal : G.Nonterminal -> string,
        !           203:                      showTerminalClass : G.Terminal -> string} -> Core -> unit
        !           204:       val printCoreSet: {printCore : Core -> unit} -> CoreSet.set -> unit
        !           205: 
        !           206:       val mkselectCores: {rules : G.Rule list,
        !           207:                          numNonterminals : int }
        !           208:                                  -> G.Nonterminal -> CoreSet.set
        !           209:       val mkcoreClosure: {rules : G.Rule list,
        !           210:                          numNonterminals : int,
        !           211:                          selectCores : G.Nonterminal -> CoreSet.set
        !           212:                         } -> CoreSet.set -> CoreSet.set
        !           213: 
        !           214:       val immediateSymbols: CoreSet.set -> G.Symbol list
        !           215:       val copyCoreSet : CoreSet.set -> CoreSet.set
        !           216: 
        !           217:       type true
        !           218:       val prop_f_to_c_a :
        !           219:         {first_string : G.Symbol list -> G.Terminal list,
        !           220:          selectCores : G.Nonterminal -> CoreSet.set}  ->
        !           221:                          (CoreSet.set -> unit)
        !           222:       val propagate_l_to_c_a :
        !           223:        {selectCores : G.Nonterminal -> CoreSet.set } ->
        !           224:                (CoreSet.set * bool ref) -> unit
        !           225:       val propagate_l_to_g_i : (Core -> Core) ->
        !           226:                                (((CoreSet.set * G.Symbol * CoreSet.set) *
        !           227:                                   bool ref) -> unit)
        !           228:       val set_prop : (G.Symbol list -> bool) -> (CoreSet.set -> unit)
        !           229:       val hardwire_eof : (CoreSet.set * G.Terminal * G.Nonterminal) -> unit
        !           230:    end;
        !           231: 
        !           232: signature V2_LR_GRAPH =
        !           233:    sig
        !           234:       structure G: V2_LR_GRAMMAR
        !           235:       structure Lr_Graph : GRAPH
        !           236:       val mkGraph : {rules : G.Rule list, verbose : bool,
        !           237:                     eof : G.Terminal, start : G.Nonterminal,
        !           238:                     termPrecedence : G.Terminal -> int option,
        !           239:                     showTerminalClass : G.Terminal -> string,
        !           240:                     showTerminalValue : G.Terminal -> string,
        !           241:                     showNonterminal : G.Nonterminal -> string,
        !           242:                     showAttribute : G.Attribute -> string,
        !           243:                     numTerminals : int,
        !           244:                     numNonterminals : int
        !           245:                    } -> Lr_Graph.graph
        !           246:    end;
        !           247: 
        !           248: signature V2_LOOKAHEAD =
        !           249:    sig
        !           250:       structure G: V2_LR_GRAMMAR
        !           251:       structure Utils : V2_LR_UTILS
        !           252:       val mkfunctions : {numNonterminals:int,
        !           253:                         selectCores : G.Nonterminal -> Utils.CoreSet.set,
        !           254:                         showNonterminal : G.Nonterminal -> string,
        !           255:                         showTerminalClass : G.Terminal -> string
        !           256:                         } -> {nullable_string : G.Symbol list -> bool,
        !           257:                               first_string : G.Symbol list -> G.Terminal list}
        !           258:    end;
        !           259: signature V2_LR_TABLE =
        !           260:    sig
        !           261:       structure G: V2_LR_GRAMMAR
        !           262:       val mktable :
        !           263:         outstream ->
        !           264:                    {rules : G.Rule list, verbose : bool,
        !           265:                     eof : G.Terminal, start : G.Nonterminal,
        !           266:                     termPrecedence : G.Terminal -> int option,
        !           267:                     showTerminalClass : G.Terminal -> string,
        !           268:                     showTerminalValue : G.Terminal -> string,
        !           269:                     showNonterminal : G.Nonterminal -> string,
        !           270:                     showAttribute : G.Attribute -> string,
        !           271:                     numTerminals : int,
        !           272:                     numNonterminals : int
        !           273:                     } -> unit
        !           274:    end;
        !           275: structure Busy: BUSY =
        !           276:    struct
        !           277:       val len = ref 0
        !           278:       val file = ref std_out           (* file to send output *)
        !           279:       val list = ref (nil : string list)  (* or list to save output on *)
        !           280:       val to_file = ref true           (* true = to file, false = to_list *)
        !           281:       
        !           282:       val sendto_list = fn () => (to_file := false; list := nil)
        !           283:       val sendto_file = fn f => (file := f; to_file := true)
        !           284:       val get_list = fn () => (!list)
        !           285: 
        !           286:       val dots = ref false
        !           287: 
        !           288:       val P = fn x => if (!to_file) then output (!file) x
        !           289:                      else list := x :: (!list)
        !           290: 
        !           291:       fun sym s = (if !len = 75 then (P "\n"; len := 0) else ();
        !           292:                    flush_out (!file);
        !           293:                    P s;
        !           294:                    len := !len + 1;
        !           295:                    dots := true
        !           296:                   )
        !           297: 
        !           298:       fun dot() = sym "."
        !           299:       fun star() = sym "*"
        !           300: 
        !           301:       fun print s = (if !dots then (P "\n"; len := 0) else ();
        !           302:                      dots := false;
        !           303:                      P s;
        !           304:                      len := !len + size s
        !           305:                     );
        !           306: 
        !           307:       fun println s = (print s; P "\n"; len := 0)
        !           308: 
        !           309:       fun withSpace pr = fn x => (pr x; print " ")
        !           310:       fun withNewline pr = fn x => (pr x; println " ")
        !           311: 
        !           312:       fun withDot f a = f a before dot()
        !           313:    end;
        !           314: 
        !           315: functor Memo(type Arg): MEMO =
        !           316:    struct
        !           317:       type Arg = Arg
        !           318:       type 'a relation = 'a * 'a -> bool
        !           319: 
        !           320:       fun memo_fn (Eq: Arg relation) (F: Arg -> '2a) =
        !           321:          let val MemoSet = (ref nil): (Arg * '2a) list ref
        !           322:              fun MemoCall(Arg, (X, Y) :: XYRest, Eq) =
        !           323:                     if Eq(Arg, X) then Y else MemoCall(Arg, XYRest, Eq)   |
        !           324:                  MemoCall(Arg, nil, _) =
        !           325:                     let val Y = F(Arg)
        !           326:                     in  (MemoSet := (Arg, Y) :: !MemoSet; Y)
        !           327:                     end
        !           328: 
        !           329:          in  fn X => MemoCall(X, !MemoSet, Eq)
        !           330:          end
        !           331: 
        !           332:       exception Enum_memo_fn
        !           333:       fun enum_memo_fn (Enum: Arg -> int, Max: int) (F: Arg -> '2a) =
        !           334:          let val MemoArray = array(Max, NONE): '2a option array
        !           335:          in  fn x =>
        !           336:                let val n = Enum(x)
        !           337:                in  case MemoArray sub n of
        !           338:                       NONE => let val y = F(x)
        !           339:                               in  update(MemoArray, n, SOME(y)); y
        !           340:                               end   |
        !           341:                       SOME(y) => y
        !           342:                end
        !           343:                handle Subscript => raise Enum_memo_fn
        !           344:          end
        !           345: 
        !           346:        (* catalog: given a function Tag for getting the selector tag
        !           347:           from any object, bundle the objects to give an efficient selector
        !           348:           function *)
        !           349: 
        !           350:       exception Catalog
        !           351:       fun catalog{tag, ordOfTag, items}: ('tag -> Arg list) =
        !           352:         let val OrdOfThing = ordOfTag o tag
        !           353: 
        !           354:              fun MaxOrdOfTag(Item :: IRest, Result): int =
        !           355:                     (Busy.dot();
        !           356:                      let val ThisOrd = OrdOfThing(Item)
        !           357:                      in  if ThisOrd > Result then MaxOrdOfTag(IRest, ThisOrd)
        !           358:                                              else MaxOrdOfTag(IRest, Result)
        !           359:                      end
        !           360:                     )   |
        !           361:                  MaxOrdOfTag(nil, Result) = Result
        !           362: 
        !           363:              val MaxOrdOfTags =
        !           364:                 (Busy.print "MaxOrdOfTags"; MaxOrdOfTag(items, 0))
        !           365: 
        !           366:              val TheCatalog =
        !           367:                 array(MaxOrdOfTags + 1, NONE): Arg list option array
        !           368: 
        !           369:              fun InsertItem(Item) =
        !           370:                 let val ord = OrdOfThing(Item)
        !           371:                 in  (case TheCatalog sub ord of
        !           372:                         SOME(L) =>
        !           373:                            update(TheCatalog, ord, SOME(Item :: L))   |
        !           374: 
        !           375:                         NONE =>
        !           376:                            update(TheCatalog, ord, SOME [Item])
        !           377:                     ) before Busy.dot()
        !           378:                 end
        !           379: 
        !           380:              val _ = (Busy.print "catalog"; map InsertItem items)
        !           381: 
        !           382:          in  fn Tag => (case TheCatalog sub ordOfTag(Tag) of
        !           383:                            SOME(L) => L   |
        !           384:                            NONE => raise Catalog
        !           385:                        ) handle Subscript => raise Catalog
        !           386:          end
        !           387:    end;
        !           388: 
        !           389: functor BaseSet(B : sig type elem
        !           390:                        val gt : elem * elem -> bool
        !           391:                        val eq : elem * elem -> bool
        !           392:                    end ) : BASESET =
        !           393: 
        !           394: struct
        !           395: 
        !           396:  type elem = B.elem
        !           397:  val elem_gt = B.gt
        !           398:  val elem_eq = B.eq 
        !           399: 
        !           400:  datatype Color = RED | BLACK
        !           401: 
        !           402:  datatype base_set = EMPTY | TREE of (B.elem * Color * base_set * base_set)
        !           403:  exception Select_arb
        !           404:  val empty = EMPTY
        !           405: 
        !           406:  fun insert key t =
        !           407:   let fun f EMPTY = TREE(key,RED,EMPTY,EMPTY)
        !           408:         | f (TREE(k,BLACK,l,r)) =
        !           409:            if elem_gt (key,k)
        !           410:            then case f r
        !           411:                 of r as TREE(rk,RED, rl as TREE(rlk,RED,rll,rlr),rr) =>
        !           412:                        (case l
        !           413:                         of TREE(lk,RED,ll,lr) =>
        !           414:                                TREE(k,RED,TREE(lk,BLACK,ll,lr),
        !           415:                                           TREE(rk,BLACK,rl,rr))
        !           416:                          | _ => TREE(rlk,BLACK,TREE(k,RED,l,rll),
        !           417:                                                TREE(rk,RED,rlr,rr)))
        !           418:                  | r as TREE(rk,RED,rl, rr as TREE(rrk,RED,rrl,rrr)) =>
        !           419:                        (case l
        !           420:                         of TREE(lk,RED,ll,lr) =>
        !           421:                                TREE(k,RED,TREE(lk,BLACK,ll,lr),
        !           422:                                           TREE(rk,BLACK,rl,rr))
        !           423:                          | _ => TREE(rk,BLACK,TREE(k,RED,l,rl),rr))
        !           424:                  | r => TREE(k,BLACK,l,r)
        !           425:            else if elem_gt(k,key)
        !           426:            then case f l
        !           427:                 of l as TREE(lk,RED,ll, lr as TREE(lrk,RED,lrl,lrr)) =>
        !           428:                        (case r
        !           429:                         of TREE(rk,RED,rl,rr) =>
        !           430:                                TREE(k,RED,TREE(lk,BLACK,ll,lr),
        !           431:                                           TREE(rk,BLACK,rl,rr))
        !           432:                          | _ => TREE(lrk,BLACK,TREE(lk,RED,ll,lrl),
        !           433:                                                TREE(k,RED,lrr,r)))
        !           434:                  | l as TREE(lk,RED, ll as TREE(llk,RED,lll,llr), lr) =>
        !           435:                        (case r
        !           436:                         of TREE(rk,RED,rl,rr) =>
        !           437:                                TREE(k,RED,TREE(lk,BLACK,ll,lr),
        !           438:                                           TREE(rk,BLACK,rl,rr))
        !           439:                          | _ => TREE(lk,BLACK,ll,TREE(k,RED,lr,r)))
        !           440:                  | l => TREE(k,BLACK,l,r)
        !           441:            else TREE(key,BLACK,l,r)
        !           442:         | f (TREE(k,RED,l,r)) =
        !           443:            if elem_gt(key,k) then TREE(k,RED,l, f r)
        !           444:            else if elem_gt(k,key) then TREE(k,RED, f l, r)
        !           445:            else TREE(key,RED,l,r)
        !           446:    in case f t
        !           447:       of TREE(k,RED, l as TREE(_,RED,_,_), r) => TREE(k,BLACK,l,r)
        !           448:        | TREE(k,RED, l, r as TREE(_,RED,_,_)) => TREE(k,BLACK,l,r)
        !           449:        | t => t
        !           450:   end
        !           451: 
        !           452:  fun select_arb (TREE(k,_,l,r)) = k
        !           453:    | select_arb EMPTY = raise Select_arb
        !           454:    
        !           455:  fun exists key t =
        !           456:   let fun look EMPTY = false
        !           457:        | look (TREE(k,_,l,r)) =
        !           458:                if elem_gt(k,key) then look l
        !           459:                else if elem_gt(key,k) then look r
        !           460:                else true
        !           461:    in look t
        !           462:    end
        !           463: 
        !           464:  fun find key t =
        !           465:   let fun look EMPTY = NONE
        !           466:        | look (TREE(k,_,l,r)) =
        !           467:                if elem_gt(k,key) then look l
        !           468:                else if elem_gt(key,k) then look r
        !           469:                else SOME k
        !           470:    in look t
        !           471:   end
        !           472: 
        !           473:   fun revsetfold f t start =
        !           474:      let fun scan (EMPTY,value) = value
        !           475:           | scan (TREE(k,_,l,r),value) = scan(r,f(k,scan(l,value)))
        !           476:      in scan(t,start)
        !           477:      end
        !           478: 
        !           479:    fun setfold f t start =
        !           480:        let fun scan(EMPTY,value) = value
        !           481:              | scan(TREE(k,_,l,r),value) = scan(l,f(k,scan(r,value)))
        !           482:        in scan(t,start)
        !           483:        end
        !           484: 
        !           485:    fun app f t =
        !           486:       let fun scan EMPTY = ()
        !           487:             | scan(TREE(k,_,l,r)) = (scan l; f k; scan r)
        !           488:       in scan t
        !           489:       end
        !           490: 
        !           491: (* equal_tree : test if two trees are equal.  Two trees are equal if
        !           492:    the set of leaves are equal *)
        !           493: 
        !           494:    fun set_eq (tree1 as (TREE _),tree2 as (TREE _)) =
        !           495:      let datatype pos = L | R | M
        !           496:         exception Done
        !           497:         fun getvalue(stack as ((a,position)::b)) =
        !           498:            (case a
        !           499:             of (TREE(k,_,l,r)) =>
        !           500:                (case position
        !           501:                 of L => getvalue ((l,L)::(a,M)::b)
        !           502:                  | M => (k,case r of  EMPTY => b | _ => (a,R)::b)
        !           503:                  | R => getvalue ((r,L)::b)
        !           504:                 )
        !           505:              | EMPTY => getvalue b
        !           506:             )
        !           507:            | getvalue(nil) = raise Done
        !           508:          fun f (nil,nil) = true
        !           509:            | f (s1 as (_ :: _),s2 as (_ :: _ )) =
        !           510:                          let val (v1,news1) = getvalue s1
        !           511:                              and (v2,news2) = getvalue s2
        !           512:                          in (elem_eq(v1,v2)) andalso f(news1,news2)
        !           513:                          end
        !           514:            | f _ = false
        !           515:       in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false
        !           516:       end
        !           517:     | set_eq (EMPTY,EMPTY) = true
        !           518:     | set_eq _ = false
        !           519: 
        !           520:    (* gt_tree : Test if tree1 is greater than tree 2 *)
        !           521: 
        !           522:    fun set_gt (tree1,tree2) =
        !           523:      let datatype pos = L | R | M
        !           524:         exception Done
        !           525:         fun getvalue(stack as ((a,position)::b)) =
        !           526:            (case a
        !           527:             of (TREE(k,_,l,r)) =>
        !           528:                (case position
        !           529:                 of L => getvalue ((l,L)::(a,M)::b)
        !           530:                  | M => (k,case r of EMPTY => b | _ => (a,R)::b)
        !           531:                  | R => getvalue ((r,L)::b)
        !           532:                 )
        !           533:              | EMPTY => getvalue b
        !           534:             )
        !           535:            | getvalue(nil) = raise Done
        !           536:          fun f (nil,nil) = false
        !           537:            | f (s1 as (_ :: _),s2 as (_ :: _ )) =
        !           538:                          let val (v1,news1) = getvalue s1
        !           539:                              and (v2,news2) = getvalue s2
        !           540:                          in (elem_gt(v1,v2)) orelse (elem_eq(v1,v2) andalso f(news1,news2))
        !           541:                          end
        !           542:            | f (_,nil) = true
        !           543:            | f (nil,_) = false
        !           544:       in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false
        !           545:       end
        !           546: end
        !           547: 
        !           548: functor FullSet (B : sig type elem
        !           549:                         val eq : (elem*elem) -> bool
        !           550:                         val gt : (elem*elem) -> bool
        !           551:                     end
        !           552:                ) : FULLSET =
        !           553:    struct
        !           554:       structure C = BaseSet(B)
        !           555:       open C
        !           556:       type set = base_set
        !           557: 
        !           558:       fun is_empty(S) = (let val (_) = select_arb(S) in false end
        !           559:                          handle Select_arb => true)
        !           560: 
        !           561:       fun make_list(S) = setfold (fn (a,r) => a::r) S nil
        !           562: 
        !           563:       val contained = exists
        !           564: 
        !           565:       fun make_set l =
        !           566:          List.fold (fn (a,NewSet) => insert a NewSet) l empty
        !           567: 
        !           568:       fun partition F S = setfold (fn (a,(Yes,No)) =>
        !           569:                                if F(a) then (insert a Yes,No)
        !           570:                                else (Yes,insert a No)) 
        !           571:                             S (empty,empty)
        !           572: 
        !           573:       fun remove(X, XSet) =
        !           574:              let val (YSet, _) =
        !           575:                         partition (fn a => not (elem_eq (X, a))) XSet
        !           576:              in  YSet
        !           577:              end
        !           578: 
        !           579:       fun difference(Xs, Ys) =
        !           580:           setfold (fn (a,Xs') => if exists a Ys then Xs' else insert a Xs') Xs 
        !           581:                empty
        !           582: 
        !           583:       fun singleton X = insert X empty
        !           584: 
        !           585:       fun card(S) = setfold (fn (a,count) => count+1) S 0
        !           586: 
        !           587:       val same_set = set_eq
        !           588: 
        !           589:       fun union(Xs,Ys)= setfold (fn (a,Xs) => insert a Xs) Ys Xs
        !           590: 
        !           591:       local
        !           592:            fun closure'(from, f, result) =
        !           593:              if is_empty from then result
        !           594:              else
        !           595:                let val (more,result) =
        !           596:                        setfold (fn (a,(more',result')) =>
        !           597:                                let val more = f a
        !           598:                                    val new = difference(more,result)
        !           599:                                in (union(more',new),union(result',new))
        !           600:                                end) from
        !           601:                                 (empty,result)
        !           602:                in closure'(more,f,result)
        !           603:                end
        !           604:       in
        !           605:          fun closure(start, f) = closure'(start, f, start)
        !           606:       end
        !           607:    end;
        !           608: 
        !           609: functor Graph (B :
        !           610:                sig
        !           611:                  type node
        !           612:                  type edge
        !           613:                  val eq_node : node * node -> bool
        !           614:                  val gt_node : node * node -> bool
        !           615:                  val eq_edge : edge * edge -> bool
        !           616:                  val gt_edge : edge * edge -> bool
        !           617:                end
        !           618:                ) : GRAPH =
        !           619:    struct
        !           620: 
        !           621:        open B
        !           622: 
        !           623:        type graph_edge = {From : node, Edge : edge, To :node }
        !           624: 
        !           625:        fun EqEdge ({From=F1,Edge=E1, To = T1},{From=F2,Edge=E2,To=T2}) =
        !           626:          eq_node (F1,F2) andalso eq_node (T1,T2) andalso eq_edge(E1,E2)
        !           627: 
        !           628:        fun GtEdge ({From=F1,Edge=E1, To = T1},{From=F2,Edge=E2,To=T2}) =
        !           629:          gt_node(F1,F2) orelse (eq_node(F1,F2) andalso
        !           630:                (gt_node(T1,T2) orelse (eq_node(T1,T2) andalso gt_edge(E1,E2))))
        !           631: 
        !           632:        structure N = FullSet (struct
        !           633:                                  type elem = node
        !           634:                                  val eq = eq_node
        !           635:                                  val gt = gt_node
        !           636:                                end 
        !           637:                                )
        !           638: 
        !           639:        structure EdgeSet =  FullSet (struct
        !           640:                                    type elem = graph_edge
        !           641:                                    val eq = EqEdge
        !           642:                                    val gt= GtEdge
        !           643:                                end
        !           644:                                )
        !           645: 
        !           646: 
        !           647:        datatype graph = GRAPH of {TheNodes : N.set, TheEdges : EdgeSet.set} 
        !           648: 
        !           649:        fun find_node (GRAPH {TheNodes, ...},n) = N.find n TheNodes
        !           650: 
        !           651:         val null_graph  = GRAPH {TheNodes = N.empty, TheEdges = EdgeSet.empty}
        !           652: 
        !           653:         fun nodes_of(GRAPH{TheNodes, ...}) = N.make_list TheNodes
        !           654: 
        !           655:         fun num_nodes(GRAPH{TheNodes, ...}) = N.card(TheNodes)
        !           656: 
        !           657:         fun add_node (GRAPH {TheNodes, TheEdges} , n1) =
        !           658:                    GRAPH{TheNodes=N.insert n1 TheNodes, TheEdges=TheEdges}
        !           659: 
        !           660:         fun add_edge (GRAPH {TheNodes, TheEdges}, n1, Edge, n2) =
        !           661:                    let val NewEdges =
        !           662:                             EdgeSet.insert {From=n1, Edge=Edge, To=n2} TheEdges
        !           663:                    in GRAPH {TheNodes=TheNodes, TheEdges=NewEdges}
        !           664:                    end
        !           665: 
        !           666:         fun join (GRAPH{TheNodes, TheEdges},n1, Edge, n2) =
        !           667:                    GRAPH {TheNodes=N.insert n1 (N.insert n2 TheNodes),
        !           668:                          TheEdges= EdgeSet.insert {From=n1,Edge=Edge,
        !           669:                                                    To=n2} TheEdges }
        !           670: 
        !           671:         fun edges ( GRAPH {TheNodes, TheEdges }, n) = 
        !           672:                let fun match {From, Edge,To} = eq_node (From, n)
        !           673:               in EdgeSet.setfold (fn (e,r) =>
        !           674:                   if match e then EdgeSet.insert e r else r)
        !           675:                 TheEdges EdgeSet.empty
        !           676:               end
        !           677: 
        !           678:         fun all_edges(GRAPH{TheEdges, ...}) =  TheEdges
        !           679: 
        !           680:    end;
        !           681: functor V2_Lset (G : V2_LR_GRAMMAR) : V2_LSET = 
        !           682:      struct
        !           683:        open G
        !           684:        structure G = G
        !           685:        abstype Lookahead = LS of (G.Terminal*int) list 
        !           686:        with val emptylookahead = LS nil
        !           687: 
        !           688:             (* mergelookahead - return true as the second element of the
        !           689:                pair if lookahead set 2 contains some elements lookahead
        !           690:                set 1 does not
        !           691:             *)
        !           692: 
        !           693:             fun mergelookahead (p,flag : bool ref) : Lookahead =
        !           694:                let fun f(nil,nil,r) = rev r
        !           695:                       | f(a::a',nil,r) = f(a',nil,a::r)
        !           696:                       | f(nil,b::b',r) = f(b',nil,b::r)
        !           697:                       | f(x as ((a as (_,hash_a))::a'),
        !           698:                           y as ((b as (_,hash_b))::b'),r) =
        !           699:                              if ((hash_a : int ) <  hash_b) then
        !           700:                                  f(a',y,a::r)
        !           701:                              else if (hash_a>hash_b) then
        !           702:                                  f(x,b',b::r)
        !           703:                              else f(a',b',a::r)
        !           704:                in case p of
        !           705:                   (LS a,LS b) =>
        !           706:                      let val r = f(a,b,nil)
        !           707:                      in (if (length a) < (length r) then
        !           708:                             flag := true
        !           709:                         else (); LS r)
        !           710:                      end
        !           711:                 end
        !           712: 
        !           713:            (* addterms - adds terminals to a lookahead set *)
        !           714: 
        !           715:            fun addterms(LS a,l) =
        !           716:                 let fun g(l,e) =
        !           717:                       let val hash_e = termHash e
        !           718:                            fun insert(nil,e) = [(e,hash_e)]
        !           719:                            | insert(t as ((a' as (_,hash_a))::a),e) =
        !           720:                               if (hash_a<hash_e) then a'::(insert(a,e))
        !           721:                               else if (hash_a=hash_e) then t
        !           722:                               else (e,hash_e)::a'::a
        !           723:                       in insert(l,e)
        !           724:                       end
        !           725:                     val r=List.fold (fn (e,r) => g(r,e)) l a
        !           726:                 in LS r
        !           727:                 end
        !           728: 
        !           729:            fun makelookaheadlist (LS a) = List.map (fn (t,_) => t) a
        !           730:        end
        !           731:     end;
        !           732:                    
        !           733: functor V2_LrUtils(structure G : V2_LR_GRAMMAR): V2_LR_UTILS =
        !           734:    struct
        !           735:   
        !           736:       structure G = G
        !           737:       structure Lset = V2_Lset(G)
        !           738:       structure Memo = Memo(type Arg = G.Nonterminal)
        !           739: 
        !           740:       open G 
        !           741: 
        !           742:       val DEBUG = false
        !           743:       val print = if DEBUG then output std_out
        !           744:                  else Busy.print
        !           745:       val println = if DEBUG then fn x => (print x; print "\n")
        !           746:                    else Busy.println
        !           747:       val withNewline = if DEBUG then (fn pr => fn x => (pr x; print "\n"))
        !           748:                        else Busy.withNewline
        !           749: 
        !           750:      (* diagnostics *)
        !           751:       val mkshowSymbol =
        !           752:        fn {showTerminalClass = showTerminalClass : G.Terminal -> string,
        !           753:            showNonterminal = showNonterminal : G.Nonterminal -> string
        !           754:           } => fn (TERM t) => showTerminalClass t
        !           755:                 | (NONTERM nt) => showNonterminal nt
        !           756: 
        !           757:       fun showSpaced f lst = fold (fn (x, y) => x ^ " " ^ y) (map f lst) ""
        !           758: 
        !           759:       datatype Core = CORE of { I : {coreLHS: G.Nonterminal,
        !           760:                                     corePrecedence: int option,
        !           761:                                     coreAttribute: G.Attribute},
        !           762:                                coreRHSbefore: G.Symbol list,
        !           763:                                coreRHSafter: G.Symbol list,
        !           764:                               prop : bool ref,
        !           765:                               lookaheads : Lset.Lookahead ref
        !           766:                               } 
        !           767: 
        !           768:        
        !           769:       val printCore =
        !           770:        fn {showSymbol=showSymbol: G.Symbol -> string,
        !           771:            showNonterminal=showNonterminal : G.Nonterminal -> string,
        !           772:            showTerminalClass=showTerminalClass : G.Terminal -> string } =>
        !           773:         fn (CORE c) =>
        !           774:          let val {I = {coreLHS=coreLHS, ...}, coreRHSbefore, coreRHSafter,
        !           775:                  prop, lookaheads} = c
        !           776:          in (
        !           777:             print(showNonterminal coreLHS ^ " : "
        !           778:                        ^ showSpaced showSymbol (rev coreRHSbefore)
        !           779:                        ^ "_"
        !           780:                        ^ showSpaced showSymbol coreRHSafter
        !           781:                       );
        !           782:          if DEBUG then
        !           783:            print(" lookaheads: " ^ showSpaced showTerminalClass
        !           784:                        (Lset.makelookaheadlist (!lookaheads))
        !           785:                 )
        !           786:          else ()
        !           787:            )
        !           788:          end
        !           789: 
        !           790:       fun gtSymbol(TERM t1, TERM t2) = gtTerminal(t1,t2)
        !           791:         | gtSymbol(NONTERM nt1, NONTERM nt2) = gtNonterminal(nt1,nt2)
        !           792:         | gtSymbol (TERM _,NONTERM _) = true
        !           793:        | gtSymbol _ = false
        !           794: 
        !           795:       fun eqSymbol(TERM t1, TERM t2) = eqTerminal(t1,t2)
        !           796:         | eqSymbol(NONTERM nt1, NONTERM nt2) =eqNonterminal(nt1,nt2)
        !           797:         | eqSymbol _ = false
        !           798: 
        !           799:       fun eqCore(CORE {I = {coreAttribute = G.ATTRIB {num=n1,...}, ...},
        !           800:                            coreRHSbefore=b1, ...},
        !           801:                 CORE {I = {coreAttribute = G.ATTRIB {num=n2,...}, ...},
        !           802:                            coreRHSbefore = b2, ...}
        !           803:                ) =
        !           804:         (n1 = n2) andalso (length b1 = length b2)
        !           805: 
        !           806:       fun gtCore(CORE {I = {coreAttribute = G.ATTRIB {num=n1,...}, ...},
        !           807:                            coreRHSbefore=b1, ...},
        !           808:                 CORE {I = {coreAttribute = G.ATTRIB {num=n2,...}, ...},
        !           809:                            coreRHSbefore = b2, ...}
        !           810:                ) =
        !           811:          (n1>n2) orelse (n1=n2 andalso (length b1) > length (b2))
        !           812: 
        !           813:       structure CoreSet = FullSet (struct
        !           814:                                        type elem = Core
        !           815:                                        val gt = gtCore
        !           816:                                        val eq = eqCore
        !           817:                                    end)
        !           818: 
        !           819:       fun filter f (x :: xs) = if f x then x :: filter f xs else filter f xs
        !           820:         | filter f nil = nil
        !           821: 
        !           822:       fun buildCore(RULE{lhs, rhs, attribute, precedence}) =
        !           823:          CORE({I = {coreLHS=lhs,
        !           824:                     corePrecedence=precedence,
        !           825:                     coreAttribute=attribute},
        !           826:                coreRHSbefore=nil,
        !           827:                coreRHSafter=rhs,
        !           828:               prop=ref false,
        !           829:               lookaheads=ref Lset.emptylookahead
        !           830:               }
        !           831:              )
        !           832: 
        !           833:       fun copyCore(a as (CORE c)) =
        !           834:         case c
        !           835:           of {I,coreRHSbefore, coreRHSafter, ...} =>
        !           836:             CORE({I=I,
        !           837:                   coreRHSbefore=coreRHSbefore,
        !           838:                   coreRHSafter=coreRHSafter,
        !           839:                   prop=ref false,
        !           840:                   lookaheads = ref Lset.emptylookahead
        !           841:                   })
        !           842: 
        !           843:        val copyCoreSet  = fn s =>
        !           844:           CoreSet.setfold (fn (a,r)=> CoreSet.insert (copyCore a) r) s
        !           845:           CoreSet.empty
        !           846: 
        !           847:       val printCoreSet = fn {printCore = printCore : Core -> unit} =>
        !           848:           let val printCoreIndented = fn core =>
        !           849:                (print "   "; withNewline printCore core)
        !           850:           in fn cores => CoreSet.app printCoreIndented cores
        !           851:           end
        !           852: 
        !           853:       val buildCores = fn rules => fn nt =>
        !           854:          let val matchingProds =
        !           855:                 filter (fn RULE{lhs, ...} => eqNonterminal(lhs, nt))
        !           856:                        rules
        !           857: 
        !           858:              val cores = CoreSet.make_set (map buildCore matchingProds)
        !           859:          in
        !           860: (*
        !           861:             if DEBUG then
        !           862:                (println("buildCores " ^ showNonterminal nt);
        !           863:                 printCoreSet cores
        !           864:                )
        !           865:             else
        !           866: *)              ();
        !           867: 
        !           868:             cores
        !           869:          end
        !           870: 
        !           871:       val mkselectCores =
        !           872:         fn {rules=rules : G.Rule list,numNonterminals=n : int} =>
        !           873:           (Memo.enum_memo_fn (G.nontermHash, n))
        !           874:            (buildCores rules)
        !           875: 
        !           876:       fun immediateSymbols cores =
        !           877:        CoreSet.setfold
        !           878:           (fn (CORE {coreRHSafter,...},result) =>
        !           879:                case coreRHSafter
        !           880:                  of sym :: _ =>
        !           881:                     if (exists (fn a => eqSymbol(a,sym)) result)
        !           882:                      then result
        !           883:                      else sym::result
        !           884:                   | nil => result
        !           885:            ) cores nil
        !           886: 
        !           887: 
        !           888:         datatype true = T of Nonterminal | F
        !           889: 
        !           890:        (* Transitive closure : assumes array is an array of row arrays,
        !           891:           where entry a(i,j) is true if the ith item is connected to the
        !           892:           jth item, i.e. if the nonterminal with hash # i will cause all
        !           893:           the productions of the nonterminal with hash # j to be added to a
        !           894:           core set when
        !           895:           a production of the form 'a . B 'b, where hash B = i is
        !           896:           encountered *)
        !           897: 
        !           898:        val transitive_closure = fn  (a : true array array) =>
        !           899:            let val size = Array.length a
        !           900:                val i = ref 0
        !           901:                val j = ref 0
        !           902:                val k = ref 0
        !           903:            in while (!i < size) do
        !           904:                (j := 0; while (!j < size) do
        !           905: 
        !           906:                     (* check if jth nonterm derives ith nonterm *)
        !           907: 
        !           908:                     (case ((a sub !j) sub !i) of
        !           909:                        (T _) =>
        !           910: 
        !           911:                     (* if so then connect jth nonterm w/ everything the
        !           912:                        ith derives
        !           913:                     *)
        !           914:                           (k := 0;
        !           915:                            while (!k < size) do
        !           916:                                (case ((a sub !i) sub !k)
        !           917:                                   of (d as (T  x)) => update(a sub !j,!k,d)
        !           918:                                    | _ => ();
        !           919:                if DEBUG then (
        !           920:                        print ("doing " ^ (makestring (!i)) ^ " " ^
        !           921:                                (makestring (!j)) ^ " " ^ (makestring (!k)) ^
        !           922:                                "\n") 
        !           923:                              )
        !           924:                else ();
        !           925:                                 k := !k +1
        !           926:                                )
        !           927:                            )
        !           928:                      | F => (); j := !j+1
        !           929:                     );
        !           930:                 i := !i + 1
        !           931:                 )
        !           932:            end 
        !           933: 
        !           934:        (* ComputeClosureAdditions - compute the nonterminals which must
        !           935:           be added when one nonterminal with a dot before it is added to
        !           936:           the core set.  Do this by constructing an array indexed by
        !           937:           nonterminal hash #.  Each a[i,j] entry is set to true when 
        !           938:           nonterminal i derives nonterminal j.  Then take the closure
        !           939:           of the array.  (Clearly, if A -> .B, and B -> .C, then A -> .C,
        !           940:           also. *)
        !           941:                
        !           942:        fun ComputeClosureAdditions(rules,max) =
        !           943:            let val a = array(max,array(max,F)) (* re: same subarray, always *)
        !           944:                val _ = let val i = ref 0       (* re: make them different *)
        !           945:                        in while (!i<max) do    (* arrays *)
        !           946:                           (update(a,!i,array(max,F)); i := !i + 1)
        !           947:                        end
        !           948:                val g = fn (RULE {lhs,rhs=(NONTERM n)::_,...}) =>
        !           949:                           update(a sub (nontermHash lhs),nontermHash n,T n)
        !           950:                         | _ => ()
        !           951:            in (app g rules; transitive_closure(a); a)
        !           952:            end
        !           953: 
        !           954:        val ComputeClosureAdditions =
        !           955: (*
        !           956:          if DEBUG then
        !           957:                fn (rules,max) =>
        !           958:                   let val a = ComputeClosureAdditions(rules,max)
        !           959:                       val i = ref 0
        !           960:                   in (while (!i < max) do
        !           961:                        (let val j = ref 0
        !           962:                         in while (!j < max) do
        !           963:                              (case ((a sub !i) sub !j) of
        !           964:                                 T i => print ((showNonterminal i) ^ " ")
        !           965:                                 | F => ();
        !           966:                               j := !j+1)
        !           967:                         end; println ""; i := !i+1
        !           968:                        ); a)
        !           969:                    end
        !           970:          else
        !           971: *)  ComputeClosureAdditions
        !           972: 
        !           973:        (* ComputeCoreSetClosure:
        !           974:        
        !           975:           Takes the closure of a core set.  This consists of adding for
        !           976:         each item with a nonterminal immediately after the dot all
        !           977:         productions for which the nonterminal is the lhs.  This process
        !           978:         is then repeated for the new production.
        !           979: 
        !           980:           We can compute the set of all nonterminals whose productions
        !           981:        must be added when a nonterminal is added using ComputeClosure-
        !           982:        Additions.
        !           983: 
        !           984:           We keep a boolean array indexed by nonterminal hash #'s.  We look
        !           985:        at all the items in the core set.  When we find an item with a non-
        !           986:        terminal immediately after the ., we set the corresponding element
        !           987:        in the bool array to true,s ince we must add all the productions for
        !           988:        that terminal.  We also set the entries for all the nonterminals
        !           989:        which must be added when that nonterminal is added.  This uses the
        !           990:        information from ComputeClosureAdditions.
        !           991: 
        !           992:           Note that we can check the entry for the nonterminal with the dot
        !           993:        before it before doing any of this.  If it is true, since the
        !           994:        relation defined by ComputeClosureAdditions is transitive, all non-
        !           995:        terminals which would need to be added for this nonterminal have
        !           996:        already been added when it was added
        !           997: 
        !           998:           We then take the boolean array, and add all productions for
        !           999:        all nonterminals whose have been set to true.
        !          1000:         *)
        !          1001: 
        !          1002:        fun ComputeCoreSetClosure(cores,a,max,selectCores) =
        !          1003:          (* cores = core set, a = array from ComputeClosureAdditions,
        !          1004:             max = # of nonterminals *)
        !          1005: 
        !          1006:        let val b = array(max,F)
        !          1007:            fun g (CORE c) =
        !          1008:                  let val {coreRHSafter,...} = c
        !          1009:                  in case coreRHSafter of
        !          1010:                     ((NONTERM n) :: _) =>
        !          1011:                        let val num = nontermHash n
        !          1012:                        in case (b sub num) of
        !          1013:                           F => (update(b,num,T n);
        !          1014:                                 let val i = ref 0
        !          1015:                                 in while (!i < max) do
        !          1016:                                  (case ((a sub num) sub !i)
        !          1017:                                     of F => ()
        !          1018:                                      | (m as (T _)) =>
        !          1019:                                            update(b,!i,m);
        !          1020:                                    i := !i + 1
        !          1021:                                   )
        !          1022:                                  end
        !          1023:                                 )
        !          1024:                         | (T _ ) => ()
        !          1025:                        end
        !          1026:                       | _ => ()
        !          1027:                   end
        !          1028:             fun add_cores(cores) =
        !          1029:                 let fun g (i,cores) =
        !          1030:                        case (b sub i) of
        !          1031:                          (T k) => CoreSet.union(cores,
        !          1032:                                        (selectCores k))
        !          1033:                         | F => cores
        !          1034:                     fun f(i,r) =
        !          1035:                         if (i < max) then f(i+1,g(i,r))
        !          1036:                         else r
        !          1037:                 in f(0,cores)
        !          1038:                 end
        !          1039:        in ((CoreSet.app g cores); add_cores cores)
        !          1040:        end
        !          1041: 
        !          1042:        val mkcoreClosure=
        !          1043:                fn {rules=rules:G.Rule list,
        !          1044:                    numNonterminals=numNonterminals:int,
        !          1045:                    selectCores=selectCores:G.Nonterminal->CoreSet.set
        !          1046:                   } => 
        !          1047:        let val a = ComputeClosureAdditions (rules,numNonterminals)
        !          1048:        in fn cores =>
        !          1049:                 ComputeCoreSetClosure(cores,a,numNonterminals,selectCores)
        !          1050:        end
        !          1051: 
        !          1052: (* undefined now : printCoreSet, coreClosure
        !          1053: 
        !          1054:         val coreClosure =
        !          1055:            if DEBUG then
        !          1056:              fn cores =>
        !          1057:                (println "coreClosure of";
        !          1058:                 printCoreSet cores;
        !          1059:                 println "yields";
        !          1060:                 let val cores' = coreClosure cores
        !          1061:                 in
        !          1062:                    printCoreSet cores';
        !          1063:                    cores'
        !          1064:                 end
        !          1065:                )
        !          1066:          else coreClosure
        !          1067: *)
        !          1068: 
        !          1069:        (* prop_f_to_c_a: Propagate firsts to closure additions.
        !          1070:           
        !          1071:           For each item in a core of the form A -> 'a . B 'b, where
        !          1072:           B is a nonterminal, all B productions will contain first_string
        !          1073:           'b in their lookahead set
        !          1074:        *)
        !          1075: 
        !          1076:        val prop_f_to_c_a : {first_string : G.Symbol list -> G.Terminal list,
        !          1077:                             selectCores : G.Nonterminal -> CoreSet.set} ->
        !          1078:                                (CoreSet.set -> unit) =
        !          1079:           fn {first_string = first_string : G.Symbol list -> G.Terminal list,
        !          1080:               selectCores = selectCores : G.Nonterminal -> CoreSet.set}
        !          1081:                  => fn (cores : CoreSet.set) =>
        !          1082: 
        !          1083:                (* f :  check if a core has a . before a nonterminal.
        !          1084:                        If so, propagate the first set of the string
        !          1085:                        following the nonterminal to all the productions
        !          1086:                        derived from the nonterminal
        !          1087:                *)
        !          1088: 
        !          1089:                let val f = fn (CORE {coreRHSafter=(NONTERM b)::r, ...}) =>
        !          1090:                              let val firsts = first_string r
        !          1091:                                  exception ClosureError
        !          1092:                                    val g = fn a =>
        !          1093:                                        case (CoreSet.find a cores) of
        !          1094:                                          NONE => raise ClosureError
        !          1095:                                        | SOME (CORE {lookaheads=l1, ...}) =>
        !          1096:                                           l1 := Lset.addterms(!l1,firsts)
        !          1097:                                in CoreSet.app g (selectCores b)
        !          1098:                                end
        !          1099:                              | _ => ()
        !          1100: 
        !          1101:                in (CoreSet.app f cores)
        !          1102:                end
        !          1103: 
        !          1104:        (* set_prop:  Prop is a boolean variable which is set to true
        !          1105:           for items which propagate their lookaheads to items derived
        !          1106:           from them.  These items have the form 'a .B 'c, where
        !          1107:           'c derives epsilon.  The lookaheads propagate to those items
        !          1108:           derived from B through the closure operation, and to the
        !          1109:           item GOTO('a .B 'c, B).  This function sets prop for all items
        !          1110:           in a core set.
        !          1111:           
        !          1112:        *)
        !          1113: 
        !          1114:        val set_prop = 
        !          1115:           fn (nullable_string : G.Symbol list -> bool) =>
        !          1116:               let val g =  fn (CORE c) =>
        !          1117:                        let val c' = c
        !          1118:                        in case c'
        !          1119:                            of {coreRHSafter=(NONTERM _):: t,prop,...} =>       
        !          1120:                               if (nullable_string t) then prop := true
        !          1121:                               else ()
        !          1122:                             | _ => ()
        !          1123:                        end
        !          1124:               in CoreSet.app g  (* must be applied to a core set now *)
        !          1125:               end
        !          1126: 
        !          1127:        val hardwire_eof = fn (cores,eof,start) =>
        !          1128:           let val f = fn (CORE c) =>
        !          1129:                let val {I={coreLHS=lhs,...},lookaheads,...} = c
        !          1130:                in if (eqNonterminal(lhs,start)) then
        !          1131:                     lookaheads := Lset.addterms(!lookaheads,[eof])
        !          1132:                   else ()
        !          1133:                end
        !          1134:           in CoreSet.app f cores
        !          1135:           end
        !          1136: 
        !          1137:        (* propagate_l_to_c_a: Propagate lookaheads to closure additions.
        !          1138:          If an item in a core has the form A-> 'a .B 'b where B is a
        !          1139:          nonterminal, and 'b derives epsilon, then all productions of
        !          1140:          B get A's lookahead.  Returns true if any change to a
        !          1141:          B productions lookahead occurs.
        !          1142:        *)
        !          1143: 
        !          1144:    val propagate_l_to_c_a = 
        !          1145:       fn {selectCores=selectCores : G.Nonterminal -> CoreSet.set} =>
        !          1146:         fn (cores: CoreSet.set, result : bool ref) =>
        !          1147:            let val f = fn (CORE c) =>
        !          1148:                   case c
        !          1149: 
        !          1150:                     (* Check that a core item has the correct form *)
        !          1151: 
        !          1152:                     of {prop=ref true,coreRHSafter=NONTERM n::_,
        !          1153:                            lookaheads,...}=>
        !          1154:                        let  exception PropClosureError
        !          1155: 
        !          1156:                      (* g: Takes an item whose lookahead depends on the
        !          1157:                            above item, and merges the above item's
        !          1158:                            lookahead into the item's lookahead
        !          1159:                       *)
        !          1160:                            exception PropClosureError
        !          1161: 
        !          1162:                            val g = fn c =>
        !          1163:                               case (CoreSet.find c cores) of
        !          1164:                                  (SOME (CORE {lookaheads=l, ...})) =>
        !          1165:                                        l := Lset.mergelookahead
        !          1166:                                                ((!l,!lookaheads),result)
        !          1167:                                 | NONE => raise PropClosureError
        !          1168: 
        !          1169:                        (* apply g to the items directly derived from 
        !          1170:                           NONTERM n.
        !          1171:                        *)
        !          1172: 
        !          1173:                        in CoreSet.app g (selectCores n)
        !          1174:                        end
        !          1175:                      | _ => ()
        !          1176:           in CoreSet.app f cores
        !          1177:           end
        !          1178: 
        !          1179:        (* propagate_l_to_g_i: Propagate lookaheads to goto items *)
        !          1180: 
        !          1181:        val propagate_l_to_g_i =
        !          1182: 
        !          1183: 
        !          1184:           fn (shiftCore : Core -> Core) =>
        !          1185: 
        !          1186:                (* takes an edge from n1 to n2 *)
        !          1187: 
        !          1188:                fn ((n1: CoreSet.set, e: G.Symbol, n2 : CoreSet.set),result) =>
        !          1189: 
        !          1190:           let 
        !          1191: 
        !          1192:                (* match: merge lookaheads of an item into the items
        !          1193:                   which result from a shift
        !          1194:                *)
        !          1195: 
        !          1196:               val match=
        !          1197:                  fn (a as (CORE {coreRHSafter=b::_,lookaheads=l1,...})) =>
        !          1198:                     if eqSymbol(b,e) then
        !          1199:                        case (CoreSet.find (shiftCore a) n2) 
        !          1200:                            of SOME (CORE {lookaheads=l2,...}) =>
        !          1201:                                 l2 := Lset.mergelookahead((!l2,!l1),result)
        !          1202:                             | NONE => ()
        !          1203:                     else ()
        !          1204:                   | _ => ()
        !          1205:          in (CoreSet.app match n1)
        !          1206:          end
        !          1207:    end;
        !          1208: 
        !          1209: functor V2_Lookahead(structure G : V2_LR_GRAMMAR
        !          1210:                   structure Utils: V2_LR_UTILS
        !          1211:                   sharing Utils.G = G
        !          1212:                  ): V2_LOOKAHEAD =
        !          1213:    struct
        !          1214:       structure NontermMemo = Memo(type Arg = G.Nonterminal)
        !          1215: 
        !          1216:       structure G = G
        !          1217:       structure Utils = Utils
        !          1218:       open G Utils
        !          1219: 
        !          1220:      structure TermSet = FullSet(type elem = Terminal
        !          1221:                                   val gt = gtTerminal
        !          1222:                                   val eq = eqTerminal)
        !          1223: 
        !          1224:      structure NontermSet = FullSet(type elem = Nonterminal
        !          1225:                                    val gt = gtNonterminal
        !          1226:                                      val eq = eqNonterminal)
        !          1227: 
        !          1228:       val DEBUG = false
        !          1229: 
        !          1230:      (* build an enumerated memo-fn over nonterminals *)
        !          1231: 
        !          1232:     val mkfunctions = 
        !          1233:         fn {numNonterminals,selectCores,showNonterminal,showTerminalClass} =>
        !          1234: let 
        !          1235:       val nontermMemo = NontermMemo.enum_memo_fn(nontermHash, numNonterminals)
        !          1236: 
        !          1237:      (* actual print functions (rather than string generators) *)
        !          1238: 
        !          1239:       val printTerminalClass = Busy.print o showTerminalClass
        !          1240:       val printNonterminal = Busy.print o showNonterminal
        !          1241: 
        !          1242:      (* The FIRST set construction functions *)
        !          1243: 
        !          1244:      (* nullable: true if nonterminal "nt" has some null rhs production *)
        !          1245:       fun nullable(nt, cores) =
        !          1246:         CoreSet.setfold (fn (CORE c,rest) => 
        !          1247:           let val {coreRHSafter, ...} = c
        !          1248:           in rest orelse (null coreRHSafter)
        !          1249:           end) cores false
        !          1250: 
        !          1251: 
        !          1252:      (* memo-ise "nullable", add diags *)
        !          1253:       fun prNullable(nt, b) =
        !          1254:          (Busy.println("Nullable " ^ showNonterminal nt ^ "? "
        !          1255:                        ^ case b of true => "YES" | false => "NO"
        !          1256:                       );
        !          1257:           b
        !          1258:          )
        !          1259: 
        !          1260:       val nullable =
        !          1261:          nontermMemo(if DEBUG then
        !          1262:                         fn nt => prNullable(nt, nullable(nt, selectCores nt))
        !          1263:                      else
        !          1264:                         fn nt => nullable(nt, selectCores nt)
        !          1265:                     )
        !          1266: 
        !          1267: (* nullable_string: check if a string of terminals and variables is nullable *)
        !          1268: 
        !          1269:       fun nullable_string (TERM t :: _ ) = false
        !          1270:         | nullable_string (NONTERM t :: r ) =
        !          1271:                         (if nullable t then (nullable_string r) else false)
        !          1272:         | nullable_string nil = true
        !          1273: 
        !          1274:      (* accumulate: look at the start of core right-hand-sides, looking past
        !          1275:        nullable nts, applying addObj to the visible symbols. *)
        !          1276:       fun accumulate(cores, empty, addObj) =
        !          1277:          let
        !          1278:             fun accumAlongSymbols(symbols, result) =
        !          1279:                case symbols
        !          1280:                  of (sym as NONTERM nt) :: rest =>
        !          1281:                        if nullable nt then
        !          1282:                           accumAlongSymbols(rest, addObj(sym, result))
        !          1283:                        else
        !          1284:                           addObj(sym, result)
        !          1285: 
        !          1286:                   | (sym as TERM _) :: _ => addObj(sym, result)
        !          1287: 
        !          1288:                   | nil => result
        !          1289: 
        !          1290:             fun accumAlongCores(cores, result) =
        !          1291:              CoreSet.setfold (fn (CORE c,result) =>
        !          1292:                 let val {coreRHSafter, ...} = c
        !          1293:                 in accumAlongSymbols(coreRHSafter, result)
        !          1294:                 end) cores result
        !          1295:          in
        !          1296:             accumAlongCores(cores, empty)
        !          1297:          end
        !          1298: 
        !          1299: 
        !          1300:      (* first1: the FIRST set of a nonterminal in the grammar. Only looks
        !          1301:        at other terminals, but it *is* clever enough to move past nullable
        !          1302:        nonterminals at the start of a production. *)
        !          1303:       fun first1 nt = accumulate(selectCores nt,
        !          1304:                                 TermSet.empty,
        !          1305:                                  fn (TERM t, set) => TermSet.insert t set
        !          1306:                                   | (_, set) => set
        !          1307:                                 )
        !          1308: 
        !          1309:      (* memo-ise first1, add diags *)
        !          1310:       fun prFirst1(nt, termSet) =
        !          1311:          (Busy.print("First1 set of " ^ showNonterminal nt ^ " = { ");
        !          1312:           TermSet.app (Busy.withSpace printTerminalClass) termSet;
        !          1313:           Busy.println "}";
        !          1314:           termSet)
        !          1315:       val first1 = nontermMemo(if DEBUG then fn nt => prFirst1(nt, first1 nt)
        !          1316:                                else first1
        !          1317:                               )
        !          1318: 
        !          1319:      (* starters1: given a nonterminal "nt", return the set of nonterminals
        !          1320:        which can start its productions. Looks past nullables, but doesn't
        !          1321:        recurse *)
        !          1322:       fun starters1 nt = accumulate(selectCores nt,
        !          1323:                                     NontermSet.empty,
        !          1324:                                     fn (NONTERM nt, set) =>
        !          1325:                                         NontermSet.insert nt set
        !          1326:                                      | (_, set) => set
        !          1327:                                    )
        !          1328: 
        !          1329:      (* memo-ise starters1, add diags *)
        !          1330:       fun prStarters1(nt, nontermSet) =
        !          1331:          (Busy.print("Starters1 set of " ^ showNonterminal nt  ^ " = { ");
        !          1332:           NontermSet.app (Busy.withSpace printNonterminal) nontermSet;
        !          1333:           Busy.println "}";
        !          1334:           nontermSet
        !          1335:          )
        !          1336: 
        !          1337:       val starters1 =
        !          1338:          nontermMemo(if DEBUG then fn nt => prStarters1(nt, starters1 nt)
        !          1339:                      else starters1
        !          1340:                     )
        !          1341: 
        !          1342:      (* starters: a closure over starters1 *)
        !          1343:       fun starters nt = NontermSet.closure(NontermSet.singleton nt, starters1)
        !          1344: 
        !          1345:      (* memo-ise starters, add diags *)
        !          1346:       fun prStarters(nt, nontermSet) =
        !          1347:          (Busy.print("Starters set of " ^ showNonterminal nt  ^ " = { ");
        !          1348:           NontermSet.app (Busy.withSpace printNonterminal) nontermSet;
        !          1349:           Busy.println "}";
        !          1350:           nontermSet
        !          1351:          )
        !          1352: 
        !          1353:       val starters =
        !          1354:          nontermMemo(if DEBUG then fn nt => prStarters(nt, starters nt)
        !          1355:                      else starters
        !          1356:                     )
        !          1357: 
        !          1358:      (* first: maps a nonterminal to its first-set. Get all the starters of
        !          1359:        the nonterminal, get the first1 terminal set of each of these,
        !          1360:        union the whole lot together *)
        !          1361:       fun first nt =
        !          1362:          let val startersSet = starters nt
        !          1363:              val startersList = startersSet
        !          1364:          in 
        !          1365:             NontermSet.setfold (fn (a,r) => TermSet.union(r,first1 a))
        !          1366:                 startersList TermSet.empty
        !          1367:          end
        !          1368: 
        !          1369:      (* memo-ise first, add diags *)
        !          1370:       fun prFirst(nt, termSet) =
        !          1371:          (Busy.print("First set of " ^ showNonterminal nt  ^ " = { ");
        !          1372:           TermSet.app (Busy.withSpace printTerminalClass) termSet;
        !          1373:           Busy.println "}";
        !          1374:           termSet
        !          1375:          )
        !          1376: 
        !          1377:       val first =
        !          1378:          nontermMemo(if DEBUG then fn nt => prFirst(nt, first nt)
        !          1379:                      else first
        !          1380:                     )
        !          1381: 
        !          1382: 
        !          1383: 
        !          1384:      (* prefix: all possible terminals starting a symbol list *)
        !          1385:       fun prefix symbols =
        !          1386:          case symbols
        !          1387:            of TERM t :: _ => TermSet.singleton t
        !          1388:             | NONTERM nt :: rest =>
        !          1389:                  if nullable nt then
        !          1390:                     TermSet.union(first nt, prefix rest)
        !          1391:                  else
        !          1392:                     first nt
        !          1393:             | nil => TermSet.empty
        !          1394: 
        !          1395:        in {first_string = fn n => TermSet.make_list (prefix n),
        !          1396:            nullable_string = nullable_string}
        !          1397:        end
        !          1398:    end
        !          1399: 
        !          1400: functor V2_LrGraph(structure G: V2_LR_GRAMMAR
        !          1401:                 structure Utils: V2_LR_UTILS
        !          1402:                 structure Lookahead: V2_LOOKAHEAD
        !          1403:                sharing Lookahead.Utils = Utils
        !          1404:                 sharing Lookahead.G = Utils.G = G
        !          1405:                ) : V2_LR_GRAPH =
        !          1406:    struct
        !          1407: 
        !          1408:       open G Lookahead Utils
        !          1409: 
        !          1410:       val DEBUG = false
        !          1411: 
        !          1412:      (* type abbrevs for the type of graph we're generating *)
        !          1413:       type State = {state: int, cores: CoreSet.set}
        !          1414: 
        !          1415:       structure Lr_Graph = Graph
        !          1416:         (struct
        !          1417:            type node = {state : int, cores : CoreSet.set }
        !          1418:            type edge = Symbol
        !          1419:            val gt_node = fn ({cores,...}:State,{cores=cores',...}:State) =>
        !          1420:                         CoreSet.set_gt(cores,cores')
        !          1421:             val eq_node = fn ({cores,...}:State,{cores=cores',...}:State) =>
        !          1422:                          CoreSet.set_eq(cores,cores')
        !          1423:            val eq_edge = eqSymbol
        !          1424:            val gt_edge = gtSymbol
        !          1425:           end)
        !          1426:                                    
        !          1427:       type Graph = Lr_Graph.graph
        !          1428: 
        !          1429:      (* the goto function from State * Symbol to State list *)
        !          1430:       fun coreMatch(CORE c, symbol) =
        !          1431:          let val {coreRHSafter, ...} = c
        !          1432:          in
        !          1433:             case coreRHSafter
        !          1434:               of (symbol' :: _) => eqSymbol(symbol, symbol')
        !          1435:                | _ => false
        !          1436:          end
        !          1437: 
        !          1438:       exception ShiftCore
        !          1439:       fun shiftCore (a as (CORE c)) =
        !          1440:          case c
        !          1441:            of {I, coreRHSbefore, coreRHSafter=hd :: tl, prop,lookaheads} =>
        !          1442:                  CORE({I=I,
        !          1443:                        coreRHSbefore=hd :: coreRHSbefore,
        !          1444:                        coreRHSafter=tl,
        !          1445:                       prop=prop,
        !          1446:                        lookaheads = lookaheads
        !          1447:                       }
        !          1448:                      )
        !          1449:             | _ => raise ShiftCore
        !          1450: 
        !          1451: val mkGraph = fn {rules = rules : G.Rule list, verbose = verbose : bool,
        !          1452:                     eof = eof: G.Terminal,start = start: G.Nonterminal,
        !          1453:                     termPrecedence = termPrecedence: G.Terminal -> int option,
        !          1454:                     showTerminalClass=showTerminalClass: G.Terminal -> string,
        !          1455:                     showTerminalValue=showTerminalValue : G.Terminal -> string,
        !          1456:                     showNonterminal=showNonterminal : G.Nonterminal -> string,
        !          1457:                     showAttribute=showAttribute : G.Attribute -> string,
        !          1458:                     numTerminals=numTerminals : int,
        !          1459:                     numNonterminals=numNonterminals : int
        !          1460:                     } =>
        !          1461: let val showSymbol = mkshowSymbol {showTerminalClass=showTerminalClass,
        !          1462:                                   showNonterminal=showNonterminal}
        !          1463:        val printCore = printCore {showSymbol = showSymbol,
        !          1464:                                   showNonterminal = showNonterminal,
        !          1465:                                   showTerminalClass = showTerminalClass}
        !          1466:        val printCoreSet = printCoreSet {printCore=printCore}
        !          1467:        val selectCores = mkselectCores
        !          1468:                {rules=rules,numNonterminals=numNonterminals}
        !          1469:        val coreClosure = mkcoreClosure {rules=rules,
        !          1470:                                         numNonterminals = numNonterminals,
        !          1471:                                         selectCores = selectCores}
        !          1472: 
        !          1473:        val {first_string,nullable_string} = 
        !          1474:                mkfunctions {numNonterminals = numNonterminals,
        !          1475:                             selectCores = selectCores,
        !          1476:                             showNonterminal = showNonterminal,
        !          1477:                             showTerminalClass = showTerminalClass
        !          1478:                             }
        !          1479:      (* the traversal of a set of cores which can shift on "symbol" *)
        !          1480:       fun traversal'(cores, symbol, result) =
        !          1481:        coreClosure(
        !          1482:         CoreSet.setfold (fn (a,result) =>
        !          1483:            if coreMatch(a,symbol) then CoreSet.insert (shiftCore a) result
        !          1484:             else result) cores result
        !          1485:                )
        !          1486: 
        !          1487:      (* include the symbol itself as well, for convenience in graph
        !          1488:        generation *)
        !          1489:       fun traversal cores symbol =
        !          1490:          (symbol, traversal'(cores, symbol, CoreSet.empty))
        !          1491: 
        !          1492:       val NextStateNum = ref 0
        !          1493: 
        !          1494:       val traversal =
        !          1495:          if DEBUG then
        !          1496:             fn cores =>
        !          1497:                fn symbol =>
        !          1498:                   (Busy.println("Traversal by " ^ showSymbol symbol
        !          1499:                                 ^ " gives"
        !          1500:                                );
        !          1501:                    let val (_, cores') = traversal cores symbol
        !          1502:                    in
        !          1503:                       printCoreSet cores';
        !          1504:                       (symbol, cores')
        !          1505:                    end
        !          1506:                   )
        !          1507:          else
        !          1508:             traversal
        !          1509: 
        !          1510:      (* incorporate1: incorporate a traversal from->symbol->cores into
        !          1511:        "graph". Return new graph, and optionally the `to' node, if
        !          1512:        it wasn't already present.
        !          1513:       *)
        !          1514:       fun incorporate1(graph, from: Lr_Graph.node,
        !          1515:                      (symbol, cores : CoreSet.set)) =
        !          1516:          case (Lr_Graph.find_node(graph,{state=0,cores=cores})) of
        !          1517:                SOME existingNode =>
        !          1518:                     (if DEBUG then
        !          1519:                         (Busy.println "*Existing node found:";
        !          1520:                          printCoreSet(#cores(existingNode))
        !          1521:                         )
        !          1522:                      else ();
        !          1523:                      (Lr_Graph.add_edge (graph, from, symbol,existingNode),
        !          1524:                          NONE)
        !          1525:                     )
        !          1526:                | NONE =>
        !          1527:                     let val _ =
        !          1528:                            if DEBUG then
        !          1529:                               (Busy.println("*New state "
        !          1530:                                             ^ makestring (!NextStateNum));
        !          1531:                                printCoreSet cores
        !          1532:                               )
        !          1533:                            else
        !          1534:                        Busy.dot()
        !          1535: 
        !          1536:                         (* make sure every graph node has * UNIQUE * reference
        !          1537:                            variables
        !          1538:                          *)
        !          1539: 
        !          1540:                         val newNode = {cores=copyCoreSet cores,
        !          1541:                                        state=(!NextStateNum)}
        !          1542:                        val _ = NextStateNum := (!NextStateNum)+1
        !          1543:                     in  (Lr_Graph.add_edge (Lr_Graph.add_node (graph,newNode) , from, symbol,
        !          1544:                                   newNode), SOME newNode)
        !          1545:                     end
        !          1546: 
        !          1547:      (* incorporate': takes a graph, a from-node, and a list of traversals
        !          1548:        ((symbol*Core set) list). adds any new nodes to the front of "newNodes"
        !          1549:       *)
        !          1550:       fun incorporate'(graph, from: Lr_Graph.node , traversals, newNodes) =
        !          1551: 
        !          1552:          case traversals
        !          1553:            of this :: rest =>
        !          1554:                  let val (graph', to) = incorporate1(graph, from, this)
        !          1555:                  in  case to
        !          1556:                        of SOME node =>
        !          1557:                              incorporate'(graph', from, rest, node :: newNodes)
        !          1558:                         | NONE => incorporate'(graph', from, rest, newNodes)
        !          1559:                  end
        !          1560:             | nil => (graph, newNodes)
        !          1561: 
        !          1562:       fun generateGraph(events, graph) =
        !          1563:          case events
        !          1564:            of (thisEvent :: restEvents) =>
        !          1565:                  let
        !          1566:                     val {state, cores}: State = thisEvent
        !          1567: 
        !          1568:                     val closuredCores = cores
        !          1569:                     val _ =
        !          1570:                        if DEBUG then
        !          1571:                           (Busy.println("*Collecting on event: "
        !          1572:                                         ^ makestring state
        !          1573:                                        );
        !          1574:                            printCoreSet closuredCores
        !          1575:                           )
        !          1576:                        else ()
        !          1577: 
        !          1578:                     val immedSymbols = immediateSymbols closuredCores
        !          1579: 
        !          1580:                     val prSymbol = (Busy.withSpace Busy.print) o showSymbol
        !          1581:                     val _ =
        !          1582:                        if DEBUG then
        !          1583:                           (Busy.print "*Immediate symbols: { ";
        !          1584:                            map prSymbol immedSymbols;
        !          1585:                            Busy.println "}"
        !          1586:                           )
        !          1587:                        else ()
        !          1588: 
        !          1589:                     val traversals =
        !          1590:                         List.fold (fn (immed_symbol,r) =>
        !          1591:                           (traversal closuredCores immed_symbol) :: r)
        !          1592:                            immedSymbols nil
        !          1593: 
        !          1594:                     val (newGraph, newEvents) =
        !          1595:                        incorporate'(graph, thisEvent, traversals,restEvents)
        !          1596:                  in
        !          1597:                     generateGraph(newEvents, newGraph)
        !          1598:                  end
        !          1599: 
        !          1600:             | _ => graph
        !          1601: 
        !          1602:      (* propagate lookaheads : propagate lookaheads throughout the 
        !          1603:        graph 
        !          1604:        *)
        !          1605: 
        !          1606:      val propagatelookaheads = fn (g : Lr_Graph.graph) =>
        !          1607:        let val cores = Lr_Graph.nodes_of g
        !          1608:            val cores = List.map (fn c => #cores c) cores
        !          1609:            val edges = List.map (fn {From,Edge,To} =>
        !          1610:                                (#cores(From),Edge,#cores(To)))
        !          1611:                            (Lr_Graph.EdgeSet.make_list (Lr_Graph.all_edges g))
        !          1612:            val gp = ref true;
        !          1613:            val cp = ref true;
        !          1614:            val _ = List.app (set_prop nullable_string) cores
        !          1615:            val _ = List.app (prop_f_to_c_a {first_string=first_string,
        !          1616:                                             selectCores=selectCores}) cores
        !          1617:            val closure_prop = fn c =>
        !          1618:                 propagate_l_to_c_a {selectCores=selectCores} (c,cp)
        !          1619:            val goto_prop = 
        !          1620:                let val goto_prop' = propagate_l_to_g_i shiftCore
        !          1621:                in fn e => goto_prop'(e,gp)
        !          1622:                end
        !          1623:        in while (!gp = true orelse !cp = true) do
        !          1624:           (gp := false; cp := false;
        !          1625:            output std_out "Propagating lookaheads ...\n";
        !          1626:            List.app closure_prop cores;
        !          1627:            List.app goto_prop edges
        !          1628:           )
        !          1629:        end
        !          1630:            
        !          1631:      (* generate the graph *)
        !          1632:       val startCores = copyCoreSet(coreClosure(selectCores start))
        !          1633:       val startEvent = {cores=startCores, state=0}
        !          1634: 
        !          1635:       val _ = if DEBUG then () else Busy.print "Generating State Graph"
        !          1636: 
        !          1637:       val _ = NextStateNum := 1
        !          1638:       val graph = generateGraph([startEvent],
        !          1639:                   Lr_Graph.add_node(Lr_Graph.null_graph,startEvent))
        !          1640:      
        !          1641:       val _ = hardwire_eof(startCores,eof,start)
        !          1642:       val _ = propagatelookaheads graph
        !          1643:   in graph
        !          1644:   end
        !          1645: end;
        !          1646: functor V2_TableGen(structure G: V2_LR_GRAMMAR): V2_LR_TABLE =
        !          1647:    struct
        !          1648: 
        !          1649:       structure G = G
        !          1650: 
        !          1651:       structure Utils =
        !          1652:        V2_LrUtils(structure G = G)
        !          1653: 
        !          1654:      structure Lookahead =
        !          1655:         V2_Lookahead(structure G = G
        !          1656:                  structure Utils = Utils
        !          1657:                         )
        !          1658: 
        !          1659:       structure Graph =
        !          1660:         V2_LrGraph (
        !          1661:            structure G = G
        !          1662:            structure Utils = Utils
        !          1663:            structure Lookahead = Lookahead
        !          1664:           )
        !          1665: 
        !          1666:       type 'entry Table = 'entry array array
        !          1667: 
        !          1668:       fun PrTable ((pr : string->unit),
        !          1669:                   (T : 'entry Table),
        !          1670:                   (Str: (int * 'entry) -> string),
        !          1671:                   (EncaseRow : ('entry array -> unit) * (string->unit) ->
        !          1672:                                        'entry array -> unit)) =
        !          1673:        let
        !          1674:          val PrintRow = fn (R : 'entry array) =>
        !          1675:             let fun f(i,cnt) =
        !          1676:                if i<Array.length(R) then
        !          1677:                   let val s = Str (i,(R sub i))
        !          1678:                       val cnt = 
        !          1679:                             let val newcount = cnt + size s
        !          1680:                             in if newcount > 73 then (pr "\\\n\\"; size s)
        !          1681:                                 else newcount
        !          1682:                             end
        !          1683:                   in (pr s; f (i+1,cnt))
        !          1684:                   end
        !          1685:                else ()
        !          1686:             in f(0,0)
        !          1687:             end
        !          1688:          fun PrintRows i =
        !          1689:               if i < (Array.length T) then
        !          1690:                      (EncaseRow (PrintRow,pr) (T sub i); PrintRows(i+1))
        !          1691:               else ()
        !          1692:        in PrintRows 0
        !          1693:        end
        !          1694: 
        !          1695:       fun access(tab, row, col) = (tab sub row) sub col
        !          1696: 
        !          1697:      (* Generate a table from an initialisation value. Won't work if the
        !          1698:        actual value contains references *)
        !          1699:       fun genTable(value, r, c) =
        !          1700:              let
        !          1701:                 fun rows 0 = nil
        !          1702:                   | rows m = array(c, value) :: rows(m - 1)
        !          1703:              in
        !          1704:                 arrayoflist(rows r)
        !          1705:              end
        !          1706: 
        !          1707:      (* assign a table entry, using "resolve" to check it against the existing
        !          1708:         entry *)
        !          1709:       fun assign(resolve: ('entry * 'entry) -> 'entry,
        !          1710:                  T: 'entry Table,
        !          1711:                  Row: int, Col: int,
        !          1712:                  newEntry: 'entry) =
        !          1713:              let val R = T sub Row
        !          1714:                  val oldEntry = R sub Col
        !          1715: 
        !          1716:              in  update(R, Col, resolve(oldEntry, newEntry))
        !          1717:              end
        !          1718: 
        !          1719:       type State = int
        !          1720:       fun showState(state: State) = makestring state
        !          1721: 
        !          1722:      (* Specific table stuff *)
        !          1723:       datatype Action = SHIFT of State
        !          1724:                       | REDUCE of G.Attribute
        !          1725:                       | ERROR
        !          1726: 
        !          1727:       type Prec = int option
        !          1728:       type ActionEntry = {action: Action, prec: Prec}
        !          1729:       datatype Goto = GOTO of int option
        !          1730: 
        !          1731:       exception AssignAction (* of ActionEntry * ActionEntry *)
        !          1732:       exception AssignGoto of Goto     (* Returns the current entry *)
        !          1733: 
        !          1734:   (* convert integer between 0 and 65535 to a a 2 byte character
        !          1735:      string representing the integer, with low byte first *)
        !          1736: 
        !          1737: val convert_int = fn (i:int) => 
        !          1738:   if i>(256*256-1) then 
        !          1739:        let exception Convert_int  in raise Convert_int end
        !          1740:   else
        !          1741:        let val make_char = fn (i:int) =>
        !          1742:                let val s = makestring i
        !          1743:                in (substring("\\000",0,1+3 + (~(size s)))) ^ s
        !          1744:                end
        !          1745:        in (make_char (i mod 256)) ^ (make_char (i div 256))
        !          1746:        end
        !          1747: 
        !          1748: local
        !          1749:          val make_entry = fn (i,s) => (convert_int (i+1)) ^ s
        !          1750:          val showAction = fn states => fn (n : int,{action, prec}) =>
        !          1751:                  case action
        !          1752:                     of (REDUCE (G.ATTRIB {num,...})) =>
        !          1753:                         make_entry(n,convert_int(states+num))
        !          1754:                      | (SHIFT i) =>
        !          1755:                          make_entry(n,convert_int(i))
        !          1756:                      | ERROR => ""
        !          1757:            val showGoto =
        !          1758:                fn (n:int,(GOTO(SOME j))) =>
        !          1759:                   make_entry(n,convert_int(j))
        !          1760:                 | _ => ""
        !          1761: in
        !          1762: val printLr_Table = fn (file : outstream, gotos, actions,
        !          1763:                        DisplayAttributes,states) =>
        !          1764: let val pr = output file
        !          1765:     val prln = fn s => (pr s; pr "\n");
        !          1766:     val EncaseRow = fn (PrintRow,pr) => fn r =>
        !          1767:                (PrintRow r; pr (convert_int 0); pr "\\\n\\")
        !          1768:     val PrintTable = fn (table,entry_print) =>
        !          1769:                  (pr "\"\\\n\\";
        !          1770:                   PrTable (pr,table,entry_print,EncaseRow);
        !          1771:                   prln "\"")
        !          1772: in (pr "\
        !          1773: \structure Lr_Table : MLY_LR_TABLE = \n\
        !          1774: \    struct\n\
        !          1775: \     structure G = G\n\
        !          1776: \     open G\n\
        !          1777: \\n\
        !          1778: \     type State = int \n\
        !          1779: \     val initialState = 0 \n\
        !          1780: \     fun showState(state: State) = makestring state \n\
        !          1781: \\n\
        !          1782: \    (* Specific table stuff *) \n\
        !          1783: \     datatype Action = SHIFT of State \n\
        !          1784: \                     | REDUCE of Attribute \n\
        !          1785: \                     | ERROR  \n\
        !          1786: \      datatype Goto = GOTO of State\n";
        !          1787:        pr "local\n\
        !          1788: \              val string_to_int = fn(s,index) => (ordof(s,index) + \n\
        !          1789: \                      ordof(s,index+1)*256,index+2)\n";
        !          1790:        DisplayAttributes(file);
        !          1791:        pr "val numStates =";
        !          1792:        prln (makestring states);
        !          1793:        pr "\
        !          1794: \              val convert_string_to_list = fn conv_func => fn(s,index) =>\n\
        !          1795: \                 let fun f (r,index) =\n\
        !          1796: \                       let val (num,index) = string_to_int(s,index)\n\
        !          1797: \                       in if num=0 then (rev r,index)\n\
        !          1798: \                          else let val (i,index) = string_to_int(s,index)\n\
        !          1799: \                               in f((num-1,(conv_func i))::r,index)\n\
        !          1800: \                               end\n\
        !          1801: \                       end\n\
        !          1802: \                  in f(nil,index)\n\
        !          1803: \                  end\n\
        !          1804: \               val convert_string_to_array = fn conv_func => fn s =>\n\
        !          1805: \                  let val convert_row =convert_string_to_list conv_func\n\
        !          1806: \                      fun f(r,index) =\n\
        !          1807: \                        if (index < size s) then\n\
        !          1808: \                         let val (newlist,index) = convert_row (s,index)\n\
        !          1809: \                         in f(newlist::r,index)\n\
        !          1810: \                         end\n\
        !          1811: \                        else arrayoflist(rev r)\n\
        !          1812: \                  in f(nil,0)\n\
        !          1813: \                  end\n\
        !          1814: \               val int_to_goto = fn i => GOTO i\n\
        !          1815: \\n\
        !          1816: \               val int_to_action = fn i =>\n\
        !          1817: \                      if i >= numStates then\n\
        !          1818: \                              get_attribute(i-numStates)\n\
        !          1819: \                         else SHIFT i\n\
        !          1820: \               val make_goto_table = convert_string_to_array int_to_goto\n\
        !          1821: \               val make_action_table=convert_string_to_array int_to_action\n";
        !          1822:        prln "in";
        !          1823:        prln "val actionT = make_action_table";
        !          1824:        PrintTable(actions,showAction states);
        !          1825:        prln "val gotoT = make_goto_table";
        !          1826:        PrintTable(gotos,showGoto);
        !          1827:        pr "\
        !          1828: \      exception NotThere\n\
        !          1829: \      fun find(((key:int),data)::b,i) =\n\
        !          1830: \              if (i>key) then find(b,i)\n\
        !          1831: \              else if (i<key) then raise NotThere\n\
        !          1832: \              else data\n\
        !          1833: \        | find (nil,i) = raise NotThere\n\
        !          1834: \       fun action(state,T t) =\n\
        !          1835: \              find(actionT sub state,t) handle NotThere => ERROR\n\
        !          1836: \       exception Goto\n\
        !          1837: \       fun goto(state,NT t) =\n\
        !          1838: \              (case find(gotoT sub state,t)\n\
        !          1839: \                 of (GOTO i) => i)\n\
        !          1840: \               handle NotThere => raise Goto\n\
        !          1841: \     end\nend\n")
        !          1842: end
        !          1843: end
        !          1844: 
        !          1845: val mktable = fn dest => fn (ALL as
        !          1846:                    {rules = rules : G.Rule list, verbose=verbose : bool,
        !          1847:                     eof = eof : G.Terminal, start = start: G.Nonterminal,
        !          1848:                     termPrecedence = termPrecedence: G.Terminal -> int option,
        !          1849:                     showTerminalClass= showTerminalClass: G.Terminal -> string,
        !          1850:                     showTerminalValue=showTerminalValue : G.Terminal -> string,
        !          1851:                     showNonterminal=showNonterminal : G.Nonterminal -> string,
        !          1852:                     showAttribute=showAttribute : G.Attribute -> string,
        !          1853:                     numTerminals=numTerminals : int,
        !          1854:                     numNonterminals=numNonterminals : int
        !          1855:                     }) =>
        !          1856: let
        !          1857:       val rr_error = ref false
        !          1858: 
        !          1859:       (* DisplayAttributes: print values for the attributes of the rules,
        !          1860:         of the form a{rule #} = ATTRIB ...   These values are used in
        !          1861:         the printed out version of the Action table. *)
        !          1862: 
        !          1863:        fun DisplayAttributes (f) =
        !          1864:           let val pr = (output f)
        !          1865:           in (pr
        !          1866: "val get_attribute= \n\
        !          1867: \      let val convert_back = fn (s,i) =>\n\
        !          1868: \              let val (lhs,ni) = string_to_int(s,i)\n\
        !          1869: \                  val (rhsLength,ni) = string_to_int(s,ni)\n\
        !          1870: \                  val (num,ni) = string_to_int(s,ni)\n\
        !          1871: \              in (REDUCE(G.ATTRIB{lhs=G.NT lhs,rhsLength=rhsLength,\n\
        !          1872: \                                  num=num}),ni,num)\n\
        !          1873: \              end\n\
        !          1874: \           val numRules =";
        !          1875:               pr (makestring (List.length rules));
        !          1876:               pr "\nval attrib_data =\n\"";
        !          1877:              app(fn (G.RULE {attribute=G.ATTRIB {lhs,rhsLength,num},...}) =>
        !          1878:                    (
        !          1879:                     (* nonterminal number *)
        !          1880: 
        !          1881:                     pr (convert_int (G.nontermHash lhs));
        !          1882: 
        !          1883:                     (* rhs length *) 
        !          1884: 
        !          1885:                     pr (convert_int rhsLength);
        !          1886: 
        !          1887:                     (* num *)
        !          1888: 
        !          1889:                     pr (convert_int num);
        !          1890:                     pr "\\\n\\"
        !          1891:                    )) rules;
        !          1892: 
        !          1893:                pr "\"\n\
        !          1894: \           val attrib_array = array(numRules,ERROR)\n\
        !          1895: \           fun convert_string(s,index) =\n\
        !          1896: \              if (index < (size s)) then\n\
        !          1897: \                 let val (result,newindex,num)=convert_back(s,index)\n\
        !          1898: \                 in (update(attrib_array,num,result);\n\
        !          1899: \                     convert_string(s,newindex))\n\
        !          1900: \                 end\n\
        !          1901: \              else ()\n\
        !          1902: \      in (convert_string(attrib_data,0); fn i => attrib_array sub i)\n\
        !          1903: \      end\n";
        !          1904:          ())
        !          1905:  end
        !          1906: 
        !          1907:       val printTerminalClass = Busy.print o showTerminalClass
        !          1908:       val printNonterminal = Busy.print o showNonterminal
        !          1909: 
        !          1910:       fun srConflict(state, attrib, terminal) =
        !          1911:          (Busy.println(showState state ^ ": " ^ "shift/reduce conflict " ^
        !          1912:                       "(shift " ^ (showTerminalClass terminal) ^ ",reduce " ^
        !          1913:                        showAttribute attrib ^ ")")
        !          1914:          )
        !          1915: 
        !          1916:       fun precConflict(state, attrib, terminal) =
        !          1917:        (Busy.println ((showState state) ^
        !          1918:                ": terminal and rule have the same precedence for the");
        !          1919:         Busy.println ("shift/reduce conflict " ^
        !          1920:                       "(shift " ^ (showTerminalClass terminal) ^ ",reduce " ^
        !          1921:                        showAttribute attrib ^ ")")
        !          1922:        )
        !          1923: 
        !          1924:       fun rrConflict(a1, a2) =
        !          1925:          Busy.println("reduce/reduce conflict between "
        !          1926:                       ^ showAttribute a1 ^ " and " ^ showAttribute a2
        !          1927:                      )
        !          1928:      (* assign an action table entry for state on encountering terminal *)
        !          1929: 
        !          1930:       (* resolve: precedence handling was modified for nonassociative
        !          1931:         terminals.  Before, if a rule's precedence was greater than a
        !          1932:         terminal's a precedence in a s/r conflict, a reduce was planted.
        !          1933:          Otherwise a shift occurred.  If a rule's precedence was equal to
        !          1934:         a terminal's precedence, a shift was planted, but no warning message
        !          1935:          was printed.  This does not allow for proper handling of
        !          1936:         associativities and precedence in a yacc-like parser generator.
        !          1937: 
        !          1938:         In yacc, each terminal may have a precedence and an associativity.
        !          1939:         A terminal may be left associative, right associative,
        !          1940:         or nonassociative.  A rule is usually given the precedence of its
        !          1941:         rightmost terminal.  We want to reduce if the precedence of the
        !          1942:         rule is > the terminal, or if the precedences are = and the terminal
        !          1943:         is left associative.  We want to shift the terminal if the
        !          1944:         precedence of the terminal is higher than the rule's precedence, 
        !          1945:         or if the precedences are equal and the terminal is right associative.
        !          1946:         If the precedences are equal and the terminal is nonassociative
        !          1947:         this is an error condition.
        !          1948:        
        !          1949:         We need to print a diagnostic indicating to the user when the
        !          1950:         precedences of the rule and the terminal are equal.  Then we
        !          1951:         can give the rule precedence x, right associative terminals
        !          1952:         precedence x+1, left associative terminals precedence x-1, and
        !          1953:         nonassociative terminals precedence. x.
        !          1954:        *)
        !          1955: 
        !          1956: 
        !          1957:       fun assignAction(actions, state, terminal, entry) =
        !          1958:        let fun resolve ({action=ERROR, ...}, x) = x
        !          1959:             | resolve (s as {action=SHIFT _, prec=shiftPrec},
        !          1960:                  r as {action=REDUCE a, prec=redPrec}) =
        !          1961:                (case (shiftPrec,redPrec)
        !          1962:                 of (NONE,_) => (srConflict(state, a, terminal); s)
        !          1963:                  | (_,NONE) => (srConflict(state, a, terminal); s)
        !          1964:                  | (SOME (i:int),SOME j) =>
        !          1965:                        if i = j then (precConflict(state, a, terminal); s)
        !          1966:                        else if i > j then s
        !          1967:                        else r
        !          1968:                 )
        !          1969:             | resolve (r as {action=REDUCE _, ...},s as {action=SHIFT _, ...})=
        !          1970:                        resolve(s,r)
        !          1971:             | resolve (r1 as {action=REDUCE a1, ...},
        !          1972:                       r2 as {action=REDUCE a2, ...}) =
        !          1973:                 (rrConflict(a1,a2); rr_error := true; r1)
        !          1974:             | resolve _ = let exception Resolve in raise Resolve end
        !          1975:        in assign(resolve, actions, state, G.termHash terminal, entry)
        !          1976:        end
        !          1977: 
        !          1978:      (* assign a goto entry for a state * nonterminal *)
        !          1979:       fun assignGoto(gotos, state, Nonterminal, Entry) =
        !          1980:              let fun resolve(GOTO NONE, x) = x   |
        !          1981:                      resolve(Old, _) = raise AssignGoto Old
        !          1982:              in
        !          1983:                 assign(resolve, gotos, state, G.nontermHash Nonterminal, Entry)
        !          1984:              end
        !          1985: 
        !          1986:      (* make table entries for all the graph's edges *)
        !          1987:       fun plantEdgeMoves(actions, gotos, allEdges) =
        !          1988:        let val f  = 
        !          1989:                 fn ({From={state=from,...},Edge,To={state=to,...}}
        !          1990:                                : Graph.Lr_Graph.EdgeSet.elem) =>
        !          1991:                        case Edge
        !          1992:                             of G.TERM t =>
        !          1993:                                assignAction(actions, from, t,
        !          1994:                                  {action=SHIFT to, prec=termPrecedence t})
        !          1995:                         | G.NONTERM nt =>
        !          1996:                                  assignGoto(gotos, from, nt, GOTO(SOME to))
        !          1997:        in Graph.Lr_Graph.EdgeSet.app f allEdges
        !          1998:        end
        !          1999: 
        !          2000:      (* plant all reductions from a particular state *)
        !          2001:       fun plantReductions actions (state,r) =
        !          2002:          let val {cores, state} = state
        !          2003: 
        !          2004:             (* plant a reduction for a core item if the dot is at the end of
        !          2005:                the item *)
        !          2006: 
        !          2007:             val plantReduction =
        !          2008:                 fn  Utils.CORE {coreRHSafter=nil,lookaheads,
        !          2009:                                 I={corePrecedence, coreAttribute, ...},
        !          2010:                                 ...} =>
        !          2011: 
        !          2012:                        (* plant a reduction for each terminal in the
        !          2013:                           lookahead set *)
        !          2014: 
        !          2015:                        List.app (fn lookahead =>
        !          2016:                                assignAction(actions,state,lookahead,
        !          2017:                                     {action=REDUCE coreAttribute,
        !          2018:                                      prec=corePrecedence})
        !          2019:                          ) (Utils.Lset.makelookaheadlist (!lookaheads))
        !          2020: 
        !          2021:                     | _ => ()
        !          2022:             val closuredCores = (* coreClosure *) cores
        !          2023: 
        !          2024:          in (Busy.sendto_list();
        !          2025:              Utils.CoreSet.app plantReduction closuredCores;
        !          2026:             case Busy.get_list()
        !          2027:                of nil => r
        !          2028:                 | l => (state,l)::r)
        !          2029:          end
        !          2030: 
        !          2031:      (* plant all reductions for all states *)
        !          2032: 
        !          2033:       fun plantStates(actions: ActionEntry Table,
        !          2034:                      states: Graph.Lr_Graph.node list) =
        !          2035:          List.fold (fn (state,r) => (plantReductions actions) (state,r))
        !          2036:                         states nil;
        !          2037: 
        !          2038:      (*  Generate graph *)
        !          2039: 
        !          2040:        val graph = Graph.mkGraph ALL;
        !          2041:        val theNodes = Graph.Lr_Graph.nodes_of graph
        !          2042:        val theEdges = Graph.Lr_Graph.all_edges graph
        !          2043:        val numNodes = Graph.Lr_Graph.num_nodes graph
        !          2044: 
        !          2045:         val actions=genTable({action=ERROR,prec=NONE},numNodes, numTerminals)
        !          2046:         val gotos = genTable(GOTO NONE, numNodes, numNonterminals)
        !          2047: 
        !          2048:       in (Busy.println "Filling Tables";
        !          2049:          if verbose then
        !          2050:           (let val outfile = open_out "y.output"
        !          2051:                val allerrs =  (plantEdgeMoves(actions,gotos,theEdges);
        !          2052:                                plantStates(actions,theNodes))
        !          2053:                val errmsgs = fn state =>
        !          2054:                    fold (fn ((s,l),r) => if s=state then l::r else r) allerrs
        !          2055:                        nil
        !          2056:                val _ = Busy.sendto_file outfile
        !          2057:                val printCore = Utils.printCore
        !          2058:                         {showSymbol = (Utils.mkshowSymbol
        !          2059:                                        ({showTerminalClass=showTerminalClass,
        !          2060:                                          showNonterminal=showNonterminal})
        !          2061:                                        ),
        !          2062:                           showTerminalClass = showTerminalClass,
        !          2063:                           showNonterminal = showNonterminal
        !          2064:                         }
        !          2065:                val printCores = fn (state : int,cores) =>
        !          2066:                        Utils.CoreSet.app (fn a =>
        !          2067:                            let val (Utils.CORE c) = a
        !          2068:                                val {coreRHSafter,
        !          2069:                                     I = {coreLHS,
        !          2070:                                          coreAttribute=Utils.G.ATTRIB {num, ...},
        !          2071:                                          ...},
        !          2072:                                     ...
        !          2073:                                    } = c
        !          2074:                            in (Busy.print "\t";
        !          2075:                                printCore a;
        !          2076:                                case coreRHSafter
        !          2077:                                 of nil => Busy.println (" (reduce by rule "^
        !          2078:                                                        (makestring num) ^ ")")
        !          2079:                                 | _ => Busy.println ""
        !          2080:                                 )
        !          2081:                            end) cores
        !          2082: 
        !          2083:                val printActions = fn (state : int) =>
        !          2084:                   let fun f i = 
        !          2085:                        if i < numTerminals then
        !          2086:                          (case (#action(access(actions,state, i)))
        !          2087:                             of SHIFT s =>
        !          2088:                                Busy.println ("\t" ^
        !          2089:                                              (showTerminalClass (G.T i)) ^
        !          2090:                                              "\tshift " ^ (showState s))
        !          2091:                          | REDUCE (G.ATTRIB {lhs,num,...}) =>
        !          2092:                             Busy.println ("\t" ^ (showTerminalClass (G.T i))^
        !          2093:                                           "\treduce by rule " ^
        !          2094:                                 (makestring num))
        !          2095:                          | ERROR => ();
        !          2096:                           f (i+1))
        !          2097:                          else ()
        !          2098:                        fun g i =
        !          2099:                          if i < numNonterminals then
        !          2100:                             (case access(gotos, state, i)
        !          2101:                                 of GOTO(SOME s) =>
        !          2102:                                Busy.println("\t" ^(showNonterminal (G.NT i))^
        !          2103:                                         "\tgoto " ^ (showState s))
        !          2104:                                  | _  => ();
        !          2105:                              g (i+1))
        !          2106:                          else ()
        !          2107:                    in (f 0; g 0)
        !          2108:                    end
        !          2109:                  fun print_state a =
        !          2110:                      let val {state,cores} = a
        !          2111:                          val cores = (* coreClosure *) cores
        !          2112:                      in
        !          2113:                        (Busy.println "";
        !          2114:                         revapp (revapp Busy.print) (errmsgs state);
        !          2115:                         Busy.println "";
        !          2116:                         Busy.println(" state " ^ (makestring state) ^
        !          2117:                                     ":");
        !          2118:                         Busy.println "";
        !          2119:                         printCores(state,cores);
        !          2120:                         Busy.println "";
        !          2121:                         printActions(state)
        !          2122:                        )
        !          2123:                       end
        !          2124: 
        !          2125:                 fun find_state n =
        !          2126:                   let fun f(a::b) = 
        !          2127:                        let val {state,cores} = a
        !          2128:                        in if state=n then a else f b
        !          2129:                        end
        !          2130:                   in f theNodes
        !          2131:                   end
        !          2132:                 fun all_states () =
        !          2133:                   let fun f i = if i<numNodes then
        !          2134:                                   (print_state (find_state i); f (i+1))
        !          2135:                                 else ()
        !          2136:                   in f 0
        !          2137:                   end
        !          2138:            in all_states();
        !          2139:               Busy.sendto_file std_out;
        !          2140:               close_out outfile
        !          2141:            end)
        !          2142:        else(plantEdgeMoves(actions, gotos,theEdges);
        !          2143:             let val errs = (plantStates(actions,theNodes))
        !          2144:             in (Busy.sendto_file std_out;
        !          2145:                         revapp (fn (_,s) => map Busy.print s) errs)
        !          2146:             end
        !          2147:            );
        !          2148: 
        !          2149:         if (!rr_error) then raise AssignAction
        !          2150:         else printLr_Table(dest,gotos,actions,DisplayAttributes,numNodes)
        !          2151:        )
        !          2152:    end
        !          2153: end;
        !          2154: structure MLY_MAKE_PARSER = 
        !          2155:   struct
        !          2156: val print_parser = fn pr => pr
        !          2157: "\
        !          2158: \\n\
        !          2159: \\n\
        !          2160: \signature MLY_GRAMMAR =\n\
        !          2161: \   sig\n\
        !          2162: \      type Terminal\n\
        !          2163: \      type Nonterminal\n\
        !          2164: \      datatype Symbol = TERM of Terminal | NONTERM of Nonterminal\n\
        !          2165: \\n\
        !          2166: \      datatype Attribute = ATTRIB of {lhs:Nonterminal,rhsLength:int,num: int }\n\
        !          2167: \\n\
        !          2168: \      val showTerminalClass : Terminal -> string\n\
        !          2169: \      val showTerminalValue: Terminal -> string\n\
        !          2170: \      val showNonterminal : Nonterminal -> string\n\
        !          2171: \      val eqNonterminal : Nonterminal * Nonterminal -> bool\n\
        !          2172: \      val eqTerminal : Terminal * Terminal -> bool\n\
        !          2173: \\n\
        !          2174: \      type Lineno\n\
        !          2175: \      val lineno : Lineno ref\n\
        !          2176: \      val error: string -> Lineno -> unit\n\
        !          2177: \\n\
        !          2178: \     val ErrTermList : Terminal list\n\
        !          2179: \     val preferred_subst : Terminal -> Terminal list\n\
        !          2180: \     val is_keyword : Terminal -> bool\n\
        !          2181: \     val preferred_insert : Terminal -> bool\n\
        !          2182: \     val eof : Terminal\n\
        !          2183: \     val start : Nonterminal\n\
        !          2184: \   end\n\
        !          2185: \\n\
        !          2186: \signature MLY_LR_TABLE =\n\
        !          2187: \   sig\n\
        !          2188: \      structure G : MLY_GRAMMAR\n\
        !          2189: \      \n\
        !          2190: \      type State\n\
        !          2191: \      val initialState: State\n\
        !          2192: \      val showState: State -> string\n\
        !          2193: \\n\
        !          2194: \      datatype Action =   SHIFT of State | REDUCE of G.Attribute | ERROR\n\
        !          2195: \      val action: State * G.Terminal -> Action\n\
        !          2196: \      val actionT : (int * Action) list array\n\
        !          2197: \      val goto: State * G.Nonterminal -> State\n\
        !          2198: \   end\n\
        !          2199: \\n\
        !          2200: \signature MLY_ACTIONS = \n\
        !          2201: \    sig \n\
        !          2202: \      type Value\n\
        !          2203: \      val ErrValList : Value list\n\
        !          2204: \      val VOID : Value\n\
        !          2205: \      val rule : (int * Value list) -> (Value * Value list)\n\
        !          2206: \    end\n\
        !          2207: \\n\
        !          2208: \\n\
        !          2209: \signature MLY_PARSER =\n\
        !          2210: \   sig\n\
        !          2211: \      structure A: MLY_GRAMMAR\n\
        !          2212: \      structure B: MLY_ACTIONS\n\
        !          2213: \      val parse: (unit -> A.Terminal * B.Value) -> (int*int) -> B.Value\n\
        !          2214: \   end;\n\
        !          2215: \\n\
        !          2216: \functor ParserGen(structure Lr_Table : MLY_LR_TABLE\n\
        !          2217: \                    structure RuleAction: MLY_ACTIONS\n\
        !          2218: \                     ) : MLY_PARSER =\n\
        !          2219: \   struct\n\
        !          2220: \     structure A = Lr_Table.G\n\
        !          2221: \     structure B = RuleAction\n\
        !          2222: \     open Lr_Table RuleAction Lr_Table.G\n\
        !          2223: \     exception Error\n\
        !          2224: \     val DEBUG = false\n\
        !          2225: \\n\
        !          2226: \     \n\
        !          2227: \\n\
        !          2228: \     exception Joinlists\n\
        !          2229: \\n\
        !          2230: \     val TestLexVList = \n\
        !          2231: \      let fun f(a::a',b::b',r) = f(a',b',(a,b)::r)\n\
        !          2232: \            | f(nil,nil,r) = rev r\n\
        !          2233: \            | f _ = raise Joinlists\n\
        !          2234: \      in f(ErrTermList,ErrValList,nil)\n\
        !          2235: \      end\n\
        !          2236: \\n\
        !          2237: \     type Element = { term : G.Terminal, value : Value, stack : State list,\n\
        !          2238: \                       def_reduces : G.Attribute list, lineno : G.Lineno}\n\
        !          2239: \\n\
        !          2240: \      local \n\
        !          2241: \       val print = output std_out\n\
        !          2242: \       val println = fn s => (print s; print \"\\n\")\n\
        !          2243: \      in\n\
        !          2244: \        fun printStack(stack: State list, n: int) =\n\
        !          2245: \         case stack\n\
        !          2246: \           of (state) :: rest =>\n\
        !          2247: \                 (print(\"          \" ^ makestring n ^ \": \");\n\
        !          2248: \                  println(showState state);\n\
        !          2249: \                  printStack(rest, n+1)\n\
        !          2250: \                 )\n\
        !          2251: \            | nil => ()\n\
        !          2252: \                \n\
        !          2253: \        fun prAction(stack as (state) :: _, next, action) =\n\
        !          2254: \             (println \"Parse: state stack:\";\n\
        !          2255: \              printStack(stack, 0);\n\
        !          2256: \              print(\"       state=\"\n\
        !          2257: \                         ^ showState state    \n\
        !          2258: \                         ^ \" next=\"\n\
        !          2259: \                         ^ showTerminalClass next\n\
        !          2260: \                         ^ \" action=\"\n\
        !          2261: \                        );\n\
        !          2262: \              case action\n\
        !          2263: \                of SHIFT state' =>\n\
        !          2264: \                      println(\"SHIFT \" ^ showState state')\n\
        !          2265: \                 | REDUCE(ATTRIB{lhs, ...}) =>\n\
        !          2266: \                      println(\"REDUCE \" ^ showNonterminal lhs)\n\
        !          2267: \                 | ERROR =>\n\
        !          2268: \                      println \"ERROR\";\n\
        !          2269: \              action\n\
        !          2270: \             )\n\
        !          2271: \        | prAction (_,_,action) = action\n\
        !          2272: \     end\n\
        !          2273: \\n\
        !          2274: \    \n\
        !          2275: \\n\
        !          2276: \     val pr_errln = error\n\
        !          2277: \     val pr_err = error\n\
        !          2278: \      \n\
        !          2279: \\n\
        !          2280: \     \n\
        !          2281: \\n\
        !          2282: \     fun parse lexer (MaxLookAhead,Size) = \n\
        !          2283: \      let exception Remove\n\
        !          2284: \        val MaxLookAhead = max(0,MaxLookAhead) \n\
        !          2285: \          val Size = max(0,Size)\n\
        !          2286: \\n\
        !          2287: \      val ls = (ref nil) : ((Terminal * Value) * Lineno) list ref\n\
        !          2288: \\n\
        !          2289: \      val lexer = fn () =>\n\
        !          2290: \        case (!ls) of\n\
        !          2291: \          nil => (lexer(),!lineno)\n\
        !          2292: \        | a::b => (ls := b; a)\n\
        !          2293: \\n\
        !          2294: \      \n\
        !          2295: \\n\
        !          2296: \      fun print_lookahead () = \n\
        !          2297: \       (app (fn ((a:Terminal,_),_) => (print (showTerminalClass a); print \" \")) (!ls);\n\
        !          2298: \        print \"\\n\")\n\
        !          2299: \\n\
        !          2300: \      fun remove (0,s) = s\n\
        !          2301: \        | remove (n,a::b) = remove(n-1,b)\n\
        !          2302: \        | remove _ = raise Remove\n\
        !          2303: \\n\
        !          2304: \      exception ParseStep\n\
        !          2305: \      val FixError = ParseStep\n\
        !          2306: \      exception psRemoveBind\n\
        !          2307: \\n\
        !          2308: \      exception Reduce\n\
        !          2309: \\n\
        !          2310: \      fun reduce(l,vs) =\n\
        !          2311: \           fold (fn (ATTRIB{rhsLength,num,...},vs) =>\n\
        !          2312: \              let val (nv,vs) = rule (num,vs)\n\
        !          2313: \              in nv::vs\n\
        !          2314: \              end) l vs\n\
        !          2315: \\n\
        !          2316: \\n\
        !          2317: \      \n\
        !          2318: \\n\
        !          2319: \      fun fix_error(ss as (topstate :: _ ) : State list ,\n\
        !          2320: \              (vs,oss) : (Value list * State list),\n\
        !          2321: \              queue as (x,y) : (Element list * Element list),\n\
        !          2322: \              reductions :  G.Attribute list,\n\
        !          2323: \              lexv as ((term,value),lineno),\n\
        !          2324: \              c : int,\n\
        !          2325: \              min_advance : int,\n\
        !          2326: \              max_advance : int) =\n\
        !          2327: \         let\n\
        !          2328: \\n\
        !          2329: \              val _ = pr_errln(\"syntax error found at \" ^\n\
        !          2330: \                                (showTerminalClass term)) lineno\n\
        !          2331: \\n\
        !          2332: \              val min_delta = 3\n\
        !          2333: \\n\
        !          2334: \       \n\
        !          2335: \\n\
        !          2336: \              val toklist = x@(rev ({term=term,value=value,lineno=lineno,\n\
        !          2337: \                                     stack=oss,def_reduces=nil}::y))\n\
        !          2338: \\n\
        !          2339: \      \n\
        !          2340: \\n\
        !          2341: \              datatype Oper = INSERT | DELETE  | SUBST of Terminal\n\
        !          2342: \              datatype Change = CHANGE of {pos : int, distance : int,\n\
        !          2343: \                                           term : Terminal, value : Value,\n\
        !          2344: \                                           oper : Oper,lineno : Lineno}\n\
        !          2345: \\n\
        !          2346: \       val print_change = fn (CHANGE {pos,distance,term,value,oper,lineno}) =>\n\
        !          2347: \          (print (\"{ pos= \" ^ (makestring pos));\n\
        !          2348: \           print (\" dis= \" ^ (makestring distance));\n\
        !          2349: \           print (\" term = \" ^ (showTerminalClass term));\n\
        !          2350: \           print (\"oper= \" ^ (case oper\n\
        !          2351: \                               of INSERT => \"INSERT \"\n\
        !          2352: \                                | SUBST _ => \"SUBST \"\n\
        !          2353: \                                | DELETE => \"DELETE \"));\n\
        !          2354: \\n\
        !          2355: \           print \"}\\n\")\n\
        !          2356: \\n\
        !          2357: \      val print_cl = map print_change\n\
        !          2358: \\n\
        !          2359: \      \n\
        !          2360: \\n\
        !          2361: \              val ExtraTokens =\n\
        !          2362: \                let fun f (t,0) = rev t\n\
        !          2363: \                      | f (t,n) =\n\
        !          2364: \                              let val (lexval as ((term,_),_)) = lexer()\n\
        !          2365: \                              in f(lexval::t,\n\
        !          2366: \                                   if eqTerminal(term,eof) then 0 else n-1)\n\
        !          2367: \                              end\n\
        !          2368: \                in f(nil,max_advance)\n\
        !          2369: \                end\n\
        !          2370: \\n\
        !          2371: \      \n\
        !          2372: \                              \n\
        !          2373: \\n\
        !          2374: \         val LexValueList =\n\
        !          2375: \              (map (fn ({term, value,lineno, ...} : Element) =>\n\
        !          2376: \                          ((term,value),lineno))\n\
        !          2377: \               toklist) @ (ExtraTokens)\n\
        !          2378: \\n\
        !          2379: \        val TermList = map (fn ((a,_),l) => (a,l)) LexValueList\n\
        !          2380: \\n\
        !          2381: \       \n\
        !          2382: \\n\
        !          2383: \        exception parseTest\n\
        !          2384: \        exception parseRemoveBind\n\
        !          2385: \\n\
        !          2386: \        fun parse (ss as (s :: _),tokenlist) =\n\
        !          2387: \          (case tokenlist\n\
        !          2388: \               of nil => 0\n\
        !          2389: \                | (e as (a, _ ))::b => \n\
        !          2390: \              (case Lr_Table.action(s,a)\n\
        !          2391: \                of ERROR => length tokenlist\n\
        !          2392: \                 | (SHIFT s) => parse(s::ss,b)\n\
        !          2393: \                 | (REDUCE (ATTRIB {lhs,rhsLength, ...})) =>\n\
        !          2394: \\n\
        !          2395: \                      \n\
        !          2396: \\n\
        !          2397: \                      if eqNonterminal(lhs,start) then ~1\n\
        !          2398: \                      else case remove(rhsLength,ss)\n\
        !          2399: \                              of (ns as (ts :: _ )) =>\n\
        !          2400: \                                 parse(goto(ts,lhs)::ns,e::b)\n\
        !          2401: \                               |  _ => raise parseRemoveBind\n\
        !          2402: \                )\n\
        !          2403: \            )\n\
        !          2404: \            | parse _ = raise parseTest\n\
        !          2405: \\n\
        !          2406: \        exception Rev_queue_fold\n\
        !          2407: \\n\
        !          2408: \      \n\
        !          2409: \\n\
        !          2410: \      fun rev_queue_fold (queue : 'b list,toklist : 'c list)\n\
        !          2411: \                         (g : (int * 'a * 'b list * 'c list) -> 'a)\n\
        !          2412: \                         (start : 'a) =\n\
        !          2413: \\n\
        !          2414: \      let fun f(count,results,nil,_) = results\n\
        !          2415: \            | f(count,results,queue as (q :: q'),toklist as (t :: t')) = \n\
        !          2416: \                f(count+1,g(count,results,queue,toklist),q',t')\n\
        !          2417: \            | f _ = raise Rev_queue_fold\n\
        !          2418: \      in f(0,start,queue,toklist)\n\
        !          2419: \      end\n\
        !          2420: \\n\
        !          2421: \\n\
        !          2422: \      \n\
        !          2423: \\n\
        !          2424: \      fun test (new_token_list :\n\
        !          2425: \                       (Terminal * Lineno) * ((Terminal * Lineno) list) ->\n\
        !          2426: \                               ((Terminal * Lineno) list),\n\
        !          2427: \                     oper : Oper) =\n\
        !          2428: \       let fun test' (count,results, ({stack, ...} : Element) :: _,\n\
        !          2429: \              tl as   ((_,lineno) :: _)) =\n\
        !          2430: \          List.fold (fn ((a,v),r) =>\n\
        !          2431: \              let val tokens_left = parse(stack,new_token_list((a,lineno),tl))\n\
        !          2432: \              in if tokens_left > (max_advance - min_advance) then r\n\
        !          2433: \                 else (CHANGE {pos=count,term=a,value=v,distance=tokens_left,\n\
        !          2434: \                           oper = oper,lineno=lineno})::r\n\
        !          2435: \              end) TestLexVList results\n\
        !          2436: \       in rev_queue_fold (toklist,TermList) test' nil\n\
        !          2437: \       end\n\
        !          2438: \              \n\
        !          2439: \      val SubstChanges =\n\
        !          2440: \        let fun test (count,results,({stack, term, ...} : Element) :: _,\n\
        !          2441: \                       (_,lineno) :: rest) =\n\
        !          2442: \          let val max_left = max_advance - min_advance\n\
        !          2443: \          in List.fold (fn ((a,v),r) =>\n\
        !          2444: \                let val tokens_left = parse(stack,(a,lineno)::rest)\n\
        !          2445: \                in if tokens_left > max_left then r\n\
        !          2446: \                  else (CHANGE {pos=count,term=a,value=v,distance=tokens_left,\n\
        !          2447: \                              oper=SUBST term,lineno=lineno})::r\n\
        !          2448: \                end) TestLexVList results\n\
        !          2449: \          end\n\
        !          2450: \       in rev_queue_fold (toklist,TermList) test nil\n\
        !          2451: \       end\n\
        !          2452: \\n\
        !          2453: \      val DeleteChanges = \n\
        !          2454: \        let fun test(count,results,({term,value,stack, ...} : Element) :: _,\n\
        !          2455: \                     termlist as ((_,lineno) :: rest)) =\n\
        !          2456: \                   let val tokens_left = parse(stack,rest)\n\
        !          2457: \                   in if tokens_left > (max_advance - min_advance) then\n\
        !          2458: \                            results\n\
        !          2459: \                      else (CHANGE {pos=count,distance=tokens_left,term=term,\n\
        !          2460: \                             value=value,oper=DELETE,lineno=lineno}) :: results\n\
        !          2461: \                   end\n\
        !          2462: \         in rev_queue_fold (toklist,TermList) test nil\n\
        !          2463: \         end\n\
        !          2464: \\n\
        !          2465: \      val InsertChanges =\n\
        !          2466: \         test ((fn (a,rest) => a::rest),INSERT)\n\
        !          2467: \\n\
        !          2468: \\n\
        !          2469: \\n\
        !          2470: \      local\n\
        !          2471: \\n\
        !          2472: \       fun sieve(a as (CHANGE {distance, ...}),b as (min,results)) =\n\
        !          2473: \              if min>distance then (distance,[a])\n\
        !          2474: \              else if min=distance then (min,a::results)\n\
        !          2475: \              else b\n\
        !          2476: \\n\
        !          2477: \       fun sieve_list l = List.fold sieve l (max_advance,nil)\n\
        !          2478: \\n\
        !          2479: \      in\n\
        !          2480: \\n\
        !          2481: \        val (min1,DeleteChanges) = sieve_list DeleteChanges\n\
        !          2482: \        val (min2,SubstChanges) = sieve_list SubstChanges\n\
        !          2483: \        val (min3,InsertChanges) = sieve_list InsertChanges\n\
        !          2484: \\n\
        !          2485: \        val min0 = min(min(min1,min2),min3)\n\
        !          2486: \\n\
        !          2487: \       val DeleteChanges = if min1>min0 then nil else DeleteChanges\n\
        !          2488: \       val SubstChanges = if min2>min0 then nil else SubstChanges\n\
        !          2489: \       val InsertChanges = if min3>min0 then nil else InsertChanges\n\
        !          2490: \\n\
        !          2491: \      end\n\
        !          2492: \\n\
        !          2493: \      val _ = if DEBUG then\n\
        !          2494: \                       (print_cl InsertChanges; print_cl DeleteChanges;\n\
        !          2495: \                        print_cl SubstChanges; ())\n\
        !          2496: \              else ()\n\
        !          2497: \\n\
        !          2498: \\n\
        !          2499: \\n\
        !          2500: \     val (InsertChanges,t) =\n\
        !          2501: \       List.fold (fn (a as (CHANGE {term, ...}),(r,t)) => \n\
        !          2502: \              if preferred_insert term then \n\
        !          2503: \                      if t then (a::r,t) else ([a],true)\n\
        !          2504: \              else if t then (r,t) else (a::r,t)\n\
        !          2505: \            ) InsertChanges (nil,false)\n\
        !          2506: \\n\
        !          2507: \     val (SubstChanges,t') =\n\
        !          2508: \      List.fold (fn (a as (CHANGE {term=term,oper=SUBST t', ...}),(r,t)) =>\n\
        !          2509: \              if List.exists (fn a=>eqTerminal(a,term)) (preferred_subst t') then\n\
        !          2510: \                if t then (a::r,t) else ([a],true)\n\
        !          2511: \              else if t then (r,t) else (a::r,t)\n\
        !          2512: \              | (a,(r,t)) => (a::r,t) \n\
        !          2513: \            ) SubstChanges (nil,false)\n\
        !          2514: \\n\
        !          2515: \\n\
        !          2516: \\n\
        !          2517: \    local val max_tokens = max_advance - (min_advance+min_delta)\n\
        !          2518: \\n\
        !          2519: \          val remove_keywords = fn l =>\n\
        !          2520: \              List.fold (fn (a as (CHANGE {term,distance,...}),r) =>\n\
        !          2521: \                  if (is_keyword term) andalso (distance > max_tokens) then\n\
        !          2522: \                     r\n\
        !          2523: \                  else a::r) l nil\n\
        !          2524: \\n\
        !          2525: \    in\n\
        !          2526: \\n\
        !          2527: \     val InsertChanges =\n\
        !          2528: \       if t then InsertChanges else remove_keywords InsertChanges\n\
        !          2529: \                      \n\
        !          2530: \     val DeleteChanges = remove_keywords DeleteChanges\n\
        !          2531: \\n\
        !          2532: \     val SubstChanges =\n\
        !          2533: \       if t' then SubstChanges else remove_keywords SubstChanges\n\
        !          2534: \\n\
        !          2535: \    end\n\
        !          2536: \    val MinChanges =\n\
        !          2537: \      let val ic = length InsertChanges\n\
        !          2538: \          and dc = length DeleteChanges\n\
        !          2539: \          and sc = length SubstChanges\n\
        !          2540: \      in if ic=1 then SOME InsertChanges\n\
        !          2541: \         else if dc=1 then SOME DeleteChanges\n\
        !          2542: \         else if sc=1 then SOME SubstChanges\n\
        !          2543: \         else if (min0 > (max_advance-(min_advance+min_delta))\n\
        !          2544: \                  orelse (ic+dc+sc)=0)\n\
        !          2545: \              then NONE\n\
        !          2546: \              else SOME (InsertChanges @ DeleteChanges @ SubstChanges)\n\
        !          2547: \      end\n\
        !          2548: \\n\
        !          2549: \\n\
        !          2550: \in case MinChanges \n\
        !          2551: \         of (SOME l) =>\n\
        !          2552: \              let fun print_msg (CHANGE {term, oper, lineno, ...}) =\n\
        !          2553: \\n\
        !          2554: \                   let val s = \n\
        !          2555: \                     case oper\n\
        !          2556: \                       of DELETE => \"deleting \"\n\
        !          2557: \                        | INSERT => \"inserting \"\n\
        !          2558: \                        | SUBST t => \"replacing \" ^ (showTerminalClass t) ^\n\
        !          2559: \                                 \" with \"\n\
        !          2560: \                   in pr_errln (s ^ (showTerminalClass term)) lineno\n\
        !          2561: \                   end\n\
        !          2562: \                 \n\
        !          2563: \                 val a = \n\
        !          2564: \                    if (length l > 1)\n\
        !          2565: \                       then (\n\
        !          2566: \      if DEBUG then\n\
        !          2567: \              (pr_errln \"multiple fixes possible: could fix it by\" lineno;\n\
        !          2568: \               map print_msg l;\n\
        !          2569: \               pr_errln \"fixing it with\" lineno\n\
        !          2570: \              )\n\
        !          2571: \      else ();\n\
        !          2572: \                             print_msg (hd l);\n\
        !          2573: \                             (hd l))\n\
        !          2574: \                        else (print_msg (hd l); (hd l))\n\
        !          2575: \\n\
        !          2576: \                  val pos = (fn (CHANGE {pos, ...}) => pos) a\n\
        !          2577: \                       \n\
        !          2578: \                fun f(0,q,termlist,rq',CHANGE {oper,term,value, lineno,\n\
        !          2579: \                       ...}) =\n\
        !          2580: \                 let val ({stack, ...} : Element) = hd(q)\n\
        !          2581: \                  in\n\
        !          2582: \                   (case oper\n\
        !          2583: \                    of DELETE =>\n\
        !          2584: \                    if eqTerminal(term,eof) then\n\
        !          2585: \                         (pr_errln \"EOF encountered: goodbye!\" lineno;\n\
        !          2586: \                          raise FixError)\n\
        !          2587: \                    else ls := (tl termlist) @ (!ls)\n\
        !          2588: \                     | (SUBST _) =>\n\
        !          2589: \                       ls := (((term,value),lineno)::(tl termlist)) @ (!ls)\n\
        !          2590: \                     | INSERT =>\n\
        !          2591: \                       ls := (((term,value),lineno)::termlist) @ (!ls));\n\
        !          2592: \                    parse_step(stack,(vs,stack),(rev rq',nil),nil,lexer(),\n\
        !          2593: \                               Size-pos)\n\
        !          2594: \                   end\n\
        !          2595: \                   | f(n,e  :: r, _ :: termlist, rq',change) =\n\
        !          2596: \                      f(n-1,r,termlist,e::rq',change)\n\
        !          2597: \              in f(pos,toklist,LexValueList,nil,a)\n\
        !          2598: \              end\n\
        !          2599: \        | NONE => if eqTerminal(term,eof) then\n\
        !          2600: \                         (pr_errln \"EOF encountered: goodbye!\" lineno;\n\
        !          2601: \                          raise FixError)\n\
        !          2602: \                    else\n\
        !          2603: \               (raise FixError\n\
        !          2604: \\n\
        !          2605: \)\n\
        !          2606: \      end\n\
        !          2607: \\n\
        !          2608: \      | fix_error _ = raise FixError\n\
        !          2609: \      \n\
        !          2610: \      and parse_step(ss as (topstate :: _ ),\n\
        !          2611: \                     v as (vs,oss),queue as (x,y),reductions,\n\
        !          2612: \                     lexv as ((term,value),lineno),c) =\n\
        !          2613: \         (case (if DEBUG then prAction(ss, term,\n\
        !          2614: \                                      Lr_Table.action (topstate,term))\n\
        !          2615: \                         else Lr_Table.action (topstate,term))\n\
        !          2616: \           of SHIFT s =>\n\
        !          2617: \             let val ss = s::ss\n\
        !          2618: \                 val ny = {value=value,def_reduces=reductions,\n\
        !          2619: \                          term=term,stack=oss,lineno=lineno}::y\n\
        !          2620: \\n\
        !          2621: \             in if c > 0 then\n\
        !          2622: \                   parse_step(ss,(vs,ss),(x,ny),nil,lexer(),c-1)\n\
        !          2623: \                else (case x of nil =>\n\
        !          2624: \                  let val ({value,def_reduces, ...}::nx) = rev ny\n\
        !          2625: \                  in parse_step(ss,(value::(reduce(def_reduces,vs)),ss),\n\
        !          2626: \                                (nx,nil),nil, lexer(),c)\n\
        !          2627: \                  end\n\
        !          2628: \                 | ({value,def_reduces, ...}::b) =>\n\
        !          2629: \                      parse_step(ss,(value::(reduce(def_reduces,vs)),ss),\n\
        !          2630: \                                (b,ny),nil,lexer(),c))\n\
        !          2631: \              end\n\
        !          2632: \              | REDUCE (r as (ATTRIB {lhs,rhsLength , ...})) =>\n\
        !          2633: \                 if eqNonterminal(lhs,start) then\n\
        !          2634: \                   hd(reduce(r::reductions,\n\
        !          2635: \                      fold (fn ({value,def_reduces, ...} : Element,vs) =>\n\
        !          2636: \                          value::(reduce(def_reduces,vs))) (y@(rev x)) vs))\n\
        !          2637: \                 else (\n\
        !          2638: \                  case (remove(rhsLength,ss)) \n\
        !          2639: \                    of (ss as (ts :: _)) =>\n\
        !          2640: \                      (\n\
        !          2641: \\n\
        !          2642: \                       parse_step(goto(ts,lhs)::ss,v,queue,\n\
        !          2643: \                                     r::reductions,lexv,c)\n\
        !          2644: \                      )\n\
        !          2645: \                      | _ => raise psRemoveBind\n\
        !          2646: \                  )\n\
        !          2647: \               \n\
        !          2648: \               | ERROR => fix_error(ss,v,queue,reductions,lexv,c,1,MaxLookAhead))\n\
        !          2649: \            | parse_step _ = raise ParseStep\n\
        !          2650: \          in parse_step([initialState],(nil,[initialState]),\n\
        !          2651: \                        (nil,nil),nil,lexer(),Size) \n\
        !          2652: \          end\n\
        !          2653: \end\n\
        !          2654: \"
        !          2655:   end
        !          2656: structure Misc =
        !          2657: struct
        !          2658:     structure G : V2_LR_GRAMMAR =
        !          2659:        struct
        !          2660:                datatype Terminal = T of int
        !          2661:                and Nonterminal = NT of int
        !          2662: 
        !          2663:                datatype Symbol = TERM of Terminal
        !          2664:                                | NONTERM of Nonterminal
        !          2665: 
        !          2666:                datatype Attribute = ATTRIB of { lhs : Nonterminal,
        !          2667:                                                 rhsLength : int,
        !          2668:                                                 num : int
        !          2669:                                               }
        !          2670:                datatype Rule = RULE of {lhs : Nonterminal,
        !          2671:                                         rhs : Symbol list,
        !          2672:                                         attribute : Attribute,
        !          2673:                                         precedence : int option
        !          2674:                                        }
        !          2675: 
        !          2676:                val termHash = fn (T i) => i
        !          2677:                val nontermHash = fn (NT i) => i
        !          2678:                val eqTerminal = fn ((T i),(T i')) => i = i'
        !          2679:                val eqNonterminal = fn ((NT i),(NT i')) => i = i'
        !          2680: 
        !          2681:                val gtTerminal = fn ((T i),(T i')) => i > i'
        !          2682:                val gtNonterminal = fn ((NT i),(NT i')) => i > i'
        !          2683:        end
        !          2684: 
        !          2685:      structure MakeTable = V2_TableGen(structure G = G)
        !          2686: 
        !          2687: type Lineno = int
        !          2688: val lineno = ref 1
        !          2689: val infile = ref "";
        !          2690: 
        !          2691: val error = fn t => fn (l : Lineno) =>
        !          2692:                 (output std_out ((!infile) ^ ", line " ^
        !          2693:                                 (makestring l) ^ ": " ^ t ^ "\n"))
        !          2694: 
        !          2695: datatype LexValue = LEFT | RIGHT | NONASSOC
        !          2696: 
        !          2697: type symbol = string
        !          2698: type constr = string
        !          2699: type ty = string list option
        !          2700: type constr_data = {ty: ty,num : int}
        !          2701: 
        !          2702: structure PrecSet = FullSet(struct 
        !          2703:                              type elem = (symbol * (int*LexValue))
        !          2704:                              val gt = fn ((a:string,_),(a',_)) => a > a'
        !          2705:                              val eq = fn ((a:string,_),(a',_)) => a = a'
        !          2706:                             end
        !          2707:                            )
        !          2708: 
        !          2709: structure ConstrSet = FullSet(struct
        !          2710:                                type elem = (constr * {ty : ty, num : int})
        !          2711:                                val gt =  fn ((a:string,_),(a',_)) => a > a'
        !          2712:                                val eq = fn ((a:string,_),(a',_)) => a = a'
        !          2713:                              end)
        !          2714: 
        !          2715: type decl_data = {start : symbol option,
        !          2716:                  prec :  { d : PrecSet.set,
        !          2717:                            h : int} option,
        !          2718:                  nonterm : ConstrSet.set option,
        !          2719:                  term : ConstrSet.set option,
        !          2720:                  eof : symbol option,
        !          2721:                  prefer : (symbol*symbol) list,
        !          2722:                  iprefer : symbol list,
        !          2723:                  keyword : symbol list,
        !          2724:                  structure' : symbol option,
        !          2725:                  verbose : bool}
        !          2726: 
        !          2727: type rhs_data = {rhs:symbol list, code:string, prec: symbol option} list
        !          2728: type rule = { lhs : symbol, rhs : symbol list,
        !          2729:                      code : string, prec : symbol option }
        !          2730: 
        !          2731: val out = ref std_out;
        !          2732: 
        !          2733: val len = ref 0
        !          2734: val indent = ref 0
        !          2735: val tw = 4
        !          2736: val inc_margin = fn () => indent := (!indent)+tw
        !          2737: val dec_margin = fn () => indent := (!indent)-tw
        !          2738: val reset_margin = fn () => indent := tw
        !          2739: val err_flag = ref false
        !          2740: (* The next line is bogus, it gets the wrong value of lineno *)
        !          2741: val errmsg = fn x => (err_flag := true; error x (!lineno))
        !          2742: val errln = errmsg
        !          2743:        
        !          2744: val say = fn x => output (!out) x
        !          2745: 
        !          2746: fun  newln () =
        !          2747:    let fun f i =  if i > 0 then (say " "; f (i-1)) else ()
        !          2748:    in  (say "\n"; len := (!indent); f(!indent))
        !          2749:    end
        !          2750: 
        !          2751: val sayln = fn (x : string) =>
        !          2752:        let val wl = size x
        !          2753:            val new_count = !len + wl
        !          2754:        in if (!len = 0 orelse new_count < 78)
        !          2755:              then (say x; newln())
        !          2756:              else (newln(); say  x; newln())
        !          2757:        end
        !          2758: 
        !          2759: val saywd = fn x : string =>
        !          2760:         let val wl = size x
        !          2761:             val new_count = !len + wl
        !          2762:         in if (!len = 0 orelse new_count < 78) 
        !          2763:               then (len := new_count; say x)
        !          2764:               else (newln(); len := (!len) + wl; say x)
        !          2765:         end
        !          2766: 
        !          2767: local
        !          2768:     fun add_nums(nil,i) = nil
        !          2769:       | add_nums ((c,{ty=t, ...} : constr_data)::r,i) =
        !          2770:                (c,{ty=t,num=i}) :: add_nums(r,i+1)
        !          2771: in
        !          2772:   fun make_tok_dict (l as (_ :: _)) = SOME (ConstrSet.make_set (add_nums(l,0)))
        !          2773:     | make_tok_dict nil = NONE
        !          2774: end
        !          2775: 
        !          2776: fun save_prec (l as (_::_),parity) =
        !          2777:     SOME {d= PrecSet.make_set (map (fn a => (a,(1,parity))) l), h=3}
        !          2778:   | save_prec _ = NONE
        !          2779: 
        !          2780: fun join_decls {start=a, prec=b, nonterm=c, term=d,eof=e,
        !          2781:                iprefer=f,prefer=g,keyword=h,structure'=k,verbose=verbose}
        !          2782:                {start=a',prec=b',nonterm=c',term=d',eof=e',
        !          2783:                iprefer=f',prefer=g',keyword=h',structure'=k',
        !          2784:                verbose=verbose'} =
        !          2785: 
        !          2786:     let fun j (f,NONE,NONE) = NONE
        !          2787:          | j (f,a,NONE) = a
        !          2788:          | j (f,NONE,a) = a
        !          2789:          | j (f,SOME i,SOME j) = f(i,j)
        !          2790: 
        !          2791:         fun join e = fn(i,j) =>
        !          2792:          (errln ("ignoring duplicate "^e^" declaration"); SOME i)
        !          2793: 
        !          2794:         fun join_prec({d=t,h=h},{d=t',h=h'}) =
        !          2795:           let fun f ((e as  (a,(_,p))),t) =
        !          2796:                if (PrecSet.exists e t) then 
        !          2797:                    (errln ("ignoring duplicate %prec definition of" ^ a); t)
        !          2798:                else (PrecSet.insert (a,(h+1,p)) t)
        !          2799:          in SOME {d = PrecSet.setfold f t' t,h=h+3} 
        !          2800:          end
        !          2801: 
        !          2802:       in {start= j (join "start",a,a'),
        !          2803:           prec=j (join_prec,b,b'),
        !          2804:           term = j (join "%term",d,d'),
        !          2805:           nonterm = j (join "%nonterm",c,c'),
        !          2806:           eof = j (join "%eof",e,e'),
        !          2807:           iprefer=f'@f,
        !          2808:           prefer=g'@g,
        !          2809:           keyword=h'@h,
        !          2810:           structure' = j (join "%structure",k,k'),
        !          2811:           verbose = verbose orelse verbose'}
        !          2812:       end
        !          2813: 
        !          2814: local fun print_bool_case (l : string list) =
        !          2815:        (sayln "fn t => ";
        !          2816:         sayln "case t";
        !          2817:          saywd "of ";
        !          2818:         List.app (fn s => (saywd s; sayln " => true"; saywd " | ")) l;
        !          2819:         sayln "_ => false"
        !          2820:        )
        !          2821: 
        !          2822: in fun print_is_keyword_func (l : string list) =
        !          2823:        (sayln "val is_keyword =";
        !          2824:         print_bool_case l)
        !          2825: 
        !          2826:    and print_preferred_insert_func (l : string list) =
        !          2827:        (sayln "val preferred_insert =";
        !          2828:         print_bool_case l)
        !          2829: 
        !          2830:    and print_preferred_subst_func (l : (string*(string list)) list) =
        !          2831:        (sayln "val preferred_subst = fn t =>";
        !          2832:         sayln "case t";
        !          2833:         saywd "of ";
        !          2834:         List.app (fn (a,l') =>
        !          2835:            (saywd a; saywd " => ";
        !          2836:             List.app (fn s => (saywd s; saywd "::")) l';
        !          2837:             sayln "nil"; saywd "| "
        !          2838:            )
        !          2839:         ) l;
        !          2840:         sayln " _ => nil"
        !          2841:        )
        !          2842: end
        !          2843: 
        !          2844: fun printConstrSet(constr_set,name,only_with_values) =
        !          2845:   let val _ = (inc_margin(); inc_margin(); inc_margin();
        !          2846:                saywd ("datatype " ^ name ^ " = "))
        !          2847:       val printed_something = 
        !          2848:            ConstrSet.revsetfold (fn ((s,{ty=d,...}),result) =>
        !          2849:                  (if only_with_values then
        !          2850:                        (case d
        !          2851:                         of NONE => result
        !          2852:                          | SOME t =>
        !          2853:                                (if result then saywd " | " else ();
        !          2854:                                 saywd s;
        !          2855:                                 saywd " of ";
        !          2856:                                 List.app saywd t;
        !          2857:                                 true
        !          2858:                                )
        !          2859:                        )
        !          2860:                     else
        !          2861:                        (if result then saywd " | " else ();
        !          2862:                         saywd s;
        !          2863:                         case d
        !          2864:                                of NONE => ()
        !          2865:                                 | SOME t => (saywd " of "; List.app saywd t);
        !          2866:                         true
        !          2867:                        )
        !          2868:                   )
        !          2869:                ) constr_set false;
        !          2870:          in (dec_margin(); dec_margin(); dec_margin(); sayln "";
        !          2871:             printed_something)
        !          2872:         end
        !          2873: 
        !          2874: fun PrConstructors(n,t) = 
        !          2875:      (saywd ("datatype "^n^ " = ");
        !          2876:       ConstrSet.revsetfold( fn ((s,_),r) =>
        !          2877:                (if r then saywd " | " else (); saywd s; true)) t false;
        !          2878:       newln())
        !          2879: 
        !          2880: val make_parser = fn (HEADER : string, MPC_DECLS : decl_data,
        !          2881:                      TRULELIST : rule list) =>
        !          2882: (let exception SemanticError
        !          2883:  in let val ({start=start,prec=p,nonterm=nt,term=t,eof=eof,
        !          2884:           prefer=prefer,iprefer=iprefer,keyword=keyword,
        !          2885:           structure'=structure',verbose=verbose}) = MPC_DECLS
        !          2886: 
        !          2887:        val p = case p of NONE => PrecSet.empty | SOME {d,h} => d
        !          2888: 
        !          2889:        val _ = (let val f = fn d => errln("missing "^d^" definition")
        !          2890:                 in (case t of NONE => f "%term" | _ => ();
        !          2891:                     case nt of NONE => f "%nonterm" | _ => ())
        !          2892:                 end);
        !          2893: 
        !          2894:        val nonterms = 
        !          2895:                case nt of SOME i => i
        !          2896:                         | NONE => raise SemanticError
        !          2897: 
        !          2898:        val terms = case t of SOME i => i
        !          2899:                            | NONE => raise SemanticError
        !          2900: 
        !          2901:        val dummy_data = {ty = NONE,num = 0}
        !          2902:        val is_term = fn a => ConstrSet.exists (a,dummy_data) terms
        !          2903:        val is_nonterm = fn a => ConstrSet.exists (a,dummy_data) nonterms
        !          2904: 
        !          2905:        exception Get_type
        !          2906:        val get_type = fn (a,terms,nonterms) =>
        !          2907:           case (ConstrSet.find (a,dummy_data) terms)
        !          2908:            of NONE =>
        !          2909:                    (case (ConstrSet.find (a,dummy_data) nonterms)
        !          2910:                         of SOME (_,{ty=t,...}) => t
        !          2911:                          | _ => raise Get_type)
        !          2912:             | SOME (_,{ty=t,...}) => t
        !          2913: 
        !          2914:        val get_prec = fn a =>
        !          2915:           case PrecSet.find (a,(0,LEFT)) p 
        !          2916:                of NONE => NONE
        !          2917:                 | SOME (_,(a,_)) => SOME a
        !          2918: 
        !          2919:         val _ = PrecSet.app
        !          2920:                  (fn (s,_) =>
        !          2921:                        if is_term s then ()
        !          2922:                        else errln (s^" in %prec is not defined as a token")
        !          2923:                  ) p
        !          2924: 
        !          2925:        val start =
        !          2926:            case start
        !          2927:                  of NONE => start
        !          2928:                   | SOME i =>
        !          2929:                if is_nonterm i then start
        !          2930:                else (errln
        !          2931:                  (i ^ " in %start is not defined as a nonterminal"); NONE)
        !          2932: 
        !          2933:        val eof = case eof
        !          2934:                     of NONE =>(errln ("missing %eof definition"); "")
        !          2935:                      | SOME i => 
        !          2936:                if is_term i then i
        !          2937:                else (errln (i ^ " in %eof is not defined as a nonterminal"); "")
        !          2938: 
        !          2939:        fun make_unique_id s = 
        !          2940:           if (is_term s) orelse (is_nonterm s) then make_unique_id (s ^ "'")
        !          2941:                else s
        !          2942:        val void = make_unique_id "mlyVOID"
        !          2943: 
        !          2944:        local
        !          2945:           val dummy_start = make_unique_id "mlySTART"
        !          2946:           val nontermlist = rev (map (fn {lhs=lhs : symbol,...} => lhs) TRULELIST)
        !          2947:           val start = case start of NONE => (hd nontermlist) | SOME a => a
        !          2948:           val dummy_type = get_type(start,terms,nonterms)
        !          2949:           val code = case dummy_type of NONE => "" | _ => start
        !          2950:        in 
        !          2951:              val nonterms = ConstrSet.insert (dummy_start,
        !          2952:                  {ty=dummy_type,num=ConstrSet.card nonterms}) nonterms
        !          2953:              val is_nonterm = fn a => ConstrSet.exists (a,dummy_data) nonterms
        !          2954:              val TRULELIST={lhs=dummy_start,rhs=[start],code=code,prec=NONE}::
        !          2955:                             TRULELIST
        !          2956:              val start=dummy_start
        !          2957:        end
        !          2958: 
        !          2959:       val (keyword, iprefer) =
        !          2960:         let val f = fn x =>
        !          2961:             fn (a,r) =>
        !          2962:                if (is_term a) then a::r
        !          2963:                else (errln (a^" in "^x^" is not defined as a terminal"); r)
        !          2964:         in (List.fold (f "%keyword") keyword nil,
        !          2965:             List.fold (f "%insert_prefer") iprefer nil)
        !          2966:         end
        !          2967: 
        !          2968:       val prefer =
        !          2969:        let val print_err =
        !          2970:                fn s => errln (s^" in %prefer is not defined as a terminal")
        !          2971:            val f = fn (pair as (a,a'),r) =>
        !          2972:                let val flag =
        !          2973:                      if (is_term a) then false else (print_err a; true)
        !          2974:                    val flag' =
        !          2975:                      if (is_term a') then false else (print_err a'; true)
        !          2976:                in if (flag orelse flag') then r else (pair::r)
        !          2977:                end
        !          2978:         in List.fold f prefer nil
        !          2979:         end
        !          2980: 
        !          2981:       (* prefer_map : take list of (sym,sym') where sym is a preferred
        !          2982:         substitution for sym', make list of (sym,[ ... syms]) where
        !          2983:         elements in the list are all the preferred substitutions for some
        !          2984:         sym *)
        !          2985: 
        !          2986:       val prefer_map = 
        !          2987:         let 
        !          2988:          (* take prefer list, second elem of pair, return list of elems
        !          2989:             in prefer list w/ same second elem, prefer list - list of
        !          2990:             elems *)
        !          2991: 
        !          2992:            fun g (prefer_list,second_elem) =
        !          2993:              List.fold (fn (e as (f,s),(same,differ)) =>
        !          2994:                 if s=second_elem then (f::same,differ) else (same,e::differ))
        !          2995:                prefer_list (nil,nil)
        !          2996: 
        !          2997:            fun f(nil,prefer_map) = prefer_map
        !          2998:              | f(l as (e as (_,s):: _),prefer_map) = 
        !          2999:                   let val (same,differ) = g(l,s)
        !          3000:                   in f(differ,(s,same)::prefer_map)
        !          3001:                   end
        !          3002: 
        !          3003:        in f(prefer,nil)
        !          3004:        end
        !          3005: 
        !          3006:        val _ = 
        !          3007:          ConstrSet.app (fn (s,_) =>
        !          3008:            if is_term s andalso is_nonterm s
        !          3009:                then errln (s ^ " is defined as a nonterminal and a terminal")
        !          3010:                else  ()) terms
        !          3011: 
        !          3012:        val both = ConstrSet.union(terms,nonterms)
        !          3013: 
        !          3014:        val _ =
        !          3015:          let fun undef s =
        !          3016:               if (is_term s orelse is_nonterm s) then ()
        !          3017:               else (errln (s ^" is not defined as a terminal or nonterminal"))
        !          3018: 
        !          3019:              fun undef' s =
        !          3020:                 if is_nonterm s then ()
        !          3021:                 else (errln (s ^ " is not defined as a nonterminal"))
        !          3022: 
        !          3023:              fun check_rule {lhs,rhs,code,prec} = (map undef rhs; undef' lhs)
        !          3024: 
        !          3025:          in map check_rule TRULELIST
        !          3026:          end
        !          3027: 
        !          3028:        in if (!err_flag = false) then
        !          3029:                     (MLY_MAKE_PARSER.print_parser say;
        !          3030:                      reset_margin();
        !          3031:                      sayln ("structure " ^ 
        !          3032:                                 (case structure'
        !          3033:                                  of NONE => "C"
        !          3034:                                   | SOME i => i) ^
        !          3035:                              " = ");
        !          3036:                      inc_margin();
        !          3037:                      sayln "struct";
        !          3038:                      inc_margin();
        !          3039: 
        !          3040:                (* print HDR structure *)
        !          3041: 
        !          3042:                      sayln "structure HDR =";
        !          3043:                      inc_margin();
        !          3044:                      sayln "struct";
        !          3045:                      say HEADER; 
        !          3046:                      dec_margin();
        !          3047:                      sayln "";
        !          3048:                      dec_margin();
        !          3049:                      sayln "end";
        !          3050: 
        !          3051:                (* print V structure *)
        !          3052: 
        !          3053:                      inc_margin();
        !          3054:                      sayln "structure V =";
        !          3055:                      inc_margin();
        !          3056:                      sayln "struct";
        !          3057:                      sayln "open HDR;";
        !          3058: 
        !          3059:                 (* printConstrSet returns true if it printed at least
        !          3060:                    one constructor *)
        !          3061: 
        !          3062:                      if (printConstrSet(both,"Value",true)=true)
        !          3063:                        then say " | "
        !          3064:                        else ();
        !          3065:                      sayln void;
        !          3066:                      dec_margin();
        !          3067:                      sayln "";
        !          3068:                      dec_margin(); 
        !          3069:                      sayln "end";
        !          3070: 
        !          3071:                (* print LexValue structure *)
        !          3072: 
        !          3073:                      inc_margin();
        !          3074:                      sayln "structure LexValue =";
        !          3075:                      inc_margin();
        !          3076:                      sayln "struct";
        !          3077:                      sayln "open HDR;";
        !          3078:                      printConstrSet(terms,"V",false);
        !          3079:                      dec_margin();
        !          3080:                      sayln "";
        !          3081:                      dec_margin();
        !          3082:                      sayln "end";
        !          3083: 
        !          3084:                 (* print G (the grammar) structure *)
        !          3085: 
        !          3086:                      inc_margin();
        !          3087:                      sayln "structure G =";
        !          3088:                      inc_margin();
        !          3089:                      sayln "struct";
        !          3090: sayln
        !          3091: "\tdatatype Terminal = T of int\n\
        !          3092: \\tand     Nonterminal = NT of int\n\
        !          3093: \\n\
        !          3094: \\tval eqTerminal = fn ((T i),(T i')) => i = i'\n\
        !          3095: \\tval eqNonterminal = fn ((NT i),(NT i')) => i = i'";
        !          3096: 
        !          3097:                      saywd "datatype Symbol = TERM of Terminal | ";
        !          3098:                      sayln "NONTERM of Nonterminal";
        !          3099:                      newln();
        !          3100: 
        !          3101:                     let fun showSymbol(s,t,constr) =
        !          3102:                        (sayln ("fun "^s^" t = ");
        !          3103:                         sayln "case t"; saywd "of ";
        !          3104:                         ConstrSet.app
        !          3105:                         (fn (nt,{num,...}) =>
        !          3106:                                 ( say constr;
        !          3107:                                  say (makestring num);
        !          3108:                                  say " => ";
        !          3109:                                  sayln ("\""^nt^"\"");
        !          3110:                                  say " | "
        !          3111:                                  )
        !          3112:                          ) t; 
        !          3113:                        sayln "_ => \"bogus\"";
        !          3114:                        newln)
        !          3115:                     in (showSymbol ("showTerminalClass",terms,"T ");
        !          3116:                         showSymbol ("showNonterminal",nonterms,"NT "))
        !          3117:                     end;
        !          3118: 
        !          3119:                     sayln "fun showTerminalValue t = showTerminalClass t";
        !          3120:                     newln();
        !          3121: 
        !          3122:                     sayln "type Lineno = HDR.Lineno";
        !          3123:                     sayln "val lineno = HDR.lineno";
        !          3124:                     sayln "val error = HDR.error";
        !          3125: 
        !          3126:                     saywd "datatype Attribute = ATTRIB of {lhs: Nonterminal,";
        !          3127:                     sayln "rhsLength: int, num: int }";
        !          3128:                     newln();
        !          3129:                     saywd "fun showAttribute(ATTRIB{lhs,...}) =" = 
        !          3130:                     sayln "showNonterminal lhs";
        !          3131:                     newln();
        !          3132:                     saywd "datatype Rule = RULE of {lhs:Nonterminal,";
        !          3133:                     saywd "rhs: Symbol list,";
        !          3134:                     saywd "attribute : Attribute,";
        !          3135:                     sayln "precedence : int option }";
        !          3136:                     newln() ;
        !          3137:                    saywd "val ErrTermList=";
        !          3138:                    ConstrSet.app
        !          3139:                         (fn (x,{ty=NONE,num}) =>
        !          3140:                                if x=eof then ()
        !          3141:                                else saywd ("(T " ^ (makestring num) ^ ")::")
        !          3142:                           | _ => ()) terms;
        !          3143:                    sayln "nil";
        !          3144: 
        !          3145:              (* invoke Table generator *)
        !          3146: 
        !          3147:                let
        !          3148:                   exception TermNum
        !          3149:                   exception NontermNum
        !          3150:                   exception SymbolNum
        !          3151: 
        !          3152:                   val get_term_num = fn t => 
        !          3153:                        case ConstrSet.find (t,dummy_data) terms
        !          3154:                        of NONE => raise TermNum
        !          3155:                         | SOME (_,{num=num,...}) => num
        !          3156: 
        !          3157:                   val get_nonterm_num = fn nt => 
        !          3158:                        case ConstrSet.find (nt,dummy_data) nonterms
        !          3159:                        of NONE => raise NontermNum
        !          3160:                         | SOME (_,{num=num,...}) => num
        !          3161: 
        !          3162:                    val get_symbol = fn s =>
        !          3163:                        (G.TERM (G.T (get_term_num s)) handle TermNum =>
        !          3164:                            (G.NONTERM (G.NT (get_nonterm_num s)))
        !          3165:                                 handle NontermNum => raise SymbolNum
        !          3166:                        )
        !          3167: 
        !          3168:                    val numTerminals = ConstrSet.card terms
        !          3169:                    val numNonterminals = ConstrSet.card nonterms
        !          3170: 
        !          3171:                    val showTerminalClass =
        !          3172:                        let val b = array(numTerminals,"bogus")
        !          3173:                            val f = fn (s,{num=num,...}:constr_data) =>
        !          3174:                                update(b,num,s)
        !          3175:                            val _ = ConstrSet.app f terms
        !          3176:                        in fn (G.T i) => ((b sub i) handle _ => "bogus")
        !          3177:                        end
        !          3178: 
        !          3179:                    val showNonterminal =
        !          3180:                        let val b = array(numNonterminals,"bogus")
        !          3181:                            val f = fn (s,{num=num,...}:constr_data) =>
        !          3182:                                update(b,num,s)
        !          3183:                            val _ = ConstrSet.app f nonterms
        !          3184:                        in fn (G.NT i) => ((b sub i) handle _ => "bogus")
        !          3185:                        end
        !          3186: 
        !          3187:                   val _ =
        !          3188:                  (let val get_term_string = fn a =>
        !          3189:                        "(T " ^ (makestring (get_term_num a)) ^ ")"
        !          3190:                   in print_is_keyword_func (map get_term_string keyword);
        !          3191:                      print_preferred_insert_func
        !          3192:                                 (map get_term_string iprefer);
        !          3193:                      print_preferred_subst_func 
        !          3194:                                (map (fn (a,b) => ((get_term_string a),
        !          3195:                                                   map get_term_string b))
        !          3196:                                 prefer_map);
        !          3197:                      sayln ("val eof = " ^ (get_term_string eof))
        !          3198:                   end;
        !          3199:                   sayln ("val start = NT "^(makestring (get_nonterm_num start)));
        !          3200:                   dec_margin();
        !          3201:                   sayln "end"
        !          3202:                   )
        !          3203: 
        !          3204:                    val showTerminalValue = showTerminalClass
        !          3205: 
        !          3206:                    val showAttribute = fn (G.ATTRIB {lhs,rhsLength,num}) =>
        !          3207:                        showNonterminal lhs
        !          3208: 
        !          3209:                    val eof = G.T (get_term_num eof)
        !          3210:                    val start = G.NT (get_nonterm_num start)
        !          3211: 
        !          3212:                   val termPrecedence =
        !          3213:                        let val b = array(numTerminals,NONE)
        !          3214:                            val f = fn (tk,(j:int,p)) =>
        !          3215:                                      let val prec =
        !          3216:                                         SOME (case p of NONASSOC => j
        !          3217:                                                       | RIGHT => j+1
        !          3218:                                                       | LEFT => j-1)
        !          3219:                                       in update(b,get_term_num tk,prec)
        !          3220:                                       end
        !          3221:                             val _  = PrecSet.app f p
        !          3222:                        in fn (G.T i) => b sub i
        !          3223:                        end
        !          3224: 
        !          3225:                    val (_,rules) = 
        !          3226:                      List.fold (fn ({lhs=lhs,rhs=rhs,code=_,prec},(n,r)) =>
        !          3227:                      (let val newlhs = G.NT (get_nonterm_num lhs)
        !          3228:                           val newrhs = map get_symbol rhs
        !          3229:                           val newattrib =
        !          3230:                                 G.ATTRIB {lhs=newlhs,
        !          3231:                                           rhsLength=List.length rhs,
        !          3232:                                            num = n
        !          3233:                                          }
        !          3234:                            val newprec =
        !          3235:                             let fun f (a::b) =
        !          3236:                                   if (is_nonterm a) then f b else get_prec a
        !          3237:                                   | f nil = NONE
        !          3238:                             in case prec
        !          3239:                                 of NONE => f (rev rhs)
        !          3240:                                  | SOME i => get_prec i
        !          3241:                             end
        !          3242:                        in (n+1,(G.RULE {lhs=newlhs,rhs=newrhs,
        !          3243:                                        attribute=newattrib,
        !          3244:                                        precedence=newprec})::r)
        !          3245:                        end
        !          3246:                        )) TRULELIST (0,nil)
        !          3247: 
        !          3248:                in MakeTable.mktable (!out)
        !          3249:                        {rules=rules,verbose=verbose,
        !          3250:                         eof = eof, start = start,
        !          3251:                        termPrecedence = termPrecedence,
        !          3252:                        showTerminalClass = showTerminalClass,
        !          3253:                        showTerminalValue = showTerminalValue,
        !          3254:                        showNonterminal = showNonterminal,
        !          3255:                        showAttribute = showAttribute,
        !          3256:                        numTerminals = numTerminals,
        !          3257:                        numNonterminals = numNonterminals}
        !          3258:                end;
        !          3259: 
        !          3260:              (* Print R structure - actions for rules *)
        !          3261: 
        !          3262:                    sayln "structure R = ";
        !          3263:                    inc_margin();
        !          3264:                    sayln "struct";
        !          3265:                    saywd "val ErrValList = ";
        !          3266:                    ConstrSet.app (fn (x,{ty=NONE,...}) =>
        !          3267:                        if x=eof then ()
        !          3268:                        else saywd ("(V." ^ void ^ ")::") | _ => ()) terms;
        !          3269:                    sayln "nil";
        !          3270: 
        !          3271:                    sayln "exception mlyRULE of int";
        !          3272:                    sayln "fun rule(i,vl) =";
        !          3273:                    sayln "let open HDR";
        !          3274:                    sayln "    val rule_array = arrayoflist(";
        !          3275: 
        !          3276:                    let fun getconstr s = 
        !          3277:                         case (get_type(s,terms,nonterms))
        !          3278:                            of NONE => NONE
        !          3279:                             | SOME _ => SOME ("V."^s)
        !          3280: 
        !          3281: (* prlist : print list of arguments for a function for a rule *)
        !          3282: 
        !          3283:                  fun prlist rhs =
        !          3284: 
        !          3285: 
        !          3286: (* f: list of symbols for rhs, list of pairs of (symbol,last # used)
        !          3287:    Takes a rhs symbol, finds the correct variable name (eg. the number
        !          3288:    to attach to it, and whether or not to have a variable w/o a number
        !          3289:    if the rhs symbol is used only once)
        !          3290: *)
        !          3291: 
        !          3292:                     let fun f(nil,l) = ()
        !          3293:                           | f(t::rhs,l) =
        !          3294: 
        !          3295:                        let
        !          3296: 
        !          3297:                           fun g((e as (a,i))::b,r) =
        !          3298:                             if a=t then ((a,i+1)::(b@r),t^(makestring (i+1)))
        !          3299:                             else g(b,e::r)
        !          3300:                             | g(nil,r) =
        !          3301:                                  if (List.exists (fn a=>a=t) rhs) then
        !          3302:                                      ((t,1)::r,"("^t^"1)")
        !          3303:                                  else ((t,1)::r,"("^t^" as "^t^"1)")
        !          3304: 
        !          3305:                           val (newlist,var) = g(l,nil)
        !          3306: 
        !          3307:                         in 
        !          3308: 
        !          3309:                           (f(rhs,newlist);
        !          3310:                            saywd ("(" ^
        !          3311:                                   (case (getconstr t)
        !          3312:                                     of NONE => "_"
        !          3313:                                      | SOME i => ("(" ^ i ^ " " ^ var ^ ")")
        !          3314:                                   ) ^
        !          3315:                                  ")");
        !          3316:                            saywd "::"
        !          3317:                            )
        !          3318:                          end
        !          3319: 
        !          3320:                    in 
        !          3321:                        (f(rhs,nil); saywd "r672")
        !          3322:                    end
        !          3323: 
        !          3324:                     in
        !          3325:                        List.fold (fn ({lhs,rhs,code,prec},n) =>
        !          3326:                                  ( saywd "(fn (";
        !          3327:                                   prlist rhs;
        !          3328:                                   saywd ") => ((";
        !          3329: 
        !          3330:                                   let val constr = getconstr lhs
        !          3331:                                   in case constr
        !          3332:                                       of SOME i  => saywd i
        !          3333:                                        | NONE => ();
        !          3334:                                      saywd "(";
        !          3335:                                      saywd code;
        !          3336:                                      saywd ")";
        !          3337:                                      case constr
        !          3338:                                        of SOME i => ()
        !          3339:                                         | NONE => (saywd "; ";
        !          3340:                                                    saywd ("V."^void)
        !          3341:                                                   );
        !          3342:                                      sayln "),r672)";
        !          3343:                                      if (List.length rhs > 0) then
        !          3344:                                        (saywd "         | _ => raise mlyRULE ";
        !          3345:                                         saywd (makestring (n:int))
        !          3346:                                        )
        !          3347:                                      else ();
        !          3348:                                      sayln ")"
        !          3349:                                    end; saywd "::"; n+1)) TRULELIST 0
        !          3350:                     end;
        !          3351:                     sayln "nil)";
        !          3352:                     dec_margin();
        !          3353:                     sayln "in (rule_array sub i) vl end";
        !          3354:                     dec_margin();
        !          3355:                     sayln "type Value = V.Value";
        !          3356:                     say "val VOID = V.";
        !          3357:                     sayln void;
        !          3358:                     sayln "end";
        !          3359:                     dec_margin();
        !          3360: 
        !          3361:        (* print P structure - contains parsing function *)
        !          3362: 
        !          3363:                     sayln "structure P = ParserGen(structure Lr_Table = Lr_Table";
        !          3364:                     dec_margin();
        !          3365:                     sayln "                        structure RuleAction = R)";
        !          3366:                     sayln "fun parse (lex : unit -> (LexValue.V)) i= ";
        !          3367:                     inc_margin();
        !          3368:                     saywd "(fn (";
        !          3369:                     case (ConstrSet.find (start,dummy_data) nonterms) of
        !          3370:                         SOME (_,{ty=SOME _,...})
        !          3371:                              => (saywd "V."; saywd start; sayln " a) => a)")
        !          3372:                          | _ => sayln "_) => ())";
        !          3373:                     sayln "(P.parse (fn () => ";
        !          3374:                     inc_margin();
        !          3375:                     sayln "(case lex() of ";
        !          3376:                     ConstrSet.setfold (fn ((x,{ty=constr,num}),result) =>
        !          3377:                        (if result then () else saywd " | ";
        !          3378:                         say "(LexValue."; say x;
        !          3379:                         case constr
        !          3380:                           of NONE => (say ") => (G.T ";
        !          3381:                                       say (makestring num);
        !          3382:                                       sayln ("," ^ "V." ^ void ^")"))
        !          3383:                            | _ => (say " a) => (G.T ";
        !          3384:                                    say (makestring num);
        !          3385:                                    sayln ("," ^ "V." ^ x ^ " a)"));
        !          3386:                         false))
        !          3387:                     terms true;
        !          3388:                     dec_margin(); dec_margin();
        !          3389:                     sayln ")) i)";
        !          3390:                     sayln "end";
        !          3391:                     ()
        !          3392:                 )
        !          3393:        else ()
        !          3394: end handle SemanticError => ()
        !          3395: end)
        !          3396: end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.