RosettaCodeData/Task/Parsing-Shunting-yard-algorithm/Phix/parsing-shunting-yard-algorithm.phix
2017-09-25 22:28:19 +02:00

81 lines
2.9 KiB
Text

integer show_workings = 1
constant operators = {"^","*","/","+","-"},
precedence = { 4, 3, 3, 2, 2 }
procedure shunting_yard(string infix, string rpn)
string res = "", sep = "", top
sequence stack = {}
sequence ops = split(substitute_all(infix,{"(",")"},{" ( "," ) "}),' ',no_empty:=1,limit:=0)
printf(1,"Infix input: %-30s%s", {infix,iff(show_workings?'\n':'\t')})
for i=1 to length(ops) do
string op = ops[i]
if op="(" then
stack = append(stack,op)
elsif op=")" then
while 1 do
top = stack[$]
stack = stack[1..$-1]
if top="(" then exit end if
res &= sep&top
sep = " "
end while
else
integer k = find(op,operators)
if k!=0 then
integer prec = precedence[k]
while length(stack) do
top = stack[$]
k = find(top,operators)
if k=0 or prec>precedence[k]
or (top="^" and prec=precedence[k]) then
exit
end if
stack = stack[1..$-1]
res &= sep&top
sep = " "
end while
stack = append(stack,op)
else
res &= sep&op
sep = " "
end if
end if
if show_workings then
?{op,stack,res}
end if
end for
for i=length(stack) to 1 by -1 do
string op = stack[i]
res &= sep&op
sep = " "
end for
printf(1,"result: %-22s [%s]\n", {res,iff(res=rpn?"ok","**ERROR**")})
end procedure
shunting_yard("3 + 4 * 2 / (1 - 5) ^ 2 ^ 3","3 4 2 * 1 5 - 2 3 ^ ^ / +")
show_workings = 0
shunting_yard("((1 + 2) ^ (3 + 4)) ^ (5 + 6)","1 2 + 3 4 + ^ 5 6 + ^")
shunting_yard("(1 + 2) ^ (3 + 4) ^ (5 + 6)","1 2 + 3 4 + 5 6 + ^ ^")
shunting_yard("((3 ^ 4) ^ 2 ^ 9) ^ 2 ^ 5","3 4 ^ 2 9 ^ ^ 2 5 ^ ^")
shunting_yard("(1 + 4) * (5 + 3) * 2 * 3","1 4 + 5 3 + * 2 * 3 *")
shunting_yard("1 * 2 * 3 * 4","1 2 * 3 * 4 *")
shunting_yard("1 + 2 + 3 + 4","1 2 + 3 + 4 +")
shunting_yard("(1 + 2) ^ (3 + 4)","1 2 + 3 4 + ^")
shunting_yard("(5 ^ 6) ^ 7","5 6 ^ 7 ^")
shunting_yard("5 ^ 4 ^ 3 ^ 2","5 4 3 2 ^ ^ ^")
shunting_yard("1 + 2 + 3","1 2 + 3 +")
shunting_yard("1 ^ 2 ^ 3","1 2 3 ^ ^")
shunting_yard("(1 ^ 2) ^ 3","1 2 ^ 3 ^")
shunting_yard("1 - 1 + 3","1 1 - 3 +")
shunting_yard("3 + 1 - 1","3 1 + 1 -")
shunting_yard("1 - (2 + 3)","1 2 3 + -")
shunting_yard("4 + 3 + 2","4 3 + 2 +")
shunting_yard("5 + 4 + 3 + 2","5 4 + 3 + 2 +")
shunting_yard("5 * 4 * 3 * 2","5 4 * 3 * 2 *")
shunting_yard("5 + 4 - (3 + 2)","5 4 + 3 2 + -")
shunting_yard("3 - 4 * 5","3 4 5 * -")
shunting_yard("3 * (4 - 5)","3 4 5 - *")
shunting_yard("(3 - 4) * 5","3 4 - 5 *")
shunting_yard("4 * 2 + 1 - 5","4 2 * 1 + 5 -")
shunting_yard("4 * 2 / (1 - 5) ^ 2","4 2 * 1 5 - 2 ^ /")