How do you read an expression?

new topic     » goto parent     » topic index » view thread      » older message » newer message

*** Reply to note of 12/23/96 21:18
*** WARNING: a lot of code to follow ***

this will read an expression. there are a number of things that it will
*not* do, such as double unary signs (--3) and operator precedence. on the
other hand, it *will* handle the expressions you've got, as long as you
use parenthesis.

this code is *not* extensively tested. it does a parse-on-the-fly, rather
than a robust tokenize/parse/execute. on the other hand, it is fairly
small, and almost readable.

if this is too large of a post, let me know, and i will avoid such in the
future. *please* no flames, etc. there are no guarantees to the fitness
of the code; etc. etc. etc. i put it together fairly rapidly.

--- CODE STARTS HERE ---
global atom x    -- your "x" variable
global integer p    -- current character being parsed in string


function math( atom a, integer op, atom b )
 -- perform operation OP with A and B

 if op = '+' then
  return a + b
 elsif op = '-' then
  return a - b
 elsif op = '*' then
  return a * b
 elsif op = '/' then
  if b = 0 then
   -- your error handler here. division by zero.
   return 0
  else
   return a / b
  end if
 elsif op = '^' then
  return power( a, b )
 elsif op = '=' then
  return b
 elsif op = 0 then
   return a
 else
  -- your error handler here.
  -- op was not recognized
  return 1
 end if
end function


function isNumber( integer i )

 -- return true if character is part of a number

 if i = '.' then
  return -1 -- decimal place
 else
  return i >= '0' and i <= '9' -- true if ranges from '0' to '9'
 end if

end function


function isOp( integer i )

 -- return true if character is an operand

 return i = '+' or i = '-' or i = '*' or i = '/' or i = '^'

end function


function parse1( sequence s )
 integer op, decimal, sign
 atom accum, num

 op = '='    -- first operation is assignment to accumulator
 accum = 0   -- initialize accumulator
 sign = 1    -- unary minus
 while p <= length(s) do -- scan

  if s[p] = '(' then  -- left paren
    p = p + 1  -- move past the paren
    num = parse1( s )  -- recurse
    accum = math( accum, op, num )  -- accumulate
  elsif s[p] = ')' then
   return accum  -- return parsed expression
  elsif s[p] = '-' then
   -- handle unary minus
   if p = 1 then -- first character in string
    sign = -1 -- unary minus
   elsif isOp( s[p-1] ) then -- prior character was op
    sign = -1 -- unary minus
   else
    op = s[p] -- operand
   end if
  elsif isOp( s[p] ) then
   op = s[p] -- assign operand to pending operation
  elsif s[p] = 'x' then
   accum = math( accum, op, x * sign ) -- variable
   sign = 1 -- clear the sign
  elsif isNumber( s[p] ) then  -- number
   num = 0  -- clear accumulator
   decimal = 0 -- no decimal place
   while isNumber( s[p] ) do  -- while it's a number
    if s[p] = '.' then
     decimal = 1
    else
     num = ( num * 10 ) + ( s[p] - '0' ) -- accumulate
     decimal = decimal * 10 -- decimal place
    end if
    p = p + 1 -- increment pointer
   end while

   if decimal > 0 then  -- was there a decimal place?
    num = num / decimal -- divide by the decimal amount
   end if

   p = p - 1 -- back up one character (we went too far)

   num = num * sign -- add sign
   sign = 1 -- clear sign

   if s[p+1] = 'x' then -- handle stuff like 3x
    p = p + 1 -- move past x
    accum = math( accum, op, num * x ) -- include in operation
   else
    accum = math( accum, op, num ) -- perform pending operation
   end if
  else
   -- your error handler here.
   -- there is an error in the expression
  end if

  p = p + 1 -- increment to the next character

 end while

 return accum

end function


function parse( sequence s )

 -- main parsing function call
 p = 1 -- set pointer to first character
 return parse1( s ) -- parse expression

end function

-- test it
 sequence expression
 atom result

 x = 22 -- put value in x
 expression = ""  -- initialize
 while compare( expression, "\n" ) do -- until a blank line is entered
  puts( 1, "\n Give me an expression >" ) -- prompt
  expression = gets(0) -- get expression
  result = parse( expression )-- parse it
  printf( 1, "\nThe result is: %g", result ) -- print results
 end while

--- CODE ENDS HERE

merry christmas, all.

-- David Cuny

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu