Link to home
Start Free TrialLog in
Avatar of chenwei
chenwei

asked on

From string to formular

I am going to write a program which should handle the math.
                                    formular entered by the user. Excactly to say: if the program is
                                    statrd, it shows a edit window and the user can enter a math.
                                    formular in any form such as (a+b)*x/y, 5*sin(x+a) etc.. The
                                    problem is, the program reads the formular as a string, not as a
                                    formular. I was told it's quite complicated to write a program to
                                    translate the string to a formular.

                                    Dos someone have any good idea?
Avatar of KangaRoo
KangaRoo

You have to parse the expression, then evaluate it. Complexity depends a bit on how much math it is supposed to handle. Check out.

http://www.snippets.org/#section1group12

De main trick to this is to get a decent grammar for the expressions you'r expected. Check out your C and C++ documentation for how their expression grammar is defined. The grammar will directly lead to a parser implementation.
I can give example code of a simple prefix expression parser if you want.
Avatar of chenwei

ASKER

yes, please.
/*
                                                                        Infix.C

Simple Infix Expression Grammar, intended as starting point, it's by far not complete and does not perform the actual evaluation yet.

      primairy_expression:
            literal
            (expression)

      multiplicative_expression:
            primairy_expression
            multiplicative_expression * primairy_expression
            multiplicative_expression / primairy_expression
            multiplicative_expression % primairy_expression

      additive_expression:
            multiplicative_expression
            additive_expression + multiplicative_expression
            additive_expression - multiplicative_expression

   This grammar is easily and directly translated into a program. It only
   parses additive (+ and -) and multiplicative (*, / and%) expressions to
   demonstrate implementation of precedence. Other operators and their
   precedence can easily be added.

   Note:      Postfix output is obtained by replacing the printf() statements
               with pushes onto the postfix expression (rpn) stack.
*/

#include <stdio.h>
#include <ctype.h>
#include <assert.h>

void  Error(char*);
char* SkipWhite(char*);
int   ParseInfixExpression(char*);
char* AdditiveExpression(char*);
char* MultiplicativeExpression(char*);
char* PrimairyExpression(char*);
char* LiteralExpression(char*);

void Error(char* msg)
{
      assert(msg != 0);
      printf("Error: %s\n", msg);
}

char* SkipWhite(char* expression)
{
      while(expression && isspace(*expression)) ++expression;
   return expression;
}

int ParseInfixExpression(char* expression)
{
      assert(expression != 0);
      expression = AdditiveExpression(expression);
      return !expression || (expression && *expression) ? 0 : 1;
}


char* AdditiveExpression(char* expression)
{
      assert(expression != 0);

      /*      multiplicative_expression */
        expression = SkipWhite(MultiplicativeExpression(expression));

      /*      additive_expression + multiplicative_expression */
      while(expression && (*expression == '+' || *expression == '-'))
      {
            char* tmp = MultiplicativeExpression(expression+1);
      if(tmp) printf("operator: %c\n", *expression);
      expression = SkipWhite(tmp);
   }
      return expression;
}

char* MultiplicativeExpression(char* expression)
{
      assert(expression != 0);

        expression = SkipWhite( PrimairyExpression(expression) );
      while( expression
                && ( *expression == '*' || *expression == '/' || *expression == '%')
        )
      {
            char* tmp = PrimairyExpression(expression + 1);
      if(tmp) printf("operator: %c\n", *expression);
      expression = SkipWhite(tmp);
   }
      return expression;
}

char* PrimairyExpression( char* expression )
{
      assert(expression != 0);
      expression = SkipWhite(expression);
      if(*expression == '(')
      {
            expression = SkipWhite(AdditiveExpression(expression+1));
            if(!expression)
            return expression;
      else if(expression && *expression != ')')
            Error("Missing ')' in expression");
            else ++expression; // skip the brace
      }
      else
            expression = LiteralExpression(expression);
      return expression;
}

char* LiteralExpression(char* expression)
{
   int cursor = 0;
      assert(expression != 0);
   expression = SkipWhite(expression);

      while( isalnum(expression[cursor]) ) ++cursor;
   if(cursor)
      {
            char tmp = expression[cursor];
      expression[cursor] = '\0';
      printf("operand:  %s\n", expression);
      expression[cursor] = tmp;
         return expression + cursor;
   }
   else
   {
         Error("Bad Literal Expression");
            return 0;
   }
}

int main(int argc, char** argv)
{
      if(argc < 2) return 1;
      printf("Parsing ParseExpression: %s\n",argv[1]);
      ParseInfixExpression(argv[1]);
      return 0;
}
Avatar of chenwei

ASKER

yes, please.
Avatar of chenwei

ASKER

Could you update the page so I can give you the point?
ASKER CERTIFIED SOLUTION
Avatar of KangaRoo
KangaRoo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of chenwei

ASKER

Could you update the page so I can give you the point?
Avatar of chenwei

ASKER

Thank you very much!
Kangaroo you stole my answer that I stole from you!  :-)

Take a look at
https://www.experts-exchange.com/jsp/qShow.jsp?ta=cplusprog&qid=10240261 
Avatar of chenwei

ASKER

Nietod is a very honest man. We all should learn from him.

But don't worry, Nietod, you can get points from me later. The 2000 is coming and I am sure I will have a lot of questions in 2000. :-)
Avatar of chenwei

ASKER

Nietod is a very honest man. We all should learn from him.

But don't worry, Nietod, you can get points from me later. The 2000 is coming and I am sure I will have a lot of questions in 2000. :-)
He is, we all do learn from him, and I'm honoured that he's quoting me :-)