Parsing/RPN to infix conversion: Difference between revisions

m
(Added C implementation.)
 
(38 intermediate revisions by 14 users not shown)
Line 9:
* Show how the major datastructure of your algorithm changes with each new token parsed.
* Test with the following input RPN strings then print and display the output here.
:::::{| class="wikitable"
! RPN input !! sample output
|- || align="center"
Line 18:
 
* Operator precedence and operator associativity is given in this table:
::::::::{| class="wikitable"
 
! operator !! [[wp:Order_of_operations|precedence]] !! [[wp:Operator_associativity|associativity]] !! operation
Line 39:
*   [http://www.rubyquiz.com/quiz148.html Postfix to infix]   from the RubyQuiz site.
<br><br>
 
=={{header|11l}}==
{{trans|Java}}
 
<syntaxhighlight lang="11l">-V ops = ‘-+/*^’
 
F postfix_to_infix(postfix)
T Expression
String op, ex
prec = 3
 
F (String e1, e2 = ‘’, o = ‘’)
I o == ‘’
.ex = e1
E
.ex = e1‘ ’o‘ ’e2
.op = o
.prec = :ops.index(o) I/ 2
 
F String()
R .ex
 
[Expression] expr
 
L(token) postfix.split(re:‘\s+’)
V c = token[0]
V? idx = :ops.find(c)
I idx != N
V r = expr.pop()
V l = expr.pop()
V opPrec = idx I/ 2
 
I l.prec < opPrec | (l.prec == opPrec & c == ‘^’)
l.ex = ‘(’l.ex‘)’
 
I r.prec < opPrec | (r.prec == opPrec & c != ‘^’)
r.ex = ‘(’r.ex‘)’
expr.append(Expression(l.ex, r.ex, token))
E
expr.append(Expression(token))
 
print(token‘ -> ’expr)
 
assert(expr.len == 1)
R expr[0].ex
 
L(e) [‘3 4 2 * 1 5 - 2 3 ^ ^ / +’,
‘1 2 + 3 4 + ^ 5 6 + ^’]
print(‘Postfix : ’e)
print(‘Infix : ’postfix_to_infix(e))
print()</syntaxhighlight>
 
{{out}}
<pre>
Postfix : 3 4 2 * 1 5 - 2 3 ^ ^ / +
3 -> [3]
4 -> [3, 4]
2 -> [3, 4, 2]
* -> [3, 4 * 2]
1 -> [3, 4 * 2, 1]
5 -> [3, 4 * 2, 1, 5]
- -> [3, 4 * 2, 1 - 5]
2 -> [3, 4 * 2, 1 - 5, 2]
3 -> [3, 4 * 2, 1 - 5, 2, 3]
^ -> [3, 4 * 2, 1 - 5, 2 ^ 3]
^ -> [3, 4 * 2, (1 - 5) ^ 2 ^ 3]
/ -> [3, 4 * 2 / (1 - 5) ^ 2 ^ 3]
+ -> [3 + 4 * 2 / (1 - 5) ^ 2 ^ 3]
Infix : 3 + 4 * 2 / (1 - 5) ^ 2 ^ 3
 
Postfix : 1 2 + 3 4 + ^ 5 6 + ^
1 -> [1]
2 -> [1, 2]
+ -> [1 + 2]
3 -> [1 + 2, 3]
4 -> [1 + 2, 3, 4]
+ -> [1 + 2, 3 + 4]
^ -> [(1 + 2) ^ (3 + 4)]
5 -> [(1 + 2) ^ (3 + 4), 5]
6 -> [(1 + 2) ^ (3 + 4), 5, 6]
+ -> [(1 + 2) ^ (3 + 4), 5 + 6]
^ -> [((1 + 2) ^ (3 + 4)) ^ (5 + 6)]
Infix : ((1 + 2) ^ (3 + 4)) ^ (5 + 6)
</pre>
 
=={{header|Ada}}==
Using the solution of the task [[stack]]:
<syntaxhighlight lang="ada">
<lang Ada>
type Priority is range 1..4;
type Infix is record
Line 125 ⟶ 209:
end;
end Convert;
</syntaxhighlight>
</lang>
The test program:
<syntaxhighlight lang="ada">
<lang Ada>
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO; use Ada.Text_IO;
Line 140 ⟶ 224:
Put_Line (Convert ("1 2 + 3 4 + ^ 5 6 + ^"));
end RPN_to_Infix;
</syntaxhighlight>
</lang>
should produce the following output
<pre>
Line 152 ⟶ 236:
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}}
Recursively parses the RPN string backwards to build a parse tree which is then printed.
<langsyntaxhighlight lang="algol68">
# rpn to infix - parses an RPN expression and generates the equivalent #
# infix expression #
Line 384 ⟶ 468:
 
)
</syntaxhighlight>
</lang>
{{out}}<pre>
parsing expression from: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Line 438 ⟶ 522:
1 2 + 3 4 + ^ 5 6 + ^: ( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )
</pre>
 
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<syntaxhighlight lang="ahk">expr := "3 4 2 * 1 5 - 2 3 ^ ^ / +"
 
stack := {push: func("ObjInsert"), pop: func("ObjRemove")}
out := "TOKEN`tACTION STACK (comma separated)`r`n"
Loop Parse, expr, %A_Space%
{
token := A_LoopField
if token is number
stack.push([0, token])
if isOp(token)
{
b := stack.pop(), a := stack.pop(), p := b.1 > a.1 ? b.1 : a.1
p := Precedence(token) > p ? precedence(token) : p
if (a.1 < b.1) and isRight(token)
stack.push([p, "( " . a.2 " ) " token " " b.2])
else if (a.1 > b.1) and isLeft(token)
stack.push([p, a.2 token " ( " b.2 " ) "])
else
stack.push([p, a.2 . " " . token . " " . b.2])
}
out .= token "`t" (isOp(token) ? "Push Partial expression "
: "Push num" space(16)) disp(stack) "`r`n"
}
out .= "`r`n The final output infix expression is: '" disp(stack) "'"
clipboard := out
isOp(t){
return (!!InStr("+-*/^", t) && t)
}
IsLeft(o){
return !!InStr("*/+-", o)
}
IsRight(o){
return o = "^"
}
Precedence(o){
return (InStr("+-/*^", o)+3)//2
}
Disp(obj){
for each, val in obj
if val[2]
o .= ", " val[2]
return SubStr(o,3)
}
Space(n){
return n>0 ? A_Space Space(n-1) : ""
}</syntaxhighlight>
;Output
<pre style="height:30ex;overflow:scroll;">TOKEN ACTION STACK (comma separated)
3 Push num 3
4 Push num 3, 4
2 Push num 3, 4, 2
* Push Partial expression 3, 4 * 2
1 Push num 3, 4 * 2, 1
5 Push num 3, 4 * 2, 1, 5
- Push Partial expression 3, 4 * 2, 1 - 5
2 Push num 3, 4 * 2, 1 - 5, 2
3 Push num 3, 4 * 2, 1 - 5, 2, 3
^ Push Partial expression 3, 4 * 2, 1 - 5, 2 ^ 3
^ Push Partial expression 3, 4 * 2, ( 1 - 5 ) ^ 2 ^ 3
/ Push Partial expression 3, 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
+ Push Partial expression 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
 
The final output infix expression is: '3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3'</pre>
 
=={{header|AWK}}==
Line 445 ⟶ 595:
The kludge is prepending the precedence on the front of the expressions stored on the stack. This shows up when the tail() function is used, and when 'x' is prepended as a placeholder when adding parenthesis.
 
<langsyntaxhighlight lang="awk">#!/usr/bin/awk -f
 
BEGIN {
Line 547 ⟶ 697:
return s
}
</syntaxhighlight>
</lang>
 
Output:
Line 593 ⟶ 743:
Infix: (moon * (stars + mud)) ^ (fire * soup)
 
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
<lang AHK>expr := "3 4 2 * 1 5 - 2 3 ^ ^ / +"
 
stack := {push: func("ObjInsert"), pop: func("ObjRemove")}
out := "TOKEN`tACTION STACK (comma separated)`r`n"
Loop Parse, expr, %A_Space%
{
token := A_LoopField
if token is number
stack.push([0, token])
if isOp(token)
{
b := stack.pop(), a := stack.pop(), p := b.1 > a.1 ? b.1 : a.1
p := Precedence(token) > p ? precedence(token) : p
if (a.1 < b.1) and isRight(token)
stack.push([p, "( " . a.2 " ) " token " " b.2])
else if (a.1 > b.1) and isLeft(token)
stack.push([p, a.2 token " ( " b.2 " ) "])
else
stack.push([p, a.2 . " " . token . " " . b.2])
}
out .= token "`t" (isOp(token) ? "Push Partial expression "
: "Push num" space(16)) disp(stack) "`r`n"
}
out .= "`r`n The final output infix expression is: '" disp(stack) "'"
clipboard := out
isOp(t){
return (!!InStr("+-*/^", t) && t)
}
IsLeft(o){
return !!InStr("*/+-", o)
}
IsRight(o){
return o = "^"
}
Precedence(o){
return (InStr("+-/*^", o)+3)//2
}
Disp(obj){
for each, val in obj
if val[2]
o .= ", " val[2]
return SubStr(o,3)
}
Space(n){
return n>0 ? A_Space Space(n-1) : ""
}</lang>
;Output
<pre style="height:30ex;overflow:scroll;">TOKEN ACTION STACK (comma separated)
3 Push num 3
4 Push num 3, 4
2 Push num 3, 4, 2
* Push Partial expression 3, 4 * 2
1 Push num 3, 4 * 2, 1
5 Push num 3, 4 * 2, 1, 5
- Push Partial expression 3, 4 * 2, 1 - 5
2 Push num 3, 4 * 2, 1 - 5, 2
3 Push num 3, 4 * 2, 1 - 5, 2, 3
^ Push Partial expression 3, 4 * 2, 1 - 5, 2 ^ 3
^ Push Partial expression 3, 4 * 2, ( 1 - 5 ) ^ 2 ^ 3
/ Push Partial expression 3, 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
+ Push Partial expression 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
 
The final output infix expression is: '3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3'</pre>
=={{header|C}}==
Takes RPN string from command line, string must be enclosed in double quotes. This is necessary since / and ^ are control characters for the command line. The second string, which can be any valid string, is optional and if supplied, the expression tree is printed out as it is built. The final expression is printed out in both cases.
<syntaxhighlight lang="c">
<lang C>
/*Abhishek Ghosh, 7th November 2017*/
 
#include<stdlib.h>
#include<string.h>
Line 788 ⟶ 871:
return 0;
}
</syntaxhighlight>
</lang>
Output, both final and traced outputs are shown:
<pre>
Line 828 ⟶ 911:
Final infix expression : (( 1 + 2 ) ^ ( 3 + 4 )) ^ ( 5 + 6 )
</pre>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
 
namespace PostfixToInfix
{
class Program
{
class Operator
{
public Operator(char t, int p, bool i = false)
{
Token = t;
Precedence = p;
IsRightAssociative = i;
}
 
public char Token { get; private set; }
public int Precedence { get; private set; }
public bool IsRightAssociative { get; private set; }
}
 
static IReadOnlyDictionary<char, Operator> operators = new Dictionary<char, Operator>
{
{ '+', new Operator('+', 2) },
{ '-', new Operator('-', 2) },
{ '/', new Operator('/', 3) },
{ '*', new Operator('*', 3) },
{ '^', new Operator('^', 4, true) }
};
 
class Expression
{
public String ex;
public Operator op;
 
public Expression(String e)
{
ex = e;
}
 
public Expression(String e1, String e2, Operator o)
{
ex = String.Format("{0} {1} {2}", e1, o.Token, e2);
op = o;
}
}
 
static String PostfixToInfix(String postfix)
{
var stack = new Stack<Expression>();
 
foreach (var token in Regex.Split(postfix, @"\s+"))
{
char c = token[0];
 
var op = operators.FirstOrDefault(kv => kv.Key == c).Value;
if (op != null && token.Length == 1)
{
Expression rhs = stack.Pop();
Expression lhs = stack.Pop();
 
int opPrec = op.Precedence;
 
int lhsPrec = lhs.op != null ? lhs.op.Precedence : int.MaxValue;
int rhsPrec = rhs.op != null ? rhs.op.Precedence : int.MaxValue;
 
if ((lhsPrec < opPrec || (lhsPrec == opPrec && c == '^')))
lhs.ex = '(' + lhs.ex + ')';
 
if ((rhsPrec < opPrec || (rhsPrec == opPrec && c != '^')))
rhs.ex = '(' + rhs.ex + ')';
 
stack.Push(new Expression(lhs.ex, rhs.ex, op));
}
else
{
stack.Push(new Expression(token));
}
 
// print intermediate result
Console.WriteLine("{0} -> [{1}]", token,
string.Join(", ", stack.Reverse().Select(e => e.ex)));
}
return stack.Peek().ex;
}
 
static void Main(string[] args)
{
string[] inputs = { "3 4 2 * 1 5 - 2 3 ^ ^ / +", "1 2 + 3 4 + ^ 5 6 + ^" };
foreach (var e in inputs)
{
Console.WriteLine("Postfix : {0}", e);
Console.WriteLine("Infix : {0}", PostfixToInfix(e));
Console.WriteLine(); ;
}
Console.ReadLine();
}
}
}</syntaxhighlight>
<pre>3 -> [3]
4 -> [3, 4]
2 -> [3, 4, 2]
* -> [3, 4 * 2]
1 -> [3, 4 * 2, 1]
5 -> [3, 4 * 2, 1, 5]
- -> [3, 4 * 2, 1 - 5]
2 -> [3, 4 * 2, 1 - 5, 2]
3 -> [3, 4 * 2, 1 - 5, 2, 3]
^ -> [3, 4 * 2, 1 - 5, 2 ^ 3]
^ -> [3, 4 * 2, (1 - 5) ^ 2 ^ 3]
/ -> [3, 4 * 2 / (1 - 5) ^ 2 ^ 3]
+ -> [3 + 4 * 2 / (1 - 5) ^ 2 ^ 3]
Infix : 3 + 4 * 2 / (1 - 5) ^ 2 ^ 3
 
Postfix : 1 2 + 3 4 + ^ 5 6 + ^
1 -> [1]
2 -> [1, 2]
+ -> [1 + 2]
3 -> [1 + 2, 3]
4 -> [1 + 2, 3, 4]
+ -> [1 + 2, 3 + 4]
^ -> [(1 + 2) ^ (3 + 4)]
5 -> [(1 + 2) ^ (3 + 4), 5]
6 -> [(1 + 2) ^ (3 + 4), 5, 6]
+ -> [(1 + 2) ^ (3 + 4), 5 + 6]
^ -> [((1 + 2) ^ (3 + 4)) ^ (5 + 6)]
Infix : ((1 + 2) ^ (3 + 4)) ^ (5 + 6)</pre>
 
=={{header|C++}}==
Very primitive implementation, doesn't use any parsing libraries which would shorten this greatly.
<syntaxhighlight lang="cpp">
<lang Cpp>
/*Corrected by Abhishek Ghosh, 6th November 2017*/
#include <iostream>
#include <stack>
Line 910 ⟶ 1,125:
}
}
</syntaxhighlight>
</lang>
Output :
<pre>
Line 919 ⟶ 1,134:
=={{header|Common Lisp}}==
Tested on ABCL.
<langsyntaxhighlight lang="lisp">
;;;; Parsing/RPN to infix conversion
(defstruct (node (:print-function print-node)) opr infix)
Line 979 ⟶ 1,194:
(format t "~%Parsing:\"~A\"~%" expr)
(format t "RPN:\"~A\" INFIX:\"~A\"~%" expr (parse expr)))))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,078 ⟶ 1,293:
=={{header|D}}==
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.stdio, std.string, std.array;
 
void parseRPN(in string e) {
Line 1,120 ⟶ 1,335:
"1 2 + 3 4 + ^ 5 6 + ^"])
parseRPN(test);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,211 ⟶ 1,426:
 
===Alternative Version===
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="d">import std.stdio, std.string, std.array, std.algorithm;
 
void rpmToInfix(in string str) @safe {
Line 1,246 ⟶ 1,461:
"3 4 2 * 1 5 - 2 3 ^ ^ / +".rpmToInfix;
"1 2 + 3 4 + ^ 5 6 + ^".rpmToInfix;
}</langsyntaxhighlight>
{{out}}
<pre>=================
Line 1,280 ⟶ 1,495:
-----------------
( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )</pre>
 
 
=={{header|EchoLisp}}==
For convenience, modularity, reusability, and the fun of it, we split the task into two parts. '''rpn->infix''' checks the rpn expression and builds an infix - lisp - tree (which can be the input of an infix calculator). '''infix->string''' takes a tree in input and builds the required string.
 
<langsyntaxhighlight lang="scheme">
(require 'hash)
(string-delimiter "")
Line 1,346 ⟶ 1,560:
(when (right-par? node) (set! rhs (string-append "(" rhs ")")))
(string-append lhs " " node.op " " rhs))]))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,387 ⟶ 1,601:
 
=={{header|F Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">type ast =
| Num of int
| Add of ast * ast | Sub of ast * ast
Line 1,435 ⟶ 1,649:
Seq.iter (printf " %s") (infix 0 tree); printfn ""
0
</syntaxhighlight>
</lang>
Input is given via the command line.
Output includes the abstract syntax tree generated for the input.
Line 1,447 ⟶ 1,661:
=={{header|Go}}==
No error checking.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,509 ⟶ 1,723:
}
fmt.Println("infix:", stack[0].expr)
}</langsyntaxhighlight>
Output:
<pre>
Line 1,599 ⟶ 1,813:
infix: ((1 + 2) ^ (3 + 4)) ^ (5 + 6)
</pre>
 
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">class PostfixToInfix {
static class Expression {
final static String ops = "-+/*^"
 
String op, ex
int precedence = 3
 
Expression(String e) {
ex = e
}
 
Expression(String e1, String e2, String o) {
ex = String.format "%s %s %s", e1, o, e2
op = o
precedence = (ops.indexOf(o) / 2) as int
}
 
@Override
String toString() {
return ex
}
}
 
static String postfixToInfix(final String postfix) {
Stack<Expression> expr = new Stack<>()
 
for (String token in postfix.split("\\s+")) {
char c = token.charAt(0)
int idx = Expression.ops.indexOf(c as int)
if (idx != -1 && token.length() == 1) {
 
Expression r = expr.pop()
Expression l = expr.pop()
 
int opPrecedence = (idx / 2) as int
 
if (l.precedence < opPrecedence || (l.precedence == opPrecedence && c == '^' as char))
l.ex = '(' + l.ex + ')'
 
if (r.precedence < opPrecedence || (r.precedence == opPrecedence && c != '^' as char))
r.ex = '(' + r.ex + ')'
 
expr << new Expression(l.ex, r.ex, token)
} else {
expr << new Expression(token)
}
printf "%s -> %s%n", token, expr
}
expr.peek().ex
}
 
static void main(String[] args) {
(["3 4 2 * 1 5 - 2 3 ^ ^ / +", "1 2 + 3 4 + ^ 5 6 + ^"]).each { String e ->
printf "Postfix : %s%n", e
printf "Infix : %s%n", postfixToInfix(e)
println()
}
}
}</syntaxhighlight>
{{out}}
<pre>Postfix : 3 4 2 * 1 5 - 2 3 ^ ^ / +
3 -> [3]
4 -> [3, 4]
2 -> [3, 4, 2]
* -> [3, 4 * 2]
1 -> [3, 4 * 2, 1]
5 -> [3, 4 * 2, 1, 5]
- -> [3, 4 * 2, 1 - 5]
2 -> [3, 4 * 2, 1 - 5, 2]
3 -> [3, 4 * 2, 1 - 5, 2, 3]
^ -> [3, 4 * 2, 1 - 5, 2 ^ 3]
^ -> [3, 4 * 2, (1 - 5) ^ 2 ^ 3]
/ -> [3, 4 * 2 / (1 - 5) ^ 2 ^ 3]
+ -> [3 + 4 * 2 / (1 - 5) ^ 2 ^ 3]
Infix : 3 + 4 * 2 / (1 - 5) ^ 2 ^ 3
 
Postfix : 1 2 + 3 4 + ^ 5 6 + ^
1 -> [1]
2 -> [1, 2]
+ -> [1 + 2]
3 -> [1 + 2, 3]
4 -> [1 + 2, 3, 4]
+ -> [1 + 2, 3 + 4]
^ -> [(1 + 2) ^ (3 + 4)]
5 -> [(1 + 2) ^ (3 + 4), 5]
6 -> [(1 + 2) ^ (3 + 4), 5, 6]
+ -> [(1 + 2) ^ (3 + 4), 5 + 6]
^ -> [((1 + 2) ^ (3 + 4)) ^ (5 + 6)]
Infix : ((1 + 2) ^ (3 + 4)) ^ (5 + 6)</pre>
 
=={{header|Haskell}}==
Line 1,605 ⟶ 1,911:
This solution is a rough translation of the solution provided on RubyQuiz, as linked above.
 
<syntaxhighlight lang="haskell">import Debug.Trace
<lang Haskell>
 
data Expression = Const String | Exp Expression String Expression
 
------------- INFIX EXPRESSION FROM RPN STRING -----------
precedence :: Expression -> Int
 
precedence (Const _) = 5
infixFromRPN :: String -> Expression
precedence (Exp _ op _)
infixFromRPN = head . foldl buildExp [] . words
| op `elem` ["^"] = 4
 
| op `elem` ["*","/"] = 3
buildExp :: [Expression] -> String -> [Expression]
| op `elem` ["+","-"] = 2
buildExp stack x
| otherwise = 0
| (not . isOp) x =
let v = Const x : stack
in trace (show v) v
| otherwise =
let v = Exp l x r : rest
in trace (show v) v
where
r : l : rest = stack
isOp = (`elem` ["^", "*", "/", "+", "-"])
 
 
--------------------------- TEST -------------------------
main :: IO ()
main =
mapM_
( \s ->
putStr (s <> "\n-->\n")
>> (print . infixFromRPN)
s
>> putStrLn []
)
[ "3 4 2 * 1 5 - 2 3 ^ ^ / +",
"1 2 + 3 4 + ^ 5 6 + ^",
"1 4 + 5 3 + 2 3 * * *",
"1 2 * 3 4 * *",
"1 2 + 3 4 + +"
]
 
---------------------- SHOW INSTANCE ---------------------
instance Show Expression where
show (Const x) = x
show exp@(Exp l op r) = left <> " " <> op <> " " <> right
where
left
| leftNeedParen = "( " <> show l <> " )"
| otherwise = show l
right
| rightNeedParen = "( " <> show r <> " )"
| otherwise = show r
leftNeedParen =
(leftPrec < opPrec)
|| ((leftPrec == opPrec) && rightAssoc exp)
rightNeedParen =
(rightPrec < opPrec)
|| ((rightPrec == opPrec) && leftAssoc exp)
leftPrec = precedence l
rightPrec = precedence r
opPrec = precedence exp
 
leftAssoc :: Expression -> Bool
leftAssoc (Const _) = False
leftAssoc (Exp _ op _) = op `notElem` ["^", "*", "+"]
 
rightAssoc :: Expression -> Bool
rightAssoc (Const _) = False
rightAssoc (Exp _ op _) = op `elem`== ["^"]
 
instanceprecedence Show:: Expression where-> Int
showprecedence (Const x_) = x5
precedence (Exp _ op _)
show exp@(Exp l op r) = left++" "++op++" "++right
| op == "^" = 4
where left = if leftNeedParen then "( "++(show l)++" )" else show l
| op `elem` ["*", "/"] = 3
right = if rightNeedParen the "( "++(show r)++" )" else show r
| op `elem` ["+", "-"] = 2
leftNeedParen = (leftPrec < opPrec) || ((leftPrec == opPrec) && (rightAssoc exp))
| otherwise = 0</syntaxhighlight>
rightNeedParen = (rightPrec < opPrec) || ((rightPrec == opPrec) && (leftAssoc exp))
{{Out}}
leftPrec = precedence l
<pre>3 4 2 * 1 5 - 2 3 ^ ^ / +
rightPrec = precedence r
-->
opPrec = precedence exp
[3]
 
[4,3]
buildExp :: [Expression] -> String -> [Expression]
[2,4,3]
buildExp stack x
[4 * 2,3]
| not.isOp $ x = Const x : stack
[1,4 * 2,3]
| otherwise = Exp l x r : rest
[5,1,4 * 2,3]
where r:l:rest = stack
[1 - 5,4 * 2,3]
isOp = (`elem` ["^","*","/","+","-"])
[2,1 - 5,4 * 2,3]
[3,2,1 - 5,4 * 2,3]
[2 ^ 3,1 - 5,4 * 2,3]
[( 1 - 5 ) ^ 2 ^ 3,4 * 2,3]
[4 * 2 / ( 1 - 5 ) ^ 2 ^ 3,3]
[3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3]
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
 
main = do
contents <- getContents
mapM_ (print.head.(foldl buildExp []).words) (lines contents)
</lang>
 
Input:
<pre>
3 4 2 * 1 5 - 2 3 ^ ^ / +
1 2 + 3 4 + ^ 5 6 + ^
-->
1 4 + 5 3 + 2 3 * * *
[1]
1 2 * 3 4 * *
[2,1]
1 2 + 3 4 + +
[1 + 2]
</pre>
[3,1 + 2]
 
[4,3,1 + 2]
Output:
[3 + 4,1 + 2]
<pre>
3[( 1 + 42 *) 2 /^ ( 13 -+ 54 ) ^ 2 ^ 3]
[5,( 1 + 2 ) ^ ( 3 + 4 )]
[6,5,( 1 + 2 ) ^ ( 3 + 4 )]
[5 + 6,( 1 + 2 ) ^ ( 3 + 4 )]
[( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )]
( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )
 
1 4 + 5 3 + 2 3 * * *
-->
[1]
[4,1]
[1 + 4]
[5,1 + 4]
[3,5,1 + 4]
[5 + 3,1 + 4]
[2,5 + 3,1 + 4]
[3,2,5 + 3,1 + 4]
[2 * 3,5 + 3,1 + 4]
[( 5 + 3 ) * 2 * 3,1 + 4]
[( 1 + 4 ) * ( 5 + 3 ) * 2 * 3]
( 1 + 4 ) * ( 5 + 3 ) * 2 * 3
 
1 2 * 3 4 * *
-->
[1]
[2,1]
[1 * 2]
[3,1 * 2]
[4,3,1 * 2]
[3 * 4,1 * 2]
[1 * 2 * 3 * 4]
1 * 2 * 3 * 4
 
1 + 2 + 3 + 4
1 2 + 3 4 + +
</pre>
-->
[1]
[2,1]
[1 + 2]
[3,1 + 2]
[4,3,1 + 2]
[3 + 4,1 + 2]
1 + 2 + 3 + 4</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
every rpn := ![
"3 4 2 * 1 5 - 2 3 ^ ^ / +", # reqd
Line 1,723 ⟶ 2,113:
else x) || " "
return s || "]"
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 1,758 ⟶ 2,148:
Implementation:
 
<langsyntaxhighlight lang="j">tokenize=: ' ' <;._1@, deb
 
ops=: ;:'+ - * / ^'
Line 1,793 ⟶ 2,183:
stack=: stack,_;y
smoutput stack
)</langsyntaxhighlight>
 
The stack structure has two elements for each stack entry: expression precedence and expression characters.
Line 1,799 ⟶ 2,189:
Required example:
 
<langsyntaxhighlight lang="j"> parse '3 4 2 * 1 5 - 2 3 ^ ^ / +'
pushing: 3
+-+-+
Line 1,900 ⟶ 2,290:
|2|3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3|
+-+-----------------------------+
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|7}}
<syntaxhighlight lang="java">import java.util.Stack;
<lang java>public class PostfixToInfix {
 
public class PostfixToInfix {
 
public static void main(String[] args) {
Line 1,965 ⟶ 2,357:
return expr.peek().ex;
}
}</langsyntaxhighlight>
 
Output:
Line 2,002 ⟶ 2,394:
Needs EcmaScript 6 support (e.g. Chrome).
 
<langsyntaxhighlight lang="javascript">const Associativity = {
/** a / b / c = (a / b) / c */
left: 0,
Line 2,060 ⟶ 2,452:
const realOup = rpnToTree(inp).toString();
console.log(realOup === oup ? "Correct!" : "Incorrect!");
}</langsyntaxhighlight>
 
Output:
Line 2,098 ⟶ 2,490:
read +, stack = [1 + 2 + 3]
Correct!</pre>
 
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
 
This entry is based on the observation that the Parsing Expression Grammar (PEG)
for the reversed sequence of tokens of an RPN expression is essentially:
<pre>
E = operator operand operand
operand = number / E
operator = '+' | '-' | '*' | '^'
</pre>
 
it being understood that a subsequence [operator, operand1, operand2]
must finally be rendered as "(operand2 operator operand1)" because of
the reversal.
 
This PEG is so simple that only one of the functions from
[[:Category:Jq/peg.jq]], the jq library supporting PEG parsing, is
needed here, namely: `box/1`. It is therefore included in the
following listing, so there is no need to include peg.jq.
 
Notice also that the task requirements imply that the RPN string can
be readily tokenized using `splits/1`, as is done by `tokens/0`.
<syntaxhighlight lang=jq>
### PEG infrastructure
def box(E):
((.result = null) | E) as $e
| .remainder = $e.remainder
| .result += [$e.result] # the magic sauce
;
 
### Tokenize the RPN string.
# Input: a string representing an expression using RPN.
# Output: an array of corresponding tokens.
def tokens:
[splits("[ \n\r\t]+")]
| map(select(. != "")
| . as $in
| try tonumber catch $in);
 
### Parse the reversed array of tokens as produced by `tokens`.
# On entry, .remainder should be the reversed array.
# Output: {remainder, result}
def rrpn:
def found: .result += [.remainder[0]] | (.remainder |= .[1:]);
def nonempty: select(.remainder|length>0);
def check(predicate):
nonempty | select(.remainder[0] | predicate);
 
def recognize(predicate): check(predicate) | found;
 
def number : recognize(type=="number");
def operator: recognize(type=="string");
def operand : number // rrpn;
box(operator | operand | operand);
 
# Input: an array of tokens as produced by `tokens`
# Output: the infix equivalent expressed as a string.
def tokens2infix:
def infix:
if type != "array" then .
elif length == 1 then .[0] | infix
elif length == 3 then "(\(.[2] | infix) \(.[0]) \(.[1] | infix))"
else error
end;
 
{remainder: reverse} | rrpn | .result | infix;
 
# Input: an RPN string
# Output: the equivalent expression as a string using infix notation
def rpn2infix: tokens | tokens2infix;
 
def tests:
"3 4 2 * 1 5 - 2 3 ^ ^ / +",
"1 2 + 3 4 + ^ 5 6 + ^"
;
 
tests | "\"\(.)\" =>", rpn2infix, ""
</syntaxhighlight>
{{output}}
"3 4 2 * 1 5 - 2 3 ^ ^ / +" =>
(3 + ((4 * 2) / ((1 - 5) ^ (2 ^ 3))))
 
"1 2 + 3 4 + ^ 5 6 + ^" =>
(((1 + 2) ^ (3 + 4)) ^ (5 + 6))
</pre>
=={{header|Julia}}==
<syntaxhighlight lang="julia">
function parseRPNstring(rpns)
infix = []
rpn = split(rpns)
for tok in rpn
if all(isnumber, tok)
push!(infix, parse(Int, tok))
else
last = pop!(infix)
prev = pop!(infix)
push!(infix, Expr(:call, Symbol(tok), prev, last))
println("Current step: $infix")
end
end
infix
end
 
unany(s) = replace(string(s), r"Any\[:\((.+)\)\]", s"\1")
 
println("The final infix result: ", parseRPNstring("3 4 2 * 1 5 - 2 3 ^ ^ / +") |> unany, "\n")
println("The final infix result: ", parseRPNstring("1 2 + 3 4 + ^ 5 6 + ^") |> unany)
</syntaxhighlight>
{{output}}
<pre>
Current step: Any[3, :(4 * 2)]
Current step: Any[3, :(4 * 2), :(1 - 5)]
Current step: Any[3, :(4 * 2), :(1 - 5), :(2 ^ 3)]
Current step: Any[3, :(4 * 2), :((1 - 5) ^ (2 ^ 3))]
Current step: Any[3, :((4 * 2) / (1 - 5) ^ (2 ^ 3))]
Current step: Any[:(3 + (4 * 2) / (1 - 5) ^ (2 ^ 3))]
The final infix result: 3 + (4 * 2) / (1 - 5) ^ (2 ^ 3)
 
Current step: Any[:(1 + 2)]
Current step: Any[:(1 + 2), :(3 + 4)]
Current step: Any[:((1 + 2) ^ (3 + 4))]
Current step: Any[:((1 + 2) ^ (3 + 4)), :(5 + 6)]
Current step: Any[:(((1 + 2) ^ (3 + 4)) ^ (5 + 6))]
The final infix result: ((1 + 2) ^ (3 + 4)) ^ (5 + 6)
</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.2.0
 
import java.util.Stack
 
class Expression(var ex: String, val op: String = "", val prec: Int = 3) {
 
constructor(e1: String, e2: String, o: String) :
this("$e1 $o $e2", o, OPS.indexOf(o) / 2)
 
override fun toString() = ex
 
companion object {
const val OPS = "-+/*^"
}
}
 
fun postfixToInfix(postfix: String): String {
val expr = Stack<Expression>()
val rx = Regex("""\s+""")
for (token in postfix.split(rx)) {
val c = token[0]
val idx = Expression.OPS.indexOf(c)
if (idx != -1 && token.length == 1) {
val r = expr.pop()
val l = expr.pop()
val opPrec = idx / 2
if (l.prec < opPrec || (l.prec == opPrec && c == '^')) {
l.ex = "(${l.ex})"
}
if (r.prec < opPrec || (r.prec == opPrec && c != '^')) {
r.ex = "(${r.ex})"
}
expr.push(Expression(l.ex, r.ex, token))
}
else {
expr.push(Expression(token))
}
println("$token -> $expr")
}
return expr.peek().ex
}
 
fun main(args: Array<String>) {
val es = listOf(
"3 4 2 * 1 5 - 2 3 ^ ^ / +",
"1 2 + 3 4 + ^ 5 6 + ^"
)
for (e in es) {
println("Postfix : $e")
println("Infix : ${postfixToInfix(e)}\n")
}
}</syntaxhighlight>
 
{{out}}
<pre>
Postfix : 3 4 2 * 1 5 - 2 3 ^ ^ / +
3 -> [3]
4 -> [3, 4]
2 -> [3, 4, 2]
* -> [3, 4 * 2]
1 -> [3, 4 * 2, 1]
5 -> [3, 4 * 2, 1, 5]
- -> [3, 4 * 2, 1 - 5]
2 -> [3, 4 * 2, 1 - 5, 2]
3 -> [3, 4 * 2, 1 - 5, 2, 3]
^ -> [3, 4 * 2, 1 - 5, 2 ^ 3]
^ -> [3, 4 * 2, (1 - 5) ^ 2 ^ 3]
/ -> [3, 4 * 2 / (1 - 5) ^ 2 ^ 3]
+ -> [3 + 4 * 2 / (1 - 5) ^ 2 ^ 3]
Infix : 3 + 4 * 2 / (1 - 5) ^ 2 ^ 3
 
Postfix : 1 2 + 3 4 + ^ 5 6 + ^
1 -> [1]
2 -> [1, 2]
+ -> [1 + 2]
3 -> [1 + 2, 3]
4 -> [1 + 2, 3, 4]
+ -> [1 + 2, 3 + 4]
^ -> [(1 + 2) ^ (3 + 4)]
5 -> [(1 + 2) ^ (3 + 4), 5]
6 -> [(1 + 2) ^ (3 + 4), 5, 6]
+ -> [(1 + 2) ^ (3 + 4), 5 + 6]
^ -> [((1 + 2) ^ (3 + 4)) ^ (5 + 6)]
Infix : ((1 + 2) ^ (3 + 4)) ^ (5 + 6)
</pre>
 
=={{header|Lua}}==
The ouput contains more parenthesis then in strictly nessicary, but otherwise seems to read correctly
<syntaxhighlight lang="lua">function tokenize(rpn)
local out = {}
local cnt = 0
for word in rpn:gmatch("%S+") do
table.insert(out, word)
cnt = cnt + 1
end
return {tokens = out, pos = 1, size = cnt}
end
 
function advance(lex)
if lex.pos <= lex.size then
lex.pos = lex.pos + 1
return true
else
return false
end
end
 
function current(lex)
return lex.tokens[lex.pos]
end
 
function isOperator(sym)
return sym == '+' or sym == '-'
or sym == '*' or sym == '/'
or sym == '^'
end
 
function buildTree(lex)
local stack = {}
 
while lex.pos <= lex.size do
local sym = current(lex)
advance(lex)
 
if isOperator(sym) then
local b = table.remove(stack)
local a = table.remove(stack)
 
local t = {op=sym, left=a, right=b}
table.insert(stack, t)
else
table.insert(stack, sym)
end
end
 
return table.remove(stack)
end
 
function infix(tree)
if type(tree) == "table" then
local a = {}
local b = {}
 
if type(tree.left) == "table" then
a = '(' .. infix(tree.left) .. ')'
else
a = tree.left
end
 
if type(tree.right) == "table" then
b = '(' .. infix(tree.right) .. ')'
else
b = tree.right
end
 
return a .. ' ' .. tree.op .. ' ' .. b
else
return tree
end
end
 
function convert(str)
local lex = tokenize(str)
local tree = buildTree(lex)
print(infix(tree))
end
 
function main()
convert("3 4 2 * 1 5 - 2 3 ^ ^ / +")
convert("1 2 + 3 4 + ^ 5 6 + ^")
end
 
main()</syntaxhighlight>
{{out}}
<pre>3 + ((4 * 2) / ((1 - 5) ^ (2 ^ 3)))
((1 + 2) ^ (3 + 4)) ^ (5 + 6)</pre>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Rpn_2_Infix {
Rem Form 80,60
function rpn_to_infix$(a$) {
def m=0
inventory precendence="-":=2,"+":=2,"*":=3,"/":=3,"^":=4
dim token$()
token$()=piece$(a$," ")
l=len(token$())
dim type(l)=0, right(l)=0, infix$(l)
infix=-1
for i=0 to l-1
if exist(precendence, token$(i)) then
type(i)=precendence(token$(i))
if type(i)=4 then right(i)=-1
end if
if type(i)=0 then
infix++
infix$(infix)=token$(i)
type(infix)=100
else
if right(i) then
if type(infix)<type(i) then infix$(infix)="("+infix$(infix)+")"
if type(infix-1)<100 then infix$(infix-1)="("+infix$(infix-1)+")"
infix$(infix-1)=infix$(infix-1)+token$(i)+infix$(infix)
else
if type(infix)<type(i) then infix$(infix)="("+infix$(infix)+")"
if type(infix-1)<type(i) then
infix$(infix-1)="("+infix$(infix-1)+")"+token$(i)+infix$(infix)
else
infix$(infix-1)=infix$(infix-1)+token$(i)+infix$(infix)
end if
end if
type(infix-1)=type(i)
infix--
end if
inf=each(infix$(),1, infix+1)
while inf
export$<=token$(i)+" ["+str$(inf^,"")+"] "+ array$(inf)+{
}
token$(i)=" "
end while
next i
=infix$(0)
}
Global export$
document export$
example1=rpn_to_infix$("3 4 2 * 1 5 - 2 3 ^ ^ / +")="3+4*2/(1-5)^2^3"
example2=rpn_to_infix$("1 2 + 3 4 + ^ 5 6 + ^")="((1+2)^(3+4))^(5+6)"
\\ a test from Phix example
example3=rpn_to_infix$("moon stars mud + * fire soup * ^")="(moon*(stars+mud))^(fire*soup)"
Print example1, example2, example3
Rem Print #-2, Export$
ClipBoard Export$
 
}
Rpn_2_Infix
</syntaxhighlight>
 
{{out}}
<pre style="height:30ex;overflow:scroll">
3 [0] 3
4 [0] 3
[1] 4
2 [0] 3
[1] 4
[2] 2
* [0] 3
[1] 4*2
1 [0] 3
[1] 4*2
[2] 1
5 [0] 3
[1] 4*2
[2] 1
[3] 5
- [0] 3
[1] 4*2
[2] 1-5
2 [0] 3
[1] 4*2
[2] 1-5
[3] 2
3 [0] 3
[1] 4*2
[2] 1-5
[3] 2
[4] 3
^ [0] 3
[1] 4*2
[2] 1-5
[3] 2^3
^ [0] 3
[1] 4*2
[2] (1-5)^2^3
/ [0] 3
[1] 4*2/(1-5)^2^3
+ [0] 3+4*2/(1-5)^2^3
1 [0] 1
2 [0] 1
[1] 2
+ [0] 1+2
3 [0] 1+2
[1] 3
4 [0] 1+2
[1] 3
[2] 4
+ [0] 1+2
[1] 3+4
^ [0] (1+2)^(3+4)
5 [0] (1+2)^(3+4)
[1] 5
6 [0] (1+2)^(3+4)
[1] 5
[2] 6
+ [0] (1+2)^(3+4)
[1] 5+6
^ [0] ((1+2)^(3+4))^(5+6)
moon [0] moon
stars [0] moon
[1] stars
mud [0] moon
[1] stars
[2] mud
+ [0] moon
[1] stars+mud
* [0] moon*(stars+mud)
fire [0] moon*(stars+mud)
[1] fire
soup [0] moon*(stars+mud)
[1] fire
[2] soup
* [0] moon*(stars+mud)
[1] fire*soup
^ [0] (moon*(stars+mud))^(fire*soup)
</pre >
 
=={{header|Nim}}==
{{trans|Go}}
<langsyntaxhighlight lang="nim">import tables, strutils
 
const nPrec = 9
Line 2,144 ⟶ 2,981:
 
for test in ["3 4 2 * 1 5 - 2 3 ^ ^ / +", "1 2 + 3 4 + ^ 5 6 + ^"]:
test.parseRPN</langsyntaxhighlight>
Output:
<pre>postfix: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Line 2,233 ⟶ 3,070:
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
<lang perl>
use warnings;
# RPN to infix conversion
use feature 'say';
#
# Nigel Galloway April 1st., 2012
#
$WSb = '(?:^|\s+)';
$WSa = '(?:\s+|$)';
$num = '([+-/$]?(?:\.\d+|\d+(?:\.\d*)?))';
$op = '([-+*/^])';
while (<>) {
$n = -1;
while (s/$WSb$num\s+$num\s+$op$WSa/' '.('$'.++$n).' '/e) {@elems[$n] = '('.$1.$3.$2.')';}
while (s!(\$)(\d+)!@elems[$2]!e) {}
print(substr($_,2,-2)."\n");
}
</lang>
Produces:
<pre>
>rpn.pl
1 2 + 3 4 + ^ 5 6 + ^
((1+2)^(3+4))^(5+6)
3 4 2 * 1 5 - 2 3 ^ ^ / +
3+((4*2)/((1-5)^(2^3)))
</pre>
=={{header|Perl 6}}==
<lang perl6>my @tests = '3 4 2 * 1 5 - 2 3 ^ ^ / +',
'1 2 + 3 4 + ^ 5 6 + ^';
 
my $number = '[+-/$]?(?:\.\d+|\d+(?:\.\d*)?)';
say rpm-to-infix($_) for @tests;
my $operator = '[-+*/^]';
 
my @tests = ('1 2 + 3 4 + ^ 5 6 + ^', '3 4 2 * 1 5 - 2 3 ^ ^ / +');
sub p ($pair, $prec) {
 
$pair.key < $prec ?? "( $pair.value() )" !! $pair.value
for (@tests) {
}
my(@elems,$n);
sub rpm-to-infix($string) {
$n = -1;
say "=================\n$string";
mywhile @stack;(
for $string.words { s/
\s* (?<left>$number) # 1st operand (will be 'left' in infix)
when /\d/ { @stack.push: 9 => $_ }
\s+ (?<right>$number) # 2nd operand (will be 'right' in infix)
my $y = @stack.pop;
my \s+ (?<op>$xoperator) =# @stack.pop;operator
when '^' (?:\s+|$) { @stack.push: 4 => ~(p($x,5), $_ # more to parse, p($y,4))or }done?
/
when '*' | '/' { @stack.push: 3 => ~(p($x,3), $_, p($y,3)) }
when '+' | '-' { @stack'.push: 2 => ~(p('$x,2'.++$n),.' $_,' p($y,2)) } # placeholders
/ex) {
# LEAVE { say @stack } # phaser not yet implemented in this context
$elems[$n] = "($+{left}$+{op}$+{right})" # infix expression
}
}
say "-----------------";
@stack».value;while (
s/ (\$)(\d+) # for each placeholder
}</lang>
/ $elems[$2] # evaluate expression, substitute numeric value
/ex
) { say } # track progress
say '=>' . substr($_,2,-2)."\n";
}</syntaxhighlight>
{{out}}
<pre>================= ($2^$3)
(($0^$1)^$3)
3 4 2 * 1 5 - 2 3 ^ ^ / +
(((1+2)^$1)^$3)
-----------------
(((1+2)^(3+4))^$3)
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
(((1+2)^(3+4))^(5+6))
=================
=>((1 2 + 2)^(3 4 + 4))^ (5 6 + ^6)
 
-----------------
(3+$4)
( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )</pre>
(3+($0/$3))
(3+((4*2)/$3))
(3+((4*2)/($1^$2)))
(3+((4*2)/((1-5)^$2)))
(3+((4*2)/((1-5)^(2^3))))
=>3+((4*2)/((1-5)^(2^3)))</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>integer show_workings = 1
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #004080;">bool</span> <span style="color: #000000;">show_workings</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
constant operators = {"^","*","/","+","-"},
precedence = { 4, 3, 3, 2, 2 },
<span style="color: #008080;">constant</span> <span style="color: #000000;">operators</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"/"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"+"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-"</span><span style="color: #0000FF;">},</span>
rassoc = {'r', 0 ,'l', 0 ,'l'}
<span style="color: #000000;">precedence</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span> <span style="color: #0000FF;">},</span>
 
<span style="color: #000000;">rassoc</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">'r'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span> <span style="color: #0000FF;">,</span><span style="color: #008000;">'l'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span> <span style="color: #0000FF;">,</span><span style="color: #008000;">'l'</span><span style="color: #0000FF;">}</span>
procedure parseRPN(string expr, string expected)
sequence stack = {}
<span style="color: #008080;">procedure</span> <span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">expected</span><span style="color: #0000FF;">)</span>
sequence ops = split(expr)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
string lhs, rhs
<span style="color: #000000;">ops</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">)</span>
integer lprec,rprec
<span style="color: #004080;">string</span> <span style="color: #000000;">lhs</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rhs</span>
printf(1,"Postfix input: %-30s%s", {expr,iff(show_workings?'\n':'\t')})
<span style="color: #004080;">integer</span> <span style="color: #000000;">lprec</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rprec</span>
if length(ops)=0 then ?"error" return end if
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Postfix input: %-32s%s"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">show_workings</span><span style="color: #0000FF;">?</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">:</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">)})</span>
for i=1 to length(ops) do
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ops</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #008000;">"error"</span> <span style="color: #008080;">return</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
string op = ops[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ops</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer k = find(op,operators)
<span style="color: #004080;">string</span> <span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
if k=0 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">operators</span><span style="color: #0000FF;">)</span>
stack = append(stack,{9,op})
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
else
<span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span><span style="color: #000000;">op</span><span style="color: #0000FF;">})</span>
if length(stack)<2 then ?"error" return end if
<span style="color: #008080;">else</span>
{rprec,rhs} = stack[$]; stack = stack[1..$-1]
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #008000;">"error"</span> <span style="color: #008080;">return</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{lprec,lhs} = stack[$]
<span style="color: #0000FF;">{</span><span style="color: #000000;">rprec</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[$];</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
integer prec = precedence[k]
<span style="color: #0000FF;">{</span><span style="color: #000000;">lprec</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[$]</span>
integer assoc = rassoc[k]
<span style="color: #004080;">integer</span> <span style="color: #000000;">prec</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">precedence</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
if lprec<prec or (lprec=prec and assoc='r') then
<span style="color: #004080;">integer</span> <span style="color: #000000;">assoc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rassoc</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
lhs = "("&lhs&")"
<span style="color: #008080;">if</span> <span style="color: #000000;">lprec</span><span style="color: #0000FF;"><</span><span style="color: #000000;">prec</span> <span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">lprec</span><span style="color: #0000FF;">=</span><span style="color: #000000;">prec</span> <span style="color: #008080;">and</span> <span style="color: #000000;">assoc</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'r'</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">lhs</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"("</span><span style="color: #0000FF;">&</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">&</span><span style="color: #008000;">")"</span>
if rprec<prec or (rprec=prec and assoc='l') then
<span style="color: #008080;">end</span> rhs<span style= "("&rhs&")color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">rprec</span><span style="color: #0000FF;"><</span><span style="color: #000000;">prec</span> <span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">rprec</span><span style="color: #0000FF;">=</span><span style="color: #000000;">prec</span> <span style="color: #008080;">and</span> <span style="color: #000000;">assoc</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'l'</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">rhs</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"("</span><span style="color: #0000FF;">&</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">&</span><span style="color: #008000;">")"</span>
stack[$] = {prec,lhs&" "&op&" "&rhs}
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #000000;">stack</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">prec</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lhs</span><span style="color: #0000FF;">&</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">op</span><span style="color: #0000FF;">&</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">rhs</span><span style="color: #0000FF;">}</span>
if show_workings then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
?{op,stack}
<span style="color: #008080;">if</span> <span style="color: #000000;">show_workings</span> <span style="color: #008080;">then</span>
end if
<span style="color: #0000FF;">?{</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">}</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
string res = stack[1][2]
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"Infix result: %s [%s]\n", {res,iff(res=expected?"ok","**ERROR**")})
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
end procedure
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Infix result: %s [%s]\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">=</span><span style="color: #000000;">expected</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"ok"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"**ERROR**"</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
parseRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +","3 + 4 * 2 / (1 - 5) ^ 2 ^ 3")
show_workings = 0
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 4 2 * 1 5 - 2 3 ^ ^ / +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"3 + 4 * 2 / (1 - 5) ^ 2 ^ 3"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 + 3 4 + ^ 5 6 + ^","((1 + 2) ^ (3 + 4)) ^ (5 + 6)")
<span style="color: #000000;">show_workings</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
parseRPN("1 2 + 3 4 + 5 6 + ^ ^","(1 + 2) ^ (3 + 4) ^ (5 + 6)")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 + 3 4 + ^ 5 6 + ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"((1 + 2) ^ (3 + 4)) ^ (5 + 6)"</span><span style="color: #0000FF;">)</span>
parseRPN("moon stars mud + * fire soup * ^","(moon * (stars + mud)) ^ (fire * soup)")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 + 3 4 + 5 6 + ^ ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(1 + 2) ^ (3 + 4) ^ (5 + 6)"</span><span style="color: #0000FF;">)</span>
parseRPN("3 4 ^ 2 9 ^ ^ 2 5 ^ ^","((3 ^ 4) ^ 2 ^ 9) ^ 2 ^ 5")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"moon stars mud + * fire soup * ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(moon * (stars + mud)) ^ (fire * soup)"</span><span style="color: #0000FF;">)</span>
parseRPN("5 6 * * + +","error")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 4 ^ 2 9 ^ ^ 2 5 ^ ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"((3 ^ 4) ^ 2 ^ 9) ^ 2 ^ 5"</span><span style="color: #0000FF;">)</span>
parseRPN("","error")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"5 6 * * + +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"error"</span><span style="color: #0000FF;">)</span>
parseRPN("1 4 + 5 3 + 2 3 * * *","(1 + 4) * (5 + 3) * 2 * 3")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"error"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 * 3 4 * *","1 * 2 * 3 * 4")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 4 + 5 3 + 2 3 * * *"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(1 + 4) * (5 + 3) * 2 * 3"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 + 3 4 + +","1 + 2 + 3 + 4")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 * 3 4 * *"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1 * 2 * 3 * 4"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 + 3 4 + ^","(1 + 2) ^ (3 + 4)")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 + 3 4 + +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1 + 2 + 3 + 4"</span><span style="color: #0000FF;">)</span>
parseRPN("5 6 ^ 7 ^","(5 ^ 6) ^ 7")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 + 3 4 + ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(1 + 2) ^ (3 + 4)"</span><span style="color: #0000FF;">)</span>
parseRPN("5 4 3 2 ^ ^ ^","5 ^ 4 ^ 3 ^ 2")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"5 6 ^ 7 ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(5 ^ 6) ^ 7"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 3 + +","1 + 2 + 3")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"5 4 3 2 ^ ^ ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"5 ^ 4 ^ 3 ^ 2"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 + 3 +","1 + 2 + 3")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 3 + +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1 + 2 + 3"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 3 ^ ^","1 ^ 2 ^ 3")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 + 3 +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1 + 2 + 3"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 ^ 3 ^","(1 ^ 2) ^ 3")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 3 ^ ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1 ^ 2 ^ 3"</span><span style="color: #0000FF;">)</span>
parseRPN("1 1 - 3 +","1 - 1 + 3")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 ^ 3 ^"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(1 ^ 2) ^ 3"</span><span style="color: #0000FF;">)</span>
parseRPN("3 1 1 - +","3 + 1 - 1") -- [txr says 3 + (1 - 1)]
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 1 - 3 +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1 - 1 + 3"</span><span style="color: #0000FF;">)</span>
parseRPN("1 2 3 + -","1 - (2 + 3)")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 1 1 - +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"3 + 1 - 1"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- [txr says 3 + (1 - 1)]</span>
parseRPN("4 3 2 + +","4 + 3 + 2")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1 2 3 + -"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1 - (2 + 3)"</span><span style="color: #0000FF;">)</span>
parseRPN("5 4 3 2 + + +","5 + 4 + 3 + 2")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"4 3 2 + +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"4 + 3 + 2"</span><span style="color: #0000FF;">)</span>
parseRPN("5 4 3 2 * * *","5 * 4 * 3 * 2")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"5 4 3 2 + + +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"5 + 4 + 3 + 2"</span><span style="color: #0000FF;">)</span>
parseRPN("5 4 3 2 + - +","5 + 4 - (3 + 2)") -- [python says 5 + (4 - (3 + 2))]
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"5 4 3 2 * * *"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"5 * 4 * 3 * 2"</span><span style="color: #0000FF;">)</span>
parseRPN("3 4 5 * -","3 - 4 * 5")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"5 4 3 2 + - +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"5 + 4 - (3 + 2)"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- [python says 5 + (4 - (3 + 2))]</span>
parseRPN("3 4 5 - *","3 * (4 - 5)") -- [python says (3 - 4) * 5] [!!flagged!!]
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 4 5 * -"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"3 - 4 * 5"</span><span style="color: #0000FF;">)</span>
parseRPN("3 4 - 5 *","(3 - 4) * 5")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 4 5 - *"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"3 * (4 - 5)"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- [python says (3 - 4) * 5] [!!flagged!!]</span>
parseRPN("4 2 * 1 5 - +","4 * 2 + 1 - 5") -- [python says 4 * 2 + (1 - 5)]
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 4 - 5 *"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(3 - 4) * 5"</span><span style="color: #0000FF;">)</span>
parseRPN("4 2 * 1 5 - 2 ^ /","4 * 2 / (1 - 5) ^ 2")
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"4 2 * 1 5 - +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"4 * 2 + 1 - 5"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- [python says 4 * 2 + (1 - 5)]</span>
parseRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +","3 + 4 * 2 / (1 - 5) ^ 2 ^ 3")</lang>
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"4 2 * 1 5 - 2 ^ /"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"4 * 2 / (1 - 5) ^ 2"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">parseRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 4 2 * 1 5 - 2 3 ^ ^ / +"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"3 + 4 * 2 / (1 - 5) ^ 2 ^ 3"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,413 ⟶ 3,241:
=={{header|PicoLisp}}==
We maintain a stack of cons pairs, consisting of precedences and partial expressions. Numbers get a "highest" precedence of '9'.
<langsyntaxhighlight PicoLisplang="picolisp">(de leftAssoc (Op)
(member Op '("*" "/" "+" "-")) )
 
Line 2,445 ⟶ 3,273:
(println Stack) )
(prog1 (cdr (pop 'Stack))
(and Stack (quit "Garbage remained on stack")) ) ) )</langsyntaxhighlight>
Test (note that the top-of-stack is in the left-most position):
<langsyntaxhighlight PicoLisplang="picolisp">: (rpnToInfix "3 4 2 * 1 5 - 2 3 \^ \^ / +")
Token Stack
3 ((9 . 3))
Line 2,477 ⟶ 3,305:
+ ((2 . "5 + 6") (4 . "(1 + 2) \^ (3 + 4)"))
^ ((4 . "((1 + 2) \^ (3 + 4)) \^ (5 + 6)"))
-> "((1 + 2) \^ (3 + 4)) \^ (5 + 6)"</langsyntaxhighlight>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
/* Uses a push-down pop-up stack for the stack (instead of array) */
cvt: procedure options (main); /* 10 Sept. 2012 */
Line 2,535 ⟶ 3,363:
 
end cvt;
</syntaxhighlight>
</lang>
Outputs:
<pre>
Line 2,580 ⟶ 3,408:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">
"""
Line 2,699 ⟶ 3,527:
print ("Input: ",strTest)
print ("Output:",strResult)
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,711 ⟶ 3,539:
=={{header|Racket}}==
{{trans|AWK}}
<langsyntaxhighlight lang="racket">
#lang racket
(require racket/dict)
Line 2,744 ⟶ 3,572:
(if (eq? +inf.0 p) (printf "[~a] " s) (printf "[~a {~a}] " s p)))
(newline))
</syntaxhighlight>
</lang>
 
Output:
Line 2,786 ⟶ 3,614:
"(moon * (stars + mud)) ^ (fire * soup)"
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub p ($pair, $prec) { $pair.key < $prec ?? "( {$pair.value} )" !! $pair.value }
 
sub rpm-to-infix($string) {
my @stack;
for $string.words {
when /\d/ { @stack.push: 9 => $_ }
my ($y,$x) = @stack.pop, @stack.pop;
when '^' { @stack.push: 4 => ~(p($x,5), $_, p($y,4)) }
when '*' | '/' { @stack.push: 3 => ~(p($x,3), $_, p($y,3)) }
when '+' | '-' { @stack.push: 2 => ~(p($x,2), $_, p($y,2)) }
}
($string, @stack».value).join("\n") ~ "\n";
}
 
say rpm-to-infix $_ for
'3 4 2 * 1 5 - 2 3 ^ ^ / +',
'1 2 + 3 4 + ^ 5 6 + ^';</syntaxhighlight>
{{out}}
<pre>3 4 2 * 1 5 - 2 3 ^ ^ / +
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
 
1 2 + 3 4 + ^ 5 6 + ^
( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )</pre>
 
=={{header|REXX}}==
{{trans|AWK}}
{{trans|Tcl}}
 
 
A Yen symbol &nbsp; '''¥''' &nbsp; was used instead of a &nbsp; '''9''' &nbsp; to make it apparenet that it's just a placeholder.
 
<br>The same reasoning was used for the ''operator associations'' &nbsp; (the left &nbsp; ◄ &nbsp; and right &nbsp; ► &nbsp; arrow symbols).
The same reasoning was used for the ''operator associations'' &nbsp; (the left &nbsp; ◄ &nbsp; and right &nbsp; ► &nbsp; arrow symbols).
<lang rexx>/*REXX program converts Reverse Polish Notation (RPN) ──► infix notation*/
<syntaxhighlight lang="rexx">/*REXX program converts Reverse Polish Notation (RPN) ───► an infix notation. */
showAction = 1 /* 0 if no showActions wanted. */
showAction = 1 # = 0 /*initialize stack pointer0 to 0if no showActions wanted. */
oS # = '+0 - / * ^' /*operator symbols. /*initialize stack pointer to 0 (zero).*/
oPoS = '2+ 2- 3/ 3* 4^' /*the operator prioritiessymbols. */
oAoP = '2 2 3 3 4' /*the operator associationspriorities. */
oA = '◄ ◄ ◄ ◄ ►' /*the operator associations. */
say "infix: " toInfix( "3 4 2 * 1 5 - 2 3 ^ ^ / +" )
say "infix: " toInfix( "1 2 + 3 4 + ^ 5 6 + ^" ) /* [↓] Sprechen Sie Deutsch.? */
say "infix: " toInfix( "Mond Sterne Schlamm + * Feur Suppe * ^" )
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────*/
pop: pop= #; #= # - 1; return @.pop
push: #= # + 1; @.#= arg(1); return
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────*/
stack2str: $=; do j=1 for #; _ = @.j; y= left(_, 1)
if pos(' ', _)==0 then _ = '{'strip( substr(_, 2) )"}"
else _ = substr(_, 2)
$=$ '{'strip(y _)"}"
end /*j*/
return space($)
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────*/
toInfix: parse arg rpn; say copies('─', 80 - 1); say 'RPN: ' space(rpn)
 
do N=1 for words(RPN); ?=word(RPN,N) /*process each of the RPN tokens.*/
if pos( ?= word(RPN,oS N)==0 then call push '¥' ? /*whenobtain innext doubt,item addin athe Yenlist. to it.*/
if pos(?,oS)==0 then elsecall do;push '¥' ? g=pop(); /*when in gp=left(gdoubt, 1);add a Yen to g=substr(g, 2)it.*/
h else do; g= pop(); hpgp= left(hg, 1); hg= substr(hg, 2)
tp h=substr pop(oP,pos); hp= left(?h, oS1),; 1 h= substr(h, 2)
ta tp= substr(oAoP, pos(?, oS), 1)
if hp<tp | (hp==tp & ta=='►') then h ta=" substr("h"oA, pos(?, oS), 1)"
if gphp<tp | (gphp==tp & ta=='') then gh= "("gh")"
call push if gp<tp || h(gp==tp & ?ta=='◄') then g= "("g")"
end call push tp || h ? g
if showAction then say right(?,25) "──►" stack2str() end
if showAction then say right(?, 25) "──►" stack2str()
end /*N*/
end /*N*/
 
return space( substr( pop(), 2) )</langsyntaxhighlight>
'''{{out|output'''|text=&nbsp; when using the default inputinputs: &nbsp; &nbsp; &nbsp; [Output is very similar to AWK's output.]}}
<pre>
<br>[Output is very similar to AWK's output.]
<pre style="height:55ex">
───────────────────────────────────────────────────────────────────────────────
RPN: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Line 2,872 ⟶ 3,729:
Suppe ──► {3 Mond * ( Sterne + Schlamm)} {¥ Feur} {¥ Suppe}
* ──► {3 Mond * ( Sterne + Schlamm)} {3 Feur * Suppe}
^ ──► {4 ( Mond * ( Sterne + Schlamm)) ^ ( Feur * Suppe)}
}
infix: ( Mond * ( Sterne + Schlamm)) ^ ( Feur * Suppe)
</pre>
 
=={{header|RPL}}==
It adds more parentheses than required, thus avoiding any ambiguity.
« '''IF''' DUP " " POS '''THEN''' " )" + "( " SWAP + '''END'''
» '<span style="color:blue">ADDPAR</span>' STO
« "}" + "{" SWAP + STR→ <span style="color:grey">@ tokenize</span>
→ postfix
« 1 postfix SIZE '''FOR''' j
postfix j GET →STR
'''IF''' "+-*/^" OVER POS '''THEN'''
ROT <span style="color:blue">ADDPAR</span> " " + SWAP + " " +
SWAP <span style="color:blue">ADDPAR</span> +
'''END'''
'''NEXT'''
» » '<span style="color:blue">→INFIX</span>' STO
 
"3 4 2 * 1 5 - 2 3 ^ ^ / +" <span style="color:blue">→INFIX</span>
"1 2 + 3 4 + ^ 5 6 + ^" <span style="color:blue">→INFIX</span>
{{out}}
<pre>
2: "3 + ( ( 4 * 2 ) / ( ( 1 - 5 ) ^ ( 2 ^ 3 ) ) )"
1: "( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )"
</pre>
 
Line 2,881 ⟶ 3,761:
See [[Parsing/RPN/Ruby]]
 
<langsyntaxhighlight lang="ruby">rpn = RPNExpression.new("3 4 2 * 1 5 - 2 3 ^ ^ / +")
infix = rpn.to_infix
ruby = rpn.to_ruby</langsyntaxhighlight>
outputs
<pre>for RPN expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Line 2,904 ⟶ 3,784:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">func p(pair, prec) {
pair[0] < prec ? "( #{pair[1]} )" : pair[1]
}
Line 2,936 ⟶ 3,816:
]
 
tests.each { say rpm_to_infix(_).join(' ') }</langsyntaxhighlight>
{{out}}
<pre>
Line 2,961 ⟶ 3,841:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Helpers
Line 2,999 ⟶ 3,879:
 
puts [rpn2infix {3 4 2 * 1 5 - 2 3 ^ ^ / +}]
puts [rpn2infix {1 2 + 3 4 + ^ 5 6 + ^}]</langsyntaxhighlight>
Output:
<pre>
Line 3,038 ⟶ 3,918:
The <code>lisp-to-infix</code> filter then takes advantage of this non-associativity in minimizing the parentheses.
 
<langsyntaxhighlight lang="txrlisp">;; alias for circumflex, which is reserved syntax
(defvar exp (intern "^"))
 
Line 3,100 ⟶ 3,980:
((a b . c) "*excess args*")
((a) (lisp-to-infix (rpn-to-lisp (string-to-rpn a))))
(else "*arg needed*"))))</langsyntaxhighlight>
 
{{out}}
Line 3,189 ⟶ 4,069:
[ .. ]
infix: 3 + (1 - 1)</pre>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Option Strict On
 
Imports System.Text.RegularExpressions
 
Module Module1
 
Class Operator_
Sub New(t As Char, p As Integer, Optional i As Boolean = False)
Token = t
Precedence = p
IsRightAssociative = i
End Sub
 
Property Token As Char
Get
Return m_token
End Get
Private Set(value As Char)
m_token = value
End Set
End Property
 
Property Precedence As Integer
Get
Return m_precedence
End Get
Private Set(value As Integer)
m_precedence = value
End Set
End Property
 
Property IsRightAssociative As Boolean
Get
Return m_right
End Get
Private Set(value As Boolean)
m_right = value
End Set
End Property
 
Private m_token As Char
Private m_precedence As Integer
Private m_right As Boolean
End Class
 
ReadOnly operators As New Dictionary(Of Char, Operator_) From {
{"+"c, New Operator_("+"c, 2)},
{"-"c, New Operator_("-"c, 2)},
{"/"c, New Operator_("/"c, 3)},
{"*"c, New Operator_("*"c, 3)},
{"^"c, New Operator_("^"c, 4, True)}
}
 
Class Expression
Public Sub New(e As String)
Ex = e
End Sub
 
Sub New(e1 As String, e2 As String, o As Operator_)
Ex = String.Format("{0} {1} {2}", e1, o.Token, e2)
Op = o
End Sub
 
ReadOnly Property Ex As String
ReadOnly Property Op As Operator_
End Class
 
Function PostfixToInfix(postfix As String) As String
Dim stack As New Stack(Of Expression)
 
For Each token As String In Regex.Split(postfix, "\s+")
Dim c = token(0)
Dim op = operators.FirstOrDefault(Function(kv) kv.Key = c).Value
If Not IsNothing(op) AndAlso token.Length = 1 Then
Dim rhs = stack.Pop()
Dim lhs = stack.Pop()
 
Dim opPrec = op.Precedence
 
Dim lhsPrec = If(IsNothing(lhs.Op), Integer.MaxValue, lhs.Op.Precedence)
Dim rhsPrec = If(IsNothing(rhs.Op), Integer.MaxValue, rhs.Op.Precedence)
 
Dim newLhs As String
If lhsPrec < opPrec OrElse (lhsPrec = opPrec AndAlso c = "^") Then
'lhs.Ex = "(" + lhs.Ex + ")"
newLhs = "(" + lhs.Ex + ")"
Else
newLhs = lhs.Ex
End If
 
Dim newRhs As String
If rhsPrec < opPrec OrElse (rhsPrec = opPrec AndAlso c <> "^") Then
'rhs.Ex = "(" + rhs.Ex + ")"
newRhs = "(" + rhs.Ex + ")"
Else
newRhs = rhs.Ex
End If
 
stack.Push(New Expression(newLhs, newRhs, op))
Else
stack.Push(New Expression(token))
End If
 
'Print intermediate result
Console.WriteLine("{0} -> [{1}]", token, String.Join(", ", stack.Reverse().Select(Function(e) e.Ex)))
Next
 
Return stack.Peek().Ex
End Function
 
Sub Main()
Dim inputs = {"3 4 2 * 1 5 - 2 3 ^ ^ / +", "1 2 + 3 4 + ^ 5 6 + ^"}
For Each e In inputs
Console.WriteLine("Postfix : {0}", e)
Console.WriteLine("Infix : {0}", PostfixToInfix(e))
Console.WriteLine()
Next
Console.ReadLine() 'remove before submit
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>Postfix : 3 4 2 * 1 5 - 2 3 ^ ^ / +
3 -> [3]
4 -> [3, 4]
2 -> [3, 4, 2]
* -> [3, 4 * 2]
1 -> [3, 4 * 2, 1]
5 -> [3, 4 * 2, 1, 5]
- -> [3, 4 * 2, 1 - 5]
2 -> [3, 4 * 2, 1 - 5, 2]
3 -> [3, 4 * 2, 1 - 5, 2, 3]
^ -> [3, 4 * 2, 1 - 5, 2 ^ 3]
^ -> [3, 4 * 2, (1 - 5) ^ 2 ^ 3]
/ -> [3, 4 * 2 / (1 - 5) ^ 2 ^ 3]
+ -> [3 + 4 * 2 / (1 - 5) ^ 2 ^ 3]
Infix : 3 + 4 * 2 / (1 - 5) ^ 2 ^ 3
 
Postfix : 1 2 + 3 4 + ^ 5 6 + ^
1 -> [1]
2 -> [1, 2]
+ -> [1 + 2]
3 -> [1 + 2, 3]
4 -> [1 + 2, 3, 4]
+ -> [1 + 2, 3 + 4]
^ -> [(1 + 2) ^ (3 + 4)]
5 -> [(1 + 2) ^ (3 + 4), 5]
6 -> [(1 + 2) ^ (3 + 4), 5, 6]
+ -> [(1 + 2) ^ (3 + 4), 5 + 6]
^ -> [((1 + 2) ^ (3 + 4)) ^ (5 + 6)]
Infix : ((1 + 2) ^ (3 + 4)) ^ (5 + 6)</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-seq}}
{{libheader|Wren-pattern}}
<syntaxhighlight lang="wren">import "./seq" for Stack
import "./pattern" for Pattern
 
class Expression {
static ops { "-+/*^" }
 
construct new(ex, op, prec) {
_ex = ex
_op = op
_prec = prec
}
 
static build(e1, e2, o) { new("%(e1) %(o) %(e2)", o, (ops.indexOf(o)/2).floor) }
 
ex { _ex }
ex=(other) { _ex = other }
prec { _prec }
 
toString { _ex }
}
 
var postfixToInfix = Fn.new { |postfix|
var expr = Stack.new()
var p = Pattern.new("+1/s")
for (token in p.splitAll(postfix)) {
var c = token[0]
var idx = Expression.ops.indexOf(c)
if (idx != -1 && token.count == 1) {
var r = expr.pop()
var l = expr.pop()
var opPrec = (idx/2).floor
if (l.prec < opPrec || (l.prec == opPrec && c == "^")) {
l.ex = "(%(l.ex))"
}
if (r.prec < opPrec || (r.prec == opPrec && c != "^")) {
r.ex = "(%(r.ex))"
}
expr.push(Expression.build(l.ex, r.ex, token))
} else {
expr.push(Expression.new(token, "", 3))
}
System.print("%(token) -> %(expr)")
}
return expr.peek().ex
}
 
var es = [
"3 4 2 * 1 5 - 2 3 ^ ^ / +",
"1 2 + 3 4 + ^ 5 6 + ^"
]
for (e in es) {
System.print("Postfix : %(e)")
System.print("Infix : %(postfixToInfix.call(e))\n")
}</syntaxhighlight>
 
{{out}}
<pre>
Postfix : 3 4 2 * 1 5 - 2 3 ^ ^ / +
3 -> [3]
4 -> [3, 4]
2 -> [3, 4, 2]
* -> [3, 4 * 2]
1 -> [3, 4 * 2, 1]
5 -> [3, 4 * 2, 1, 5]
- -> [3, 4 * 2, 1 - 5]
2 -> [3, 4 * 2, 1 - 5, 2]
3 -> [3, 4 * 2, 1 - 5, 2, 3]
^ -> [3, 4 * 2, 1 - 5, 2 ^ 3]
^ -> [3, 4 * 2, (1 - 5) ^ 2 ^ 3]
/ -> [3, 4 * 2 / (1 - 5) ^ 2 ^ 3]
+ -> [3 + 4 * 2 / (1 - 5) ^ 2 ^ 3]
Infix : 3 + 4 * 2 / (1 - 5) ^ 2 ^ 3
 
Postfix : 1 2 + 3 4 + ^ 5 6 + ^
1 -> [1]
2 -> [1, 2]
+ -> [1 + 2]
3 -> [1 + 2, 3]
4 -> [1 + 2, 3, 4]
+ -> [1 + 2, 3 + 4]
^ -> [(1 + 2) ^ (3 + 4)]
5 -> [(1 + 2) ^ (3 + 4), 5]
6 -> [(1 + 2) ^ (3 + 4), 5, 6]
+ -> [(1 + 2) ^ (3 + 4), 5 + 6]
^ -> [((1 + 2) ^ (3 + 4)) ^ (5 + 6)]
Infix : ((1 + 2) ^ (3 + 4)) ^ (5 + 6)
</pre>
 
=={{header|zkl}}==
{{trans|Go}}
<langsyntaxhighlight lang="zkl">tests:=T("3 4 2 * 1 5 - 2 3 ^ ^ / +","1 2 + 3 4 + ^ 5 6 + ^");
var opa=D(
Line 3,228 ⟶ 4,354:
}
println("infix:", stack[0][1])
}</langsyntaxhighlight>
{{out}}
<pre>
1,149

edits