<> <> <> DIRECTORY Ascii, Basics, DisplayControllers, IO, RedBlackTree, RefText, Rope, StructuredStreams, UnparserBuffer; DisplayControllersPrinting: CEDAR PROGRAM IMPORTS IO, RedBlackTree, SS: StructuredStreams, UB: UnparserBuffer = {OPEN DisplayControllers; SymbolTable: TYPE = RedBlackTree.Table; TProc: TYPE = PROC [dc: DisplayController, clientData: REF ANY]; Print: PROC [to: IO.STREAM, cp: ControlProgram] = { PrintChar: PROC [c: CHAR] = { SELECT c FROM = 0C => to.PutRope["null"]; IN ['\001 .. '\040) => {to.PutChar['^]; to.PutChar[c + 64]}; = '\040 => to.PutRope["sp"]; IN ('\040 .. Ascii.DEL) => to.PutChar[c]; ENDCASE => to.PutF["\\%b", IO.int[c - 0C]]; }; PrintTransition: PROC [t: Transition] = { SS.Begin[to]; {ENABLE UNWIND => SS.End[to]; to.PutF[ "%g[%g] %g ", IO.refAny[NEW[TProc _ t.action.proc]], IO.refAny[t.action.clientData], IO.rope[IF t.action.overrideable THEN "*" ELSE "-"]]; SS.Bp[to, united, 1]; PrintVertex[t.newVertex]; }; SS.End[to]; }; printed: SymbolTable _ RedBlackTree.Create[Identity, CompareVertices]; PrintVertex: PROC [v: Vertex] = { SS.Begin[to]; {ENABLE UNWIND => SS.End[to]; IF v = cp.start THEN to.PutRope["start"] ELSE to.PutF["%b", IO.int[LOOPHOLE[v]]]; IF printed.Lookup[v] # NIL THEN {SS.End[to]; RETURN}; printed.Insert[v, v]; SS.Bp[to, united, 1]; SELECT v.repStyle FROM epsilon => { to.PutRope["{e "]; PrintTransition[v.t]; to.PutRope["}"]; }; list => { en: EdgeList; to.PutRope["{"]; SS.Begin[to]; {ENABLE UNWIND => SS.End[to]; to.PutRope["l "]; SS.Bp[to, united, 0]; PrintTransition[v.t]; FOR el: EdgeList _ v.edgeList, en WHILE el # NIL DO sgn, delta: INT _ 0; t: Transition _ el.first.transition; FOR en _ el.rest, en.rest WHILE en # NIL AND en.first.transition = t DO thisDelta: INT _ en.first.char - el.first.char; thisSgn: INT _ SGN[thisDelta]; IF sgn = 0 THEN sgn _ thisSgn; IF thisDelta # (delta + sgn) THEN EXIT; delta _ thisDelta; ENDLOOP; SS.Bp[to, united, 0]; to.PutRope["<["]; PrintChar[el.first.char]; IF delta # 0 THEN { to.PutRope[" .. "]; PrintChar[el.first.char + delta]}; to.PutRope["] "]; PrintTransition[t]; to.PutRope["> "]; ENDLOOP; }; SS.End[to]; to.PutRope["}"]; }; array => { first, next, num: INT; to.PutRope["{"]; SS.Begin[to]; {ENABLE UNWIND => SS.End[to]; to.PutRope["a "]; num _ 1 + (LAST[CHAR] - FIRST[CHAR]); FOR first _ 0, next WHILE first < num DO t: Transition _ v.edgeArray[0C + first]; FOR next _ first+1, next+1 WHILE next < num AND v.edgeArray[0C + next] = t DO NULL ENDLOOP; SS.Bp[to, united, 0]; to.PutRope["<["]; PrintChar[0C + first]; IF next > first+1 THEN { to.PutRope[" .. "]; PrintChar[0C + next-1]}; to.PutRope["] "]; PrintTransition[t]; to.PutRope["> "]; ENDLOOP; }; SS.End[to]; to.PutRope["}"]; }; ENDCASE => ERROR; }; SS.End[to]; }; to _ SS.Create[UB.NewInittedHandle[[margin: 59, output: [stream[to]]]]]; PrintVertex[cp.start]; to.PutRope["\n"]; to.Close[]; }; SGN: PROC [i: INT] RETURNS [s: [-1 .. 1]] = {s _ SELECT i FROM <0 => -1, =0 => 0, >0 => 1, ENDCASE => ERROR}; Identity: PROC [data: REF ANY] RETURNS [REF ANY] = {RETURN [data]}; CompareVertices: PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] = { i1: INT _ LOOPHOLE[k]; i2: INT _ LOOPHOLE[data]; c _ SELECT i1 FROM less, =i2 => equal, >i2 => greater, ENDCASE => ERROR; }; }.