Annotation of researchv10no/cmd/sml/lib/twig/main.sml, revision 1.1

1.1     ! root        1: (* May 1989, Jussi Rintanen, Helsinki University of Technology *)
        !             2: 
        !             3: functor MAKEmain (structure Parser : PARSER
        !             4:                  and Automata : AUTOMATA
        !             5:                    sharing Automata.Parser = Parser)
        !             6:                    : sig val main : string -> unit end =
        !             7:   struct
        !             8: 
        !             9:     open Parser Automata
        !            10: 
        !            11:     val int2str : int -> string = makestring
        !            12: 
        !            13:     val accum = revfold
        !            14: 
        !            15:     fun count (a,nil) = 0
        !            16:       | count (a,h::t) = (if a = h then 1 else 0) + count (a,t)
        !            17: 
        !            18:     fun member p = (count p) <> 0
        !            19: 
        !            20: (* Output *)
        !            21: 
        !            22:     fun labellist (Leaf (Label l)) = [l]
        !            23:       | labellist (Tree (_,cs)) = accum (fn (c,ac) => ac@(labellist c)) cs []
        !            24:       | labellist _ = []
        !            25: 
        !            26:     fun index (passed,nil) = []
        !            27:       | index (passed,h::t) =
        !            28:        (if member (h,passed) orelse member (h,t)
        !            29:           then h^(int2str (count (h,passed) + 1))
        !            30:         else h):: (index (h::passed,t))
        !            31: 
        !            32:     fun emitlist' (e,nil) = ()
        !            33:       | emitlist' (e,[a]) = e a
        !            34:       | emitlist' (e,h::t) = (e h;e",";emitlist' (e,t))
        !            35: 
        !            36:     fun emitlist (e,l) = (e"[";emitlist'(e,l);e"]")
        !            37: 
        !            38:     fun emitcost (emit, rules, defaultcost) =
        !            39:       (emit "fun execute_cost (n:rule, ir, children) =\nlet open User\n";
        !            40:        case defaultcost of
        !            41:         NoCost => ()
        !            42:        | Cost code => (emit "val DC = ( "; app emit code; emit ") (map cost children)\n");
        !            43:        emit "val ABORT = (fn () => raise MatchAbort)\n in\ncase n of\n  ";
        !            44:        app (fn (Rule(n,_,_,p,Cost ss,_)) =>
        !            45:            (emit (int2str n);
        !            46:             emit " => (case map cost children of ";
        !            47:             emitlist (emit, index ([],labellist p));
        !            48:             emit " => (";
        !            49:             app emit ss;
        !            50:             emit ") | _ => raise InternalError \"S4\")\n  | ")
        !            51:               | (Rule(n,_,_,_,NoCost,_)) => (emit (int2str n);emit" => DC\n  | "))
        !            52:                   rules;
        !            53:        emit "_ => raise InternalError \"S4.3.\"\nend\n\n")
        !            54: 
        !            55:     fun tokens (passed,h::t) =
        !            56:       let val suffix =
        !            57:        if member (h,passed) orelse member (h,t)
        !            58:          then (int2str (count (h,passed)+1))
        !            59:        else ""
        !            60:       in
        !            61:        ("_"^h^" "^h^suffix,
        !            62:         "execute (nth(children,"^(int2str (length passed))^"))"
        !            63:         )::(tokens (h::passed,t))
        !            64:       end
        !            65:     | tokens _ = []
        !            66: 
        !            67:     fun reftokens ls = tokens ([],ls)
        !            68: 
        !            69:     fun DOtokens (passed,h::t) =
        !            70:       let val suffix =
        !            71:        if member (h,passed) orelse member (h,t)
        !            72:          then (int2str (count (h,passed)+1))
        !            73:        else ""
        !            74:       in
        !            75:        ("DO"^h^suffix,
        !            76: (*      "let val C = nth(children,"^(int2str (length passed))^")in fn () => let val _"^h^" V = execute C in V end end" *)
        !            77:         "let val C = nth(children,"^(int2str (length passed))^")in fn () => case execute C of _"^h^" V => V | _ => raise InternalError \"S4.3\" end"
        !            78:         )::(DOtokens (h::passed,t))
        !            79:       end
        !            80:       | DOtokens _ = []
        !            81: 
        !            82:     fun DOreftokens ls = DOtokens ([],ls)
        !            83: 
        !            84:     fun emittuple'(e,nil) = ()
        !            85:       | emittuple'(e,[a]) = e a
        !            86:       | emittuple'(e,h::t) = (e h;e",";emittuple'(e,t))
        !            87:        
        !            88:     fun emittuple (e,t) = (e"(";emittuple'(e,t);e")")
        !            89:       
        !            90:     fun emitval (e,l) =
        !            91:       (emittuple (e,map (fn (_,a) => a) l);
        !            92:        e" of ";
        !            93:        emittuple (e,map (fn (a,_) => a) l))
        !            94: 
        !            95:     fun emitaction (emit, rules) =
        !            96:       (emit "fun execute (Skeleton (n,_, ir, children)) =\n\
        !            97:        \ let open User\n";
        !            98:        emit "in\ncase n of\n";
        !            99:        app (fn (Rule(n,t,Label l,p,_,Action ss)) =>
        !           100:            let val labels = labellist p
        !           101:              in
        !           102:                emit (int2str n);
        !           103:                emit " => ";
        !           104:                  (case t of
        !           105:                     Ordinary => emit ("_"^l)
        !           106:                   | Topdown => emit ("_"^l)
        !           107:                   | Rewrite => emit "__rewrite");
        !           108:                     if labels <> nil
        !           109:                       then (emit " ( case ";
        !           110:                             (case t of
        !           111:                                Ordinary =>
        !           112:                                  emitval (emit,reftokens (labellist p))
        !           113:                              | Topdown =>
        !           114:                                  emitval (emit,DOreftokens (labellist p))
        !           115:                              | Rewrite => emitval (emit,[("_","()")]));
        !           116:                                emit " => ")
        !           117:                     else ();
        !           118:                     app emit ss;
        !           119:                     if labels <> nil
        !           120:                       then
        !           121:                         case t of
        !           122:                           Ordinary => emit " | _ => raise InternalError \"S5\" )"
        !           123:                         | Topdown => emit" )"
        !           124:                         | Rewrite => emit" )"
        !           125:                     else ();
        !           126:                     emit "\n  | "
        !           127:            end | _ => ())
        !           128:              rules;
        !           129:              emit "_ => raise Match\n";
        !           130:                emit "end\n\n")
        !           131: 
        !           132:     fun emitrewrite (emit, rules) =
        !           133:       (emit "fun rewriterule (r:rule) =\n\
        !           134:        \ case r of\n";
        !           135:        app (fn (Rule(n,Rewrite,_,_,_,_)) =>
        !           136:            (emit (int2str n); emit " => true |") | _ => ())
        !           137:               rules;
        !           138:        emit "_ => false\n")
        !           139: 
        !           140: (* Symbol datatype declaration *)
        !           141: 
        !           142:     fun symbol2str (Label s) = "__"^s
        !           143:       | symbol2str (Node (s,_)) = s
        !           144: 
        !           145:     fun emitsymbols (emit,symbols) =
        !           146:       let val maxarity =
        !           147:        accum
        !           148:        (fn (Node (_,a),max) => if a > max then a else max | (_,a) => a )
        !           149:           symbols 0
        !           150:       in
        !           151:        emit "ARC of int";
        !           152:        map
        !           153:        (fn s => emit (" | "^(symbol2str s)))
        !           154:           symbols;
        !           155:        emit "\n"
        !           156:       end
        !           157: 
        !           158: (* Unit match trees *)
        !           159:            
        !           160:     fun leafs (Leaf _) = 1
        !           161:       | leafs (Tree(_,cs)) = fold (op +) (map leafs cs) 0
        !           162: 
        !           163:     fun emitmatches (_,nil) = ()
        !           164:       | emitmatches (emit, (Rule(n0,_,_,p,_,_)::rules)) =
        !           165:       (emit "val matchcounts = [\n";
        !           166:       let val n =
        !           167:        (emit ("(" ^ (int2str n0) ^ "," ^ (int2str (leafs p)) ^ ")");
        !           168:         accum
        !           169:         (fn (Rule(n,_,_,p,_,_),m) =>
        !           170:            (emit (",\n(" ^ (int2str n) ^ "," ^ (int2str (leafs p)) ^ ")");
        !           171:            if n > m then n else m))
        !           172:              rules n0)
        !           173:       in
        !           174:         emit "]\nval matchtable = let val a = array(";
        !           175:         emit (int2str (n+1));
        !           176:         emit ",0) in ((app (fn(r,m)=>update (a,r,m)) matchcounts); a) end\n\n\
        !           177:           \fun matches r = matchtable sub r\n\n"
        !           178:       end)
        !           179: 
        !           180: (* Unit rules *)
        !           181: 
        !           182:     datatype matchtree = Chain of int * symbol * matchtree list
        !           183: 
        !           184:     fun closurize unitrules =
        !           185:       let val rec member =
        !           186:        (fn (a,nil) => false | (a,h::t) => if a=h then true else member (a,t))
        !           187:          val initials =
        !           188:            accum
        !           189:            (fn ((_,_,i),a) => if member (i,a) then a else i::a)
        !           190:               unitrules nil
        !           191:          fun build_unittree (nt,visited) =
        !           192:            accum (fn ((r,n,p),ac) =>
        !           193:                   if p = nt andalso not (member (n,visited))
        !           194:                     then Chain(r,n,build_unittree(n,n::visited))::ac
        !           195:                   else ac) unitrules nil
        !           196:       in
        !           197:        map (fn i => (i,build_unittree (i,[i]))) initials
        !           198:       end
        !           199:     
        !           200:     fun emitmatchtreelist (emit,nil) = ()
        !           201:       | emitmatchtreelist (emit,[m]) = emitmatchtree (emit, m)
        !           202:       | emitmatchtreelist (emit,(h::t)) = (emitmatchtree (emit,h); emit ","; emitmatchtreelist (emit,t))
        !           203:     and emitmatchtree (emit, Chain (i, j, ml)) =
        !           204:       (emit "Chain (";
        !           205:        emit (int2str i);
        !           206:        emit ",";
        !           207:        emit (symbol2str j);
        !           208:        emit ",[";
        !           209:        emitmatchtreelist (emit,ml);
        !           210:        emit "])")
        !           211: 
        !           212:     fun emitunitrules (emit, matchtrees,symbols) =
        !           213:       (emit "datatype matchtree = Chain of int * symbol * matchtree list\n";
        !           214:        emit "fun unitmatches nt = (case nt of\n";
        !           215:        app (fn (s,ms) => (emit (symbol2str s);
        !           216:                          emit " => [";
        !           217:                          emitmatchtreelist (emit,ms);
        !           218:                          emit "]\n  | "))
        !           219:            matchtrees;
        !           220:        emit "_ => [])\n\n")
        !           221: 
        !           222:     fun partition' (nil,u,n) = (u,n)
        !           223:       | partition' (Rule(r,_,l,Leaf s,_,_)::t,u,n) = partition' (t,(r,l,s)::u,n)
        !           224:       | partition' (r::t,u,n) = partition' (t,u,r::n)
        !           225: 
        !           226:     fun partition l = partition' (l,nil,nil)
        !           227: 
        !           228: (* Main *)
        !           229: 
        !           230:     fun fatal s = output std_out ("Fatal error: "^s^"\n")
        !           231: 
        !           232:     fun main inputfilename =
        !           233:       let
        !           234:        val outputfilename = inputfilename ^ ".sml"
        !           235:        val (inputf, outputf) = (open_in inputfilename,open_out outputfilename)
        !           236:        val emit = output outputf
        !           237:        val (inserts, rules, dcost, structuren, label_type, symbols) = specification inputf
        !           238:        val (unitrules, otherrules) = partition rules
        !           239:       in
        !           240:        emit "structure ";
        !           241:        emit structuren;
        !           242:        emit " =\n\
        !           243:        \struct\n\
        !           244:        \  structure User =\n\
        !           245:        \  struct\n\
        !           246:        \datatype symbol =\n";
        !           247:        emitsymbols (emit,symbols);
        !           248:        app (fn Prologue ss => (app emit ss) | Insert ss => (app emit ss)) inserts;
        !           249:        emit "\n\ndatatype result = __rewrite of tree | ";
        !           250:        emit label_type;
        !           251:        emit "\n end\n\n\
        !           252:        \structure Specification =\n\
        !           253:        \  struct\n\
        !           254:        \structure User = User\n\nopen User\n\
        !           255:        \type rule = int\n\
        !           256:        \datatype skeletal = Skeleton of (rule * cost * tree * skeletal list)\n\
        !           257:        \exception MatchAbort\n\
        !           258:        \fun cost (Skeleton(_,c,_,_)) = c\n\
        !           259:        \exception InternalError of string\n\n\
        !           260:        \fun get_subtree (n,t) = nth (get_subtrees t,n-1)\n\n";
        !           261:        emitcost (emit,rules,dcost);
        !           262:        emitaction (emit,rules);
        !           263:        emitmatches (emit, rules);
        !           264:        build_automaton (outputf,symbols,otherrules);
        !           265:        emitunitrules(emit, closurize unitrules,symbols);
        !           266:        emitrewrite (emit,rules);
        !           267:        emit "fun getreplacement (__rewrite t) = t | getreplacement _ = raise InternalError \"problem with rewrite 996\"\n\
        !           268:        \  end\n\
        !           269:         \structure Internal = MAKEtreeprocessor(Specification)\n\
        !           270:        \exception NoCover = Internal.NoCover\n\
        !           271:        \exception InternalError = Internal.InternalError\n\
        !           272:        \val translate = Internal.translate\n\
        !           273:         \end;\n";
        !           274:        close_in inputf;
        !           275:        close_out outputf
        !           276:       end
        !           277:     handle ParserError s => fatal s
        !           278:         | AutomatonError s => fatal s
        !           279:           
        !           280:   end;
        !           281: 
        !           282: structure Parser = MAKEparser(structure Symboltable = Symboltable
        !           283:                              and Lexer = Lexer);
        !           284: 
        !           285: structure Main = MAKEmain(structure Parser = Parser
        !           286:                          and Automata = MAKEautomata(structure Parser = Parser));

unix.superglobalmegacorp.com

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