Here's a program for a very simple grammar. It takes in as input an integer, then an operand, then an integer, and displays the result:
6*3=18
6-3=3
6+3=9
6/3=2
No error checking is implemented to make sure you have good input. This is one implementation of a very limited grammar. For more complex ones like the ones youa re mentioning, you may want to research Context Free Grammar and Recursive Descent Parsing. The program really doesn't parse, and certainly doesn't do it recursively, but it may give you a very small idea of how such a thing could be done.
CODE
#include <iostream>
using namespace std;
struct term
{
int operand1;
char binaryOperator;
int operand2;
};
int f (term theTerm);
int main ()
{
cout << "Enter a mathematical term. A legal term "
<< "is an integer followed by '+', '-', '*', or "
<< "'/' followed by another integer: ";
term theTerm;
cin >> theTerm.operand1;
cin >> theTerm.binaryOperator;
cin >> theTerm.operand2;
cin.ignore (); // Pause to get rid of rest of line
cout << theTerm.operand1 << theTerm.binaryOperator <<
theTerm.operand2 << "=";
cout << f(theTerm) << endl;
cin.ignore (); // Pause so console screen doesn't disappear.
return 0;
}
int f (term theTerm)
{
switch (theTerm.binaryOperator)
{
case '+':
return theTerm.operand1 + theTerm.operand2;
break;
case '-':
return theTerm.operand1 - theTerm.operand2;
break;
case '*':
return theTerm.operand1 * theTerm.operand2;
break;
case '/':
return theTerm.operand1 / theTerm.operand2;
break;
default:
return -9999; // error code: illegal binOp value
}
}
From a Context Free Grammar standpoint, this language would have one non-terminal:
TERM // short for "math term", not "terminal"
and two terminals:
NUMERIC_LITERAL
BINARY_OPERATOR
The starting Non-Terminal would be: TERM
It would have one rule:
<TERM> ---> NUMERIC_LITERAL BINARY_OPERATOR NUMERIC_LITERAL
<Term> goes to the above three terminals, in that order.
Obviously with parentheses and stuff, your grammar would be much more involved.