使用方法:10-2*3 得到结果 6。
ExpressionParser.cs
using
System;

namespace
IBMS.Text.Script

{

Field#region Field

/**//// <summary>
/// Parser of syntax
/// </summary>
public class ExpressionParser

{

/**//// <summary>
/// Threse are the token types
/// </summary>
public enum TokenTypes

{

/**//// <summary>
/// Not defined type of token
/// </summary>
None,


/**//// <summary>
/// Delimiter token type
/// </summary>
Delimiter,


/**//// <summary>
/// Variable token type
/// </summary>
Variable,


/**//// <summary>
/// Number token type
/// </summary>
Number,
}


/**//// <summary>
/// These are the types of syntax errors
/// </summary>
public enum SyntaxErrors

{

/**//// <summary>
/// All syntax error
/// </summary>
Synatx,


/**//// <summary>
/// Bracket error
/// </summary>
UnBalparens,


/**//// <summary>
/// No expression error
/// </summary>
NoExpression,

/**//// <summary>
/// Divide by zero error
/// </summary>
DivByZero,
}


/**//// <summary>
/// This token indicates end-of-expression
/// </summary>
readonly private string EOE;

/**//// <summary>
/// refers to expression string
/// </summary>
private string exp;

/**//// <summary>
/// Current index into the expression
/// </summary>
private int expIdx;

/**//// <summary>
/// Holds current token
/// </summary>
private string token;

/**//// <summary>
/// Holds current token's type
/// </summary>
private TokenTypes tokType;

#endregion


Public Mothord#region Public Mothord

/**//// <summary>
/// Constructor
/// </summary>
public ExpressionParser()

{
EOE= "\0";
}


/**//// <summary>
/// Parsor entry point
/// </summary>
/// <param name="expstr">expression string</param>
/// <returns>result of the expression</returns>
public double Evaluate(string expstr)

{
double result = 0.0;
exp =expstr;
expIdx = 0;

GetToken();
if( token == EOE)

{
HandleError(SyntaxErrors.NoExpression); //No expression present
}

//Parse and evaluate the expression
result = EvalExp2();
if( token != EOE)

{
HandleError(SyntaxErrors.Synatx);
}

return result;
}

#endregion


Private Methord#region Private Methord

/**//// <summary>
/// Add or ssubtract two terms;
/// </summary>
/// <returns>Evaluated result</returns>
private double EvalExp2()

{
char op;
double result;
double partialResult;

result = EvalExp3();

while( ((op=token[0]) ) == '+' || op == '-')

{
GetToken();
partialResult = EvalExp3();
switch(op)

{
case '+':
result += partialResult;
break;
case '-':
result -= partialResult;
break;
}
}

return result;
}


/**//// <summary>
/// Multiply or divide two factors.
/// </summary>
/// <returns>Evaluated result</returns>
public double EvalExp3()

{
char op;
double result;
double partialResult;

result = EvalExp4();

while( (op= token[0]) == '*'|| op == '/' || op =='%')

{
GetToken();
partialResult = EvalExp4();
switch(op)

{
case '*':
result *=partialResult;
break;
case '/':
if(partialResult == 0.0)

{
HandleError(SyntaxErrors.DivByZero);
}
result /= partialResult;
break;
case '%':
if(partialResult == 0.0)

{
HandleError(SyntaxErrors.DivByZero);
}
result %= partialResult;
break;
}
}

return result;

}


/**//// <summary>
/// Process an exponent
/// </summary>
/// <returns></returns>
private double EvalExp4()

{
double result;
double partialResult;
double ex;
int t;

result = EvalExp5();
if(token =="^" )

{
GetToken();
partialResult = EvalExp4();
ex = result;
if(partialResult == 0.0 )

{
result = 1.0;
}
else

{
for(t=(int)partialResult-1; t>0; t--)

{
result *= ex;
}
}
}

return result;
}

//Evaluate a unary + or -
private double EvalExp5()

{
double result;
string op;

op="";
if( (tokType == TokenTypes.Delimiter) && ( token =="+" || token =="-") )

{
op = token;
GetToken();
}

result = EvalExp6();

if(op == "-") result = - result;

return result;
}

private double EvalExp6()

{
double result;
if(token=="(")

{
GetToken();
result = EvalExp2();

if(token!=")")

{
HandleError(SyntaxErrors.UnBalparens);
}

GetToken();
}
else

{
result = Atom();
}
return result;
}


/**//// <summary>
/// Get the value of a number
/// </summary>
/// <returns></returns>
private double Atom()

{
double result = 0.0;

switch(tokType)

{
case TokenTypes.Number:
try

{
result = Double.Parse(token);
}
catch(InvalidCastException)

{
HandleError( SyntaxErrors.Synatx );
}

GetToken();
break;
default:
HandleError( SyntaxErrors.Synatx );
break;
}

return result;
}


/**//// <summary>
/// Handle an error
/// </summary>
/// <param name="error">index of error</param>
void HandleError(SyntaxErrors error)

{
String [] err = new string[]

{
"Syntax Error",
"Unabalanced Parentheses",
"No Expression Present",
"Division By Zero"
};

throw new ExpressionParserException(err[(int)error]);
}

/**//// <summary>
/// Obtain the next token
/// </summary>
private void GetToken()

{
tokType = TokenTypes.None;
token = "";
//Check for end of expression.
if( expIdx == exp.Length)

{
token = EOE;
return;
}

//Skip over white space
while( expIdx <exp.Length && char.IsWhiteSpace( exp[expIdx] ) ) ++expIdx;
//Trailing whitespace ends expression.

if( expIdx == exp.Length )
{
token = EOE;
return;
}

if( IsDelimiter(exp[expIdx] ) ) //Is operator

{
token+=exp[expIdx];
expIdx++;
tokType = TokenTypes.Delimiter;
}
else if (Char.IsLetter(exp[expIdx])) //Is variable

{
while(!IsDelimiter( exp[expIdx]) )

{
token += exp[expIdx];
expIdx ++;
if(expIdx >= exp.Length ) break;
}
tokType = TokenTypes.Variable;
}
else if( char.IsDigit(exp[expIdx])) //Is a number

{
while( !IsDelimiter(exp[expIdx]))

{
token += exp[expIdx];
expIdx ++;
if( expIdx >= exp.Length ) break;
}
tokType = TokenTypes.Number;
}
else

{
token = EOE;
return;
}
}


/**//// <summary>
/// Check whether c is a delimiter
/// </summary>
/// <param name="c">the checked char</param>
/// <returns>Return true if c is a delimiter, else return false</returns>
private static bool IsDelimiter(char c)

{
if( (" +-/*%^=()".IndexOf(c) !=-1 ))

{
return true;
}

return false;
}


#endregion
}

}
ExpressionParserException.cs