Convert a list of tokens from read order into RPN
Uses the shunting-yard algorithm
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(token_t), | intent(in), | dimension(:) | :: | tks | Input tokens in read order |
Output list in RPN
function toRPN(tks) result(o)
!! Convert a list of tokens from read order into RPN
!!
!! Uses the shunting-yard algorithm
type(token_t),dimension(:),intent(in)::tks
!! Input tokens in read order
type(token_t),dimension(:),allocatable::o
!! Output list in RPN
type(token_t),dimension(:),allocatable::s
integer::ok,sk,k
allocate(o(size(tks)))
allocate(s(size(tks)))
ok = 0
sk = 0
do k=1,size(tks)
select case(tks(k)%t)
case(T_REAL,T_IMAG,T_VAR)
ok = ok+1
o(ok) = tks(k)
case(T_FUNCTION:T_FUNCTION+R_SPAN)
sk = sk+1
s(sk) = tks(k)
case(T_LPR)
sk = sk+1
s(sk) = tks(k)
case(T_RPR)
do while(s(sk)%t/=T_LPR)
ok = ok+1
o(ok) = s(sk)
sk = sk-1
end do
sk = sk-1
if(sk/=0) then
if(s(sk)%t>=T_FUNCTION .and. s(sk)%t<T_FUNCTION+R_SPAN) then
ok = ok+1
o(ok) = s(sk)
sk = sk-1
end if
end if
case(T_OPERATOR:T_OPERATOR+R_SPAN)
if(sk/=0) then
do while( (s(sk)%t>T_OPERATOR .and. s(sk)%t<T_OPERATOR+R_SPAN) .and. &
& ( (s(sk)%t==T_POW .and. tks(k)%t==T_POW) .or. &
& (tks(k)%t<s(sk)%t) ) )
ok = ok+1
o(ok) = s(sk)
sk = sk-1
if(sk==0) exit
end do
end if
sk = sk+1
s(sk) = tks(k)
end select
end do
do while(sk>0)
ok = ok+1
o(ok) = s(sk)
sk = sk-1
end do
o = pack(o,o%t/=T_NONE)
end function toRPN