subroutine Tokenize(parser,tokenized,errorMsg)
class(EquationParser),intent(inout) :: parser
logical,intent(out) :: tokenized
character(:),allocatable,intent(out) :: errorMsg
! Local
integer :: i,j,k,id
integer,allocatable :: maxVarLen,varLen
tokenized = .false.
call parser%infix%Construct(Stack_Length)
maxVarLen = 0
do k = 1,parser%nIndepVars
maxVarLen = max(maxVarLen,len(parser%indepVars(k)%value))
enddo
i = 1
do while(parser%inFixFormula(i:i) /= ' ')
varLen = maxVarLen
if(IsFunction(j,parser%infixFormula(i:i+maxFunctionLength),id)) then
parser%inFix%top_index = parser%inFix%top_index+1
parser%inFix%tokens(parser%inFix%top_index)%tokenString = parser%inFixFormula(i:i+j-1)
parser%inFix%tokens(parser%inFix%top_index)%tokenType = Function_Token
parser%inFix%tokens(parser%inFix%top_index)%tokenIndex = id
i = i+j
elseif(IsVariable(varLen,parser%inFixFormula(i:i+varLen-1),parser%indepVars,parser%nIndepVars)) then
parser%inFix%top_index = parser%inFix%top_index+1
parser%inFix%tokens(parser%inFix%top_index)%tokenString = parser%inFixFormula(i:i+varLen-1)
parser%inFix%tokens(parser%inFix%top_index)%tokenType = Variable_Token
i = i+varLen
! Next item must be an operator, closing parentheses, or end of equation
if(.not. IsOperator(parser%infixFormula(i:i)) .and. &
parser%inFixFormula(i:i) /= ')' .and. parser%inFixFormula(i:i) /= ' ') then
errorMsg = 'Missing operator or closing parentheses after token : '// &
trim(parser%inFix%tokens(parser%inFix%top_index)%tokenString)
return
endif
elseif(IsNumber(parser%inFixFormula(i:i))) then
parser%inFix%top_index = parser%inFix%top_index+1
parser%inFix%tokens(parser%inFix%top_index)%tokenString = ''
if(parser%inFixFormula(i:i) == 'p' .or. parser%inFixFormula(i:i) == 'P') then
! Conditional for using built in 'pi' definition
parser%inFix%tokens(parser%inFix%top_index)%tokenString(1:2) = parser%inFixFormula(i:i+1)
j = 2
else
j = 0
do while(IsNumber(parser%inFixFormula(i+j:i+j)))
parser%inFix%tokens(parser%inFix%top_index)%tokenString(j+1:j+1) = parser%inFixFormula(i+j:i+j)
j = j+1
enddo
endif
parser%inFix%tokens(parser%inFix%top_index)%tokenType = Number_Token
i = i+j
! Next item must be an operator or a closing parentheses
if(.not. IsOperator(parser%infixFormula(i:i)) .and. &
parser%inFixFormula(i:i) /= ')' .and. parser%inFixFormula(i:i) /= ' ') then
errorMsg = 'Missing operator or closing parentheses after token : '// &
trim(parser%inFix%tokens(parser%inFix%top_index)%tokenString)
return
endif
elseif(IsSeparator(parser%inFixFormula(i:i))) then
parser%inFix%top_index = parser%inFix%top_index+1
parser%inFix%tokens(parser%inFix%top_index)%tokenString = parser%inFixFormula(i:i)
if(parser%inFixFormula(i:i) == '(') then
parser%inFix%tokens(parser%inFix%top_index)%tokenType = OpeningParentheses_Token
elseif(parser%inFixFormula(i:i) == ')') then
parser%inFix%tokens(parser%inFix%top_index)%tokenType = ClosingParentheses_Token
else
parser%inFix%tokens(parser%inFix%top_index)%tokenType = Operator_Token
endif
i = i+1
else
errorMsg = 'Invalid Token : '// &
trim(parser%inFixFormula(i:i))
return
endif
enddo
if(parser%inFix%tokens(1)%tokenType == Operator_Token) then
if(trim(parser%inFix%tokens(1)%tokenString) == '+' .or. &
trim(parser%inFix%tokens(1)%tokenString) == '-') then
parser%inFix%tokens(1)%tokenType = Monadic_Token
endif
endif
do i = 2,parser%inFix%top_index
if(parser%inFix%tokens(i)%tokenType == Operator_Token .and. &
parser%inFix%tokens(i-1)%tokenType == OpeningParentheses_Token) then
parser%inFix%tokens(i)%tokenType = Monadic_Token
endif
enddo
tokenized = .true.
endsubroutine Tokenize