Give some suggestion on calculating base on given math statement.

J

James

Currently, I put a JTextField and this textfield is for user to key in some
math statement. (such as "(50-20)*3+50/2")
So later my program should getback this from textfield which is String and
convert it into Integer and do calculation base on this.
So anyone can give some suggestion on it?
Is that I need to separate this string into char array then take out
operator and operand?
If that is only way, then later how to combine it back to get the final
answer from this?
 
T

Thomas Hawtin

James said:
Currently, I put a JTextField and this textfield is for user to key in some
math statement. (such as "(50-20)*3+50/2")
So later my program should getback this from textfield which is String and
convert it into Integer and do calculation base on this.
So anyone can give some suggestion on it?
Is that I need to separate this string into char array then take out
operator and operand?
If that is only way, then later how to combine it back to get the final
answer from this?

You want to convert the sequence of characters into a sequence of tokens:

"(", "50", "-", ")", "*", "3", "+", "50", "/", "2""

This simple case can be handled by StringTokenizer.

You then have to get your head around parsing a grammar. You can handle
this example with pretty simple rules. There are a number of ways of
going about it, but here's a simple one:

At the deepest level you want to be able to handle "(" and literal
tokens. Handling literals should straight forward enough - just parse
and return. Handling "(" you should recurse to the method handling the
top level expression, and then consume the trailing ")", before
returning the result to the calling method. If the first token is
anything else, then that indicates a syntax error.

A level up you should handle * and /. First off you want to handle any
leading () or literals, so call the method described in the previous
paragraph. Then loop round consuming a "*" or "/" followed by another of
the previous method. If you find a symbol which is not * or / (it should
be a + or -), just return the value computed so far.

At the top level, do much the same as the method described in the
previous paragraph, but this time for + and - calling the method for *
and / instead of the one for () and literals.

You might want to start off just implementing the first method and only
handling expressions such as "((((50))))". Then add the second method,
handling expressions such as "50*4/(3*2)". Then add the final method to
finish it off.

I was tempted to post code, but I think you should work that out for
yourself.

Tom Hawtin
 
R

Roedy Green

Currently, I put a JTextField and this textfield is for user to key in some
math statement. (such as "(50-20)*3+50/2")
So later my program should getback this from textfield which is String and
convert it into Integer and do calculation base on this.
So anyone can give some suggestion on it?

What you would like is called an eval method. Java does not have one.
See http://mindprod.com/jgloss/eval.html for your various options to
create one.

This problem is far trickier than it first looks but not nearly so
terrifying as it does just after it dawns on you just what has to be
done.
 
M

Malte

James said:
Currently, I put a JTextField and this textfield is for user to key in some
math statement. (such as "(50-20)*3+50/2")
So later my program should getback this from textfield which is String and
convert it into Integer and do calculation base on this.
So anyone can give some suggestion on it?
Is that I need to separate this string into char array then take out
operator and operand?
If that is only way, then later how to combine it back to get the final
answer from this?

Oh well, you need REXX's interpret function. We all do, btw.
 
S

Stefan Ram

James said:
Currently, I put a JTextField and this textfield is for user to
key in some math statement. (such as "(50-20)*3+50/2")
So later my program should getback this from textfield which is
String and convert it into Integer and do calculation base on this.
So anyone can give some suggestion on it?

In order to interpret or translate an expression (term), it is
decomposed into lexical units (tokens, words), which then are
used by a parser to build symbols and a structured
representation of the input. This representation then might be
evaluated or translated into some other representation.

The syntactial structuring resembles the rules for the
construction of an expression, which often is given by so-
called "productions" of the EBNF (extended Backus-Nauer-Form)
and which sometimes are left-recursive.

When writing a parser, the left-recursive productions
sometimes are a worry to the author, because it is not obvious
how to avoid an infinite recursion. The solution is to rewrite
them as right-recursive productions.

The addition with a binary infix Operator, for example, is
left associative. However, it is simpler to analyze in a
right-associative manner. Therefore, one analyzes the source
using right-associative rules and then creates a result using
a left-associative interpretation.

A left-associative grammar might be, for example, as follows.

<numeral> ::= '2' | '4' | '5'.
<expression> ::= <numeral> | <expression> '+' <numeral>.
start symbol: <expression>.

To analyze this using a recursive descent parser one
prefers to use the following grammar.

<numeral> ::= '2' | '4' | '5'.
<expression> ::= <numeral>[ '+' <expression> ].
start symbol: <expression>.

This can be written using iteration as follows.

<numeral> ::= '2' | '4' | '5'.
<expression> ::= <numeral>{ '+' <numeral> }.
start symbol: <expression>.

However, the product is created in the sense of the
first grammar. Example code follows.

class Scan
{ static String source = "5+4+2)";
static int pos = 0;
static char get(){ return source.charAt( pos++ ); }}

class Parse
{
static int numeral(){ return Scan.get() - '0'; }

static int expression(){ int result = numeral();
while( '+' == Scan.get() )result += numeral();
return result; }}

public class Start
{
public static void main( final String[] args )
{ System.out.println( Parse.expression() ); }}

To be able to parse expressions with higher
priority, the grammar can be extended.

<numeral> ::= '2' | '4' | '5'.
<product> ::= <numeral> | <product> '*' <numeral>.
<sum> ::= <product> | <sum> '+' <product>.
start symbol: <sum>.

In iterative notation:

<numeral> ::= '2' | '4' | '5'.
<product> ::= <numeral>{ '*' <numeral> }.
<sum> ::= <product>{ '+' <product> }.
start symbol: <sum>.

In Java:

class Scan
{ static String source = "5+4*2)";
static int pos = 0;
static char get( final boolean advance )
{ return source.charAt( advance ? pos++ : pos ); }}

class Parse
{
static int numeral(){ return Scan.get( true ) - '0'; }

static int product(){ int result = numeral();
while( '*' == Scan.get( false )){ Scan.get( true ); result *= numeral(); }
return result; }

static int sum(){ int result = product();
while( '+' == Scan.get( true ))result += product();
return result; }}

public class Start
{
public static void main( final String[] args )
{ System.out.println( Parse.sum() ); }}

Exercises

- What is the output of the above programs?

- Extend the last grammar and the last program so as
to handle subtraction.

- Extend the result of the last exercise in order
to handle division.

- Extend the result of the last exercise so that also
numbers with multiple digits are excepted.

- Extend the result of the last exercise so that also
terms in parentheses are accepted. The input "(2+4)*5)"
should give the result "30".

- Extend the result of the last exercise so that
also a unary minus "-" is recognized.

- Extend the result of the last exercise so that
more operators and functions are recognized.

- Extend the result of the last exercise so that
meaningful error messages are created for all
inputs that to not fulfill the rules of the input
language.

- Extend the result of the last exercise so that the
error messages also show the location where the error
was detected. It should be possible to enter expression
that span multiple lines and an error message should
contain the number of the line where an error was
detected.

See also:

JEP - Java Mathematical Expression Parser
http://www.singularsys.com/jep/

Steven Metsker: Building Parsers with Java.
Addison-Wesley 2001, ISBN 0201719622.

A.W. Appel: Modern Compiler Implementation in Java.
Cambridge University Press 1998, ISBN 0521586542.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top