Qbasicnews.com

Full Version: Formula parser
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Under pressure from bluekeyboard, I coded a small formula parser which breaks down and solves a formula (ex (10 ^(2*2))/20+( 90*4)*10+ (1+9)*88 +244 /866- 46^ 2-1 )

Code:
function ParseEq(byval eq as string) as double
    dim as integer curLow=4,curInd,numOfOps=0,numOfPar=1
    
    'filter spaces
    for c = 0 to len(eq)-1
        if eq[c]=32 then eq=left$(eq,c)+right$(eq,len(eq)-c-1)        
    next c
    
    'get rid of parantheses if they include the whole equation 'ex (234+434*(23+1)) ->  234+434*(23+1)
    if eq[0]=40 and eq[len(eq)-1]=41 then
        for c = 1 to len(eq)-1            
            if eq[c]=41 or eq[c]=40 then numOfPar+=(40-eq[c])*2+1            
            if numOfPar=0 and c<>len(eq)-1 then exit for
            if numOfPar=0 and c=len(eq)-1 then eq=mid$(eq,2,len(eq)-2)
        next
    end if
    
    'find the lowest operator
    for c = 0 to len(eq)-1
        
        'skip stuff inside parantheses in the operation count
        if eq[c]=40 then '(
            numOfPar=1
            for tempc = c+1 to len(eq)-1
                if eq[tempc]=41 or eq[tempc]=40 then numOfPar+=(40-eq[tempc])*2+1            
                c=tempc+1
                if numOfPar=0 then exit for                
            next
            if c=len(eq) then exit for 'equation end has been reached            
        end if
        
        if eq[c]=43 or eq[c]=45 or eq[c]=42 or eq[c]=47 or eq[c]=94 then numOfOps+=1
        if eq[c]=43 or eq[c]=45 then '+,-
            curLow=44-eq[c]
            curInd=c        
        elseif eq[c]=42 or eq[c]=47 then '*,/
            if abs(curLow) > 1 then
                curLow=-((eq[c]-42)/5*4-2)
                curInd=c
            end if        
        elseif eq[c]=94 then '^
            if abs(curLow) > 2 then
                curLow=3
                curInd=c
            end if          
        end if
    next
    if numOfOps=0 then return val(eq)'single number, no equation to evaluate!
    if abs(curLow)= 1 then return ParseEq(left$(eq,curInd)) + ParseEq(right$(eq,len(eq)-curInd-1))*curLow 'split formula into two formulas, the split being at the lowest operation
    if curLow= 2 then return ParseEq(left$(eq,curInd)) * ParseEq(right$(eq,len(eq)-curInd-1))
    if curLow=-2 then return ParseEq(left$(eq,curInd)) / ParseEq(right$(eq,len(eq)-curInd-1))
    if curLow= 3 then return ParseEq(left$(eq,curInd)) ^ ParseEq(right$(eq,len(eq)-curInd-1))    
end function

dim as string eq
eq="(10  ^(2*2))/20+(  90*4)*10+ (1+9)*88  +244  /866-  46^  2-1"
print (10 ^(2*2))/20+( 90*4)*10+ (1+9)*88 +244 /866- 46^ 2-1
print ParseEq(eq)
sleep
Damn...I've already told you this, but Im impressed...nice work...l33t coder 8)
Yeah, that really is impressive...:-)>.good work deleter. :-)..great work that is.
:o

Nice work!






<*COUGH*> Even though it's looking more like C than QB... </*COUGH*>
Quote::o Even though it's looking more like C than QB...
how so? Tongue

Anonymous

really nice dude...
No reason.

I once coded something similar in LISP, but it only dealt with "- + * /". It also kept fractions. (It would turn into a big fraction with 1 numerator and 1 denominator.)

It was hard work..

I'd post it, but it's not on this computer. Come to think of it, I probably deleted it..

*Well, there's the +=, the pointer, the brackets, C-type abbreviations, etc....
"Small" formula?

>anarky
Quote:"Small" formula?

>anarky
The parser is small, the formula doesn't have to be. Smile

Anonymous

hey btw, the parts where you check for symbols, like parenthesis, you should use like ASC( "(" ), it will be evaluated at compile time (so the asm will be the same), but it will be much clearer to read =)
Pages: 1 2