Annotation of researchv10no/cmd/sml/lib/mlyacc/mlyacc.hdr.sml, revision 1.1.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.