Task: Parsing_RPN calculator algorithm







Python: def op_pow(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a ** b )
def op_mul(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a * b )
def op_div(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a / b )
def op_add(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a + b )
def op_sub(stack):
    b = stack.pop(); a = stack.pop()
    stack.append( a - b )
def op_num(stack, num):
    stack.append( num )
    
ops = {
 '^': op_pow,
 '*': op_mul,
 '/': op_div,
 '+': op_add,
 '-': op_sub,
 }

def get_input(inp = None):
    'Inputs an expression and returns list of tokens'
    
    if inp is None:
        inp = input('expression: ')
    tokens = inp.strip().split()
    return tokens

def rpn_calc(tokens):
    stack = []
    table = ['TOKEN,ACTION,STACK'.split(',')]
    for token in tokens:
        if token in ops:
            action = 'Apply op to top of stack'
            ops[token](stack)
            table.append( (token, action, ' '.join(str(s) for s in stack)) )
        else:
            action = 'Push num onto top of stack'
            op_num(stack, eval(token))
            table.append( (token, action, ' '.join(str(s) for s in stack)) )
    return table

if __name__ == '__main__':
    rpn = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
    print( 'For RPN expression: %r\n' % rpn )
    rp = rpn_calc(get_input(rpn))
    maxcolwidths = [max(len(y) for y in x) for x in zip(*rp)]
    row = rp[0]
    print( ' '.join('{cell:^{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))
    for row in rp[1:]:
        print( ' '.join('{cell:<{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))

    print('\n The final output value is: %r' % rp[-1][2])




Fortran:       REAL FUNCTION EVALRP(TEXT)	
Caution: deals with single digits only.
       CHARACTER*(*) TEXT	
       INTEGER SP,STACKLIMIT		
       PARAMETER (STACKLIMIT = 6)	
       REAL*8 STACK(STACKLIMIT)		
       INTEGER L,D		
       CHARACTER*4 DEED		
       CHARACTER*1 C		
        WRITE (6,1) TEXT	
    1   FORMAT ("Evaluation of the Reverse Polish string ",A,//	
     1   "Char Token Action  SP:Stack...")	
        SP = 0			
        STACK = -666		
        DO L = 1,LEN(TEXT)	
          C = TEXT(L:L)			
          IF (C.LE." ") CYCLE		
          D = ICHAR(C) - ICHAR("0")	
          IF (D.GE.0 .AND. D.LE.9) THEN	
            DEED = "Load"			
            SP = SP + 1				
            IF (SP.GT.STACKLIMIT) STOP "Stack overflow
            STACK(SP) = D			
           ELSE				
            IF (SP.LT.2) STOP "Stack underflow
            DEED = "XEQ"		
            SELECT CASE(C)		
             CASE("+"); STACK(SP - 1) = STACK(SP - 1) + STACK(SP)	
             CASE("-"); STACK(SP - 1) = STACK(SP - 1) - STACK(SP)	
             CASE("*"); STACK(SP - 1) = STACK(SP - 1)*STACK(SP)		
             CASE("/"); STACK(SP - 1) = STACK(SP - 1)/STACK(SP)		
             CASE("^"); STACK(SP - 1) = STACK(SP - 1)**STACK(SP)	
             CASE DEFAULT		
              STOP "Unknown operator
            END SELECT			
            SP = SP - 1		
          END IF		
          WRITE (6,2) L,C,DEED,SP,STACK(1:SP)	
    2     FORMAT (I4,A6,A7,I4,":",66F14.6)	
        END DO			
        EVALRP = STACK(1)	
      END	

      PROGRAM HSILOP
      REAL V
      V = EVALRP("3 4 2 * 1 5 - 2 3 ^ ^ / +")	
      WRITE (6,*) "Result is...",V
      END