Contributor: CLIF PENN { I am trying to write an algorithm(in pseudocode or Pascal) that converts a nonparenthesized infix expression to the equivalent postfix expression. For example, the infix expression 3 - 6 * 7 + 2 / 4 * 5 - 8 converts to the postfix expression ------ message termination by server was premature---- but postfix notation would be: 3 6 7 * - 2 4 / + 5 * 8 - In the program that follows, the input is a character string which is then converted to a linked list. If numeric values are desired, the VAL function can be used at the time the list is made. The advantage of the linked list approach is the ease with which the order of the terms may be rearranged. The disadvantage is the "write only" looking code that results--very un-Pascal like. Hopefully, the comments make it clearer. The conversion of infix to postfix notation follows these rules: 1. Multiplication and division take precedence over addition and subtraction. 2. Where operations are of equal precedence, they are performed in sequential order from left to right. The algorithm uses two linked lists. One is a queue, or FIFO, type list. Each node of this list is linked to the next and each node stores a "word" from the original math string in the same order as written. The other op linked list is a short list of one or two nodes which stores the math operations in order of their postfix execution. In both these lists, the last node points to nil. The math list is parsed from the front. Each operation is placed in the op list and removed from the longer list. The longer list is relinked and the op list is inserted in the proper position for postfix notation.11:12PM 3/1/96 --------------------------- } Program InFixToPostFix; { Written in Turbo Pascal v6.0 by Clif Penn, Mar 1, 1996 } Uses CRT; Label finis; TYPE link = ^node; { link is a pointer to a node } node = record nxt:link; { points to next node (or nil) } dat:string[12]; {length of 12 is arbitrary} end; VAR head, p1, p2, op:link; s, postfix:string; Procedure MakeWrdList(ss:string); VAR wrd:string[12]; { 12 is arbitrary } s1, s2, len:integer; pt1, pt2:link; Begin pt1 := nil; s1 := 1; len := Length(ss); While s1 < len do Begin { skip spaces } While (ss[s1] = ' ') AND (s1 < len) Do Inc(s1); s2 := s1; {start of word} { parse to next space } While (ss[s2] <> ' ') AND (s2 <= len) Do Inc(s2); wrd := Copy(ss, s1, s2 - s1); {extract wrd sans spaces} s1 := s2; {advance string index} pt2 := pt1; {initially pt2 to nil, normally move down list} new(pt1) ; {get address for pt1 from heap} if pt2 = nil then head := pt1; {head-->first node} pt2^.nxt := pt1; {links old node to new} pt1^.nxt := nil; {last node in list points to nil} pt1^.dat := wrd; {stores wrd in node} End; { After above: pt1 and pt2 no longer used head-->[arg1]-->[op1]-->[arg2]-->[ .... ]-->nil } End; Procedure ShowList; VAR tmp:link; Begin tmp := head; postfix := ''; While tmp <> nil do begin postfix := postfix + tmp^.dat + ' '; {concatanate string} tmp := tmp^.nxt; {traverse the list head to tail} end; Writeln(postfix); End; Procedure InsertOp; {Inserts Op node(s) into PostFix linked list} Begin p1^.nxt := op; {insert op, the last op node points to nil} While p1^.nxt <> nil do p1 := p1^.nxt; p1^.nxt := p2^.nxt; {remove p2 node from list} p1 := p1^.nxt; {last node of prev op now linked to list} op := p2; {new op becomes p2} op^.nxt := nil; p2 := p1; {both now point to next argument} End; Procedure ExtendOp; {Extracts math symbol node from PostFix list and extends Op list} Begin p1^.nxt := p2^.nxt; {remove p2 from list} p1 := p1^.nxt; {relink arg-->arg} p2^.nxt := op; {place p2 in front of old op} op := p2; {now op linked list has 2 nodes} p2 := p1 ; {both now point to next argument} End; Procedure DoPostFix(st:string); Const Hi = ['*', '/']; {Hi, Lo are math precedence rank of symbols} Lo = ['-', '+']; Begin MakeWrdList(st); p1 := head; {After this initialization, } op := nil; {p1, p2, arg1 --> arg2 } p2 := p1^.nxt; {op --> op1 --> nil } ExtendOp; While p2^.nxt <> nil Do {last node points to nil} Begin p2 := p2^.nxt; {p2 now pointing to math operation} {Conditional char comparisons follow} If (op^.dat[1] in Hi) OR (p2^.dat[1] in Lo) then InsertOp Else ExtendOp; End; p1^.nxt := op; {links final math operation(s)} End; BEGIN {main program} ClrScr; Writeln('Just press Enter to quit.'); Writeln; { Example } s := '3 - 6 * 7 + 2 / 4 * 5 - 8'; DoPostFix(s); Writeln('In postfix notation, the infix string:'); Writeln(s, ' becomes:'); ShowList; Repeat Writeln; Writeln('Infix math string (spaces between everything):'); Readln(s); If Length(s) < 5 then goto finis; DoPostFix(s); ShowList; Until Length(s) < 5; finis: END.