{-------------------------------------------------------------} { routines for tree-walking. These routines abstract the } { idea of an in-order tour of the tree into a single record. } { The usual algorithm for a walk is recursive (see J&W 11.5), } { which is not convenient for this program. } {-------------------------------------------------------------} procedure initwalk(t:pnode; var w:treewalk); { initialize for a walk over the given tree } begin w.current := t; { start at the top node, } w.goneleft := false; { ..but descend left first off } w.top := 0 { stack is empty } end; procedure push(pn: pnode; var w: treewalk); { push a given node onto the walk-stack } begin if w.top0 then begin pop := w.stack[w.top]; w.top := w.top-1 end else pop := nil end; function treestep(var w:treewalk) : pnode; { step to the next node in lexical order in a tree. return that node as result, and save it in the walk record as "current." Return nil if end of tree. } var t : pnode; begin t := w.current; repeat if not w.goneleft then begin { descend to the left } if t<> nil then while t^.lson<>nil do begin push(t,w); t := t^.lson end; w.goneleft := true { t^ a left-leaf of tree } end else { been down; have handled current; go up/right} if t<> nil then if t^.rson <> nil then begin t := t^.rson; { jog right, then } w.goneleft := false { drop down again } end else { nowhere to go but up } t := pop(w) until w.goneleft; { repeats when we jog right } w.current := t; treestep := t end; function setscan(tree: pnode; var w: treewalk; var a: str) : pnode; { given a partial term "a," a tree "tree," and a tree- walk record "w," set up w so that a series of calls on function treestep will return all the nodes that are initially equal to a in ascending order. If there are none such, return nil. This function sets up for Term Recall when the escape key is pressed during input. The algorithm is to find the matching term that is highest in the tree, then use treestep to find the lexically-least node under that term (which may not be a match) and then to treestep to the first match.} var ua : str; p,t : pnode; r : relation; quit : boolean; begin stucase(a,ua); initwalk(tree,w); t := tree; if t=nil then setscan := nil { no matches possible } else begin { step 1 is to find any part-equal node at all } quit := false; repeat r := sxcomp(ua,t^.uref); case r of less : if t^.lson<>nil then t := t^.lson else quit := true; more : if t^.rson<>nil then t := t^.rson else quit := true; equal : quit := true end until quit; { If we have a match, it may not be the least one. If this node has a left-son, there can be lesser matches (and nonmatches) down that branch. } if r<>equal then setscan := nil { no match a-tall } else begin w.current := t; if t^.lson=nil then w.goneleft := true else begin { zoom down in tree } w.goneleft := false; repeat t := treestep(w); r := sxcomp(ua,t^.uref) until r=equal end; setscan := t end end end; p(w);