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
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
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
4. Re: How do you read an expression?
- Posted by Andrew Baron <abaron at CWAVE.COM>
Dec 26, 1996
-
Last edited Dec 27, 1996
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
-----------------------------------------------------------------------------
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