I'm trying to parse equations like these which only has two values or the square root of a certain value from a text file:
100+100
-100-100
-(100)+(-100)
sqrt(100)
by the minues signs, parenthesis and the operator symbol in the middle and the square root, and i have no idea how to start off...i've got the file part done and the simple calculation parts except that i couldnt get my program to solve the equations in the above.

char *tok = buff;
        sscanf(tok,"%lf%c%lf",&num1,&sym,&num2);

that is what have i written for the other basic operations without parenthesis and the minus sign for the second value and it works great for the simple ones. i'm using a switch method to calculate the add,sub,mul and divide but i'm not sure how to properly use the sscanf function (if i am not using it properly) or if there is another way using a function like strtok to properly parse the parenthesis and the minus signs. any kind help?

100+100
-100-100
-(100)+(-100)
sqrt(100)

The last line above could be tested / handled by:
if "sqrt(" 
    then if  int  
         then if ")" 
            then process ...


The next to last line could be tested / handled by:
else if "+(" or "-("
  then if int   
       then if ")"    
           then if valid_binary_op
              then if int or (int)
                 then process

The first two lines above both could be handled as:
else if int 
   then if valid_binary_op 
      then if int
         then process ...

else ... data input error, that input format not handled here

Edited 2 Years Ago by David W: added info

Generally, when you have to parse input that must adhere to some constraints (a language, for example) you use a grammar. The grammar can be built up in a variety of ways: using tools like yacc/bison or in code ala llvm. In the former, you usually have a parser generator that will create parser code for you from the grammar (lex/flex provides this role for yacc).

In this case, where the input is simple enough, I'd go with an in-code model. Write a routine that takes a line and returns the tokens of the line:

int tokenize (const char * line, 
              std::vector< std::pair< const char *, token_type > > &tokens) {
   // walk the input line here looking for tokens
   // for example... line = "(123)"
   tokens.push_back (std::make_pair (&line[0], TOKEN_LPAREN))
   tokens.push_back (std::make_pair (&line[1], TOKEN_NUMBER))
   tokens.push_back (std::make_pair (&line[4], TOKEN_RPAREN))
   return 3;
}

Of course, that is incomplete: you would need to do the string walking and provide the token enum. But one you have that you can easily iterate the token vector and do your processing.

Edited 2 Years Ago by L7Sqr

Comments
Good advise.

thanks! but i'm not familiar with C++ language. i'm guessing that i have to use 'strtok' in C using delimiters of the parenthesis. but the number values that come could be any length meaning that i would have to find the length of each of the value first for such method?

In addition to the isdigit check, you can also use strtol which will read as many digits as are valid and return a pointer to the next character in the string.

I provided a Code Snippet that uses this exact technique (although doesn't account for things like sqrt). Look at the ShuntingYard::convert method. It's written in C++ and uses strtod but the parsing loop could be used as C code and strtol could be used instead.

This article has been dead for over six months. Start a new discussion instead.