Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a string into a BinaryExpression object?

Say we have strings like:

string s1 = "a < 5";
string s2 = "b >= 7";
string s3 = "c <= 8";
...

I want to convert such strings into BinaryExpression objects similar to what we get by using:

  BinaryExpression b1 = Expression.MakeBinary( ExpressionType.LessThan, Expression.Parameter( typeof( int ), "a" ), Expression.Constant( 5, typeof( int ) ) );
  BinaryExpression b2 = Expression.MakeBinary( ExpressionType.GreaterThanOrEqual, Expression.Parameter( typeof( int ), "b" ), Expression.Constant( 7, typeof( int ) ) );
  BinaryExpression b3 = Expression.MakeBinary( ExpressionType.LessThanOrEqual, Expression.Parameter( typeof( int ), "c" ), Expression.Constant( 8, typeof( int ) ) );

I have created the method below:

BinaryExpression ConvertStringToBinaryExpression( string exp )
{
  string[] s = exp.Split( ' ' );
  string param = s[ 0 ];
  string comparison = s[ 1 ];
  int constant = int.Parse( s[ 2 ] );
  if ( comparison == "<" )
    return Expression.MakeBinary( ExpressionType.LessThan, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
  else if ( comparison == "<=" )
    return Expression.MakeBinary( ExpressionType.LessThanOrEqual, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
  else if ( comparison == ">" )
    return Expression.MakeBinary( ExpressionType.GreaterThan, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
  else if ( comparison == ">=" )
    return Expression.MakeBinary( ExpressionType.GreaterThanOrEqual, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
  else
    throw new ArgumentException( "Invalid expression.", "exp" );
}

However, the above method does not work properly if, for example, we have strings like:

string s4 = "a< 5"  // no space between 'a' and '<'
string s5 = "b>=9"  // no space at all
string s6 = "c <=7"  // no space betwen '<=' and '7'

What is the easiest way to make it more robust and reliable?

like image 939
Setyo N Avatar asked Oct 06 '22 01:10

Setyo N


2 Answers

As Harsha pointed it out regex would make your task simple

Match m=Regex.Match("var4 <= 433",@"(?'leftOperand'\w+)\s*(?'operator'(<|<=|>|>=))\s*(?'rightOperand'\w+)");
m.Groups["leftOperand"].Value;//the varaible or constant on left side of the operator
m.Groups["operator"].Value;//the operator
m.Groups["rightOperand"].Value;//the varaible or constant on right side of the operator
like image 158
Anirudha Avatar answered Oct 10 '22 18:10

Anirudha


Use regex to match against some types of possible expressions (if you have an exhaustive and reasonably short list of possible expressions). Also parse the string if it does not match your regex to check for any unexpected chars.

EDIT: The regex and parse will help you "clean" the string before you can use your switch/if-else case.

http://www.c-sharpcorner.com/UploadFile/prasad_1/RegExpPSD12062005021717AM/RegExpPSD.aspx

like image 44
Harsha Avatar answered Oct 10 '22 18:10

Harsha