1. How do you read an expression?

Hi all, I am a little new at Euphoria and would like to know how I might convert
a user input of say: x^2+3*4 to a expression that would get 'x' from a for loop
.  This is for a graphing program that I wrote in BASIC and want to convert.
The expression could be just 'x' or even '2x^4+3x^2-9x+7'
Andrew Baron
        E-Mail:abaron at cwave.com

new topic     » topic index » view message » categorize

2. How do you read an expression?

Andrew Baron asks:
> Hi all, I am a little new at Euphoria and would like to know how I
> might convert a user input of say: x^2+3*4 to a expression that
> would get 'x' from a for loop.
> This is for a graphing program that I wrote in BASIC and want to convert.
> The expression could be just 'x' or even '2x^4+3x^2-9x+7'

There's no simple way in Euphoria to read in a string containing an
mathematical expression with variables, and evaluate it.

There is however a tricky way to do this.

You could have a program something like:

1. ask user for input
2. read in his input string
3. write out a file, expr.e, that you create with open(), puts() etc.
   as:
       global function user(atom x)
          return  2*power(x,4) + 3*power(x,2) - 9*x + 7  -- plug in user's strin
g
       end function

-- expr.e will have been created by the time Euphoria tries
-- to include it:
include expr.e

procedure plot(atom x, atom y)
-- your graphing routine
end procedure

for x=0.0 to 100.0 by 1.0 do
    -- call user() function in the expr.e file that you just created
    plot(x, user(x))
end for

The program would probably just do one plot each time. It would
be hard to loop around and get another expression from the user since an
include statment can't be inside a loop.
The general idea is that you can create a .e file
just before Euphoria tries to include it. This trick might
be used for other purposes as well, such as selecting
from several possible versions of a .e file using a
system("copy ...", 2) command just before the include statement.

I hope this hasn't confused you too much!

-- Rob Craig
   Rapid Deployment Software

new topic     » goto parent     » topic index » view message » categorize

3. How do you read an expression?

*** 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 message » categorize

4. Re: How do you read an expression?

Like to thank David Cuny for his code.  Works perfect.  Anyone want a
program that graphs like a graphing calculator?  Cannot do X^X, SIN, COS,
TAN, and gets a few divid by zeros, but those will be fixed.
-----------------------------------------------------------------------------
                                                      Andrew Baron
                                                      E-Mail:abaron at cwave.com
-----------------------------------------------------------------------------

new topic     » goto parent     » topic index » view message » categorize

5. Re: How do you read an expression?

I'd like a copy too... I just downloaded the program yesterday and we'll
be glad if anyone will tell me where its potential is hidden and give me
and send me any programs they make....

Or

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu