Reputation: 22011
Here is the code for a simple arithmetic expression parser I wrote:
class ArithmeticExpressionParser<T> : Parser<T> where T : IConvertible
{
dynamic num1, num2;
public override T Parse(string expr)
{
base.Parse(expr);
ParseExpression();
return num1;
}
T ParseExpression()
{
if(PeekNextToken())
num1 = ParseFactorial();
if (Token == '+')
{
GetNextToken();
num2 = ParseExpression();
num1 += num2;
}
else if (Token == '-')
{
GetNextToken();
num2 = ParseExpression();
num1 -= num2;
}
return num1;
}
T ParseFactorial()
{
if(PeekNextToken())
num1 = ParseNumber();
if (Token == '*')
{
GetNextToken();
num2 = ParseFactorial();
num1 *= num2;
}
else if (Token == '/')
{
GetNextToken();
num2 = ParseFactorial();
num1 /= num2;
}
else if (Token == '%')
{
GetNextToken();
num2 = ParseFactorial();
num1 %= num2;
}
return num1;
}
T ParseNumber()
{
string temp = String.Empty;
while (char.IsDigit(Token))
{
temp += Token;
GetNextToken();
}
return (T)Convert.ChangeType(temp, typeof(T));
}
}
If info is needed about the entire Parser
class, just comment and I'll post it.
For now, here are the things I think are relevant:
protected char GetNextToken()
{
do
{
if(Count++ >= expression.Length-1) break;
} while (char.IsWhiteSpace(expression[Count]));
return expression[Count];
}
protected bool PeekNextToken()
{
if (Count + 1 < expression.Length)
return true;
else
return false;
}
string expression;
protected char Token
{
get
{
return expression[Count];
}
}
int count;
protected int Count
{
get { return count; }
set
{
if (value < expression.Length)
count = value;
}
}
Now the Problem is, it doesn't give correct results.
...a lot of weird results.
Also, please suggest improvements, and better ways to achieve the same thing.
Note: I am trying to write a simple arithmetic Recursive Descent Parser
Upvotes: 1
Views: 106
Reputation: 1141
I do not have the solution, but looking at the code - 'ParseExpression' and 'ParseFactorial' operate and return num1, which is member accesed by all. Taking your last example 2+2-2, the first of the operation which happens is 2-2 = 0, and this overwrites the the firsr read value into num1 which is equal to 2. And hence the num1 = 0 before you can complete the addition operation and hence you get 0.
I checked that this logic gives out the resultant output provided for 3 examples.
I did find one more bug, your code never reads the last character if there is no space or a delimiter.
Upvotes: 2