private bool ParseExpression(string expression, int start, out ExpressionTree tree,
out int expressionLength)
{
tree = null;
expressionLength = 0;
if(start < 0 || start >= expression.Length) {
return false;
}
// get the end position
int position = start;
ExpressionElement[] elements = new ExpressionElement[3];
int elementPosition = 0;
int length = expression.Length;
while(position < length) {
// jump over spaces
if(expression[position] == ' ' || expression[position] == ExpressionEndChar) {
position++;
continue;
}
bool positionChanged = false;
if(expression[position] == ExpressionStartChar) {
ExpressionTree child;
int subexpressionLength;
// invalid expression
if(ParseExpression(expression, position + 1, out child, out subexpressionLength) == false) {
return false;
}
// invalid expression
if(elementPosition == 1) {
return false;
}
elements[elementPosition].Type = ElementType.Tree;
elements[elementPosition].Element = child;
elementPosition++;
position += subexpressionLength + 1;
positionChanged = true;
}
else {
// get the first substring
string[] components = expression.Substring(position).Split(ExpressionSeparators,
StringSplitOptions.RemoveEmptyEntries);
// invalid expression
if(components.Length == 0) {
return false;
}
FilterImplication implication;
if(GetImplicationType(components[0], out implication)) {
// valid Implication
if(elementPosition != 1) {
// invalid expression
return false;
}
elements[elementPosition].Type = ElementType.Implication;
elements[elementPosition].Element = implication;
elementPosition++;
}
else {
// Filter name
if(elementPosition == 1) {
// invalid expression
return false;
}
FilterBase filter = GetFilter(components[0]);
// invalid expression
if(filter == null) {
return false;
}
elements[elementPosition].Type = ElementType.Filter;
elements[elementPosition].Element = filter;
elementPosition++;
}
position += components[0].Length + 1;
positionChanged = true;
}
if(positionChanged == false) {
position++;
}
if(position >= length || elementPosition >= 3) {
// end of expression, build evaluation tree
if(elementPosition == 2) {
// invalid expression
return false;
}
// build the tree
tree = AssociateElements(elements, elementPosition);
expressionLength = position - start;
return true;
}
}
return false;
}