It was one of the articles on Expression Evaluator that got me thinking, how easy it was to write an expression evaluator in C# with different types. Well thinking is one thing and doing another. So I set about to write an expression evaluator, which could take in data of types
string and boolean.
I am still at learning C#, so I decided to experiment a bit with all kinds of programming constructs. In places where a
foreach could have been very useful, I have used a
while. Pardon me for this indulgence.
public class ExpressionEvaluator
protected string postfix
protected string operators
protected string separators
protected Hashtable precedence
protected StringStack stack
protected Hashtable symbol_table
public ExpressionEvaluator(string exp)
public ExpressionEvaluator(string exp,
ref Hashtable sym) : this(exp)
The first constructor receives a string infix expression. It populates the operator precedence table and converts the infix expression to a postfix expression. The second constructor, receives a reference symbol table from the user of the class. Whenever an identifier is found in the expression, the value is either read or updated in the symbol table.
public string Solve()
The user of the class, calls this method to solve the expression. Basically this implements the postfix expression evaluation algorithm.
protected string Evaluate(string opr,
string operand1, string operand2)
This method, gets the types operand object from the
string, checks if the operation
opr is valid for the types of
operand2. If valid it calls the
GetResult() method, else throws an
protected void InfixToPostfix()
infix tokens to
postfix token list.
protected bool IsOperator(string str)
str is an operator.
protected string GetResult(string opr,
object obj1, object obj2)
This function actually applies
opr to the objects
obj2. It returns the result as
protected bool IsValidTypeConversion(TypeCode t1, TypeCode t2)
Checks if the type conversion is a valid one.
protected object GetTypedOperand(string operand)
string operand, it returns a typed object. Here I tried to use some regular expressions to identify the typed object to return. If none of the regular expression patterns match, we assume it is an identifier. Here is the source snippet:
string long_pattern = "([0-9])+";
string double_pattern = "(?:[0-9]*\\.)?[0-9]+";
string string_pattern =
string bool_pattern = "(true|false)+";
if (Regex.IsMatch(operand, long_pattern))
if (Regex.IsMatch(operand, double_pattern))
if (Regex.IsMatch(operand, string_pattern))
if (Regex.IsMatch(operand.ToLower(), bool_pattern))
public class MalformedExpException : Exception
When a postfix expression cannot be parsed on the stack, the exception is thrown.
public class InvalidIdentifierException : Exception
When a token in an expression is an identifier, and cannot be found in the symbol table, the exception is thrown.
public class InvalidTypeConversionException : Exception
When a type conversion is invalid, the exception is thrown
public class InvalidOperationOnType : Exception
When an operation cannot be applied to types of operands, the exception is thrown.
- I would like to implement operations like