81 lines
2.9 KiB
Text
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 ^ /")
|