Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

153 lines
3.0 KiB
C#

using System;
using System.Collections;
using NUnit.Core;
using NUnit.Core.Filters;
namespace NUnit.Util
{
/// <summary>
/// CategoryExpression parses strings representing boolean
/// combinations of categories according to the following
/// grammar:
/// CategoryName ::= string not containing any of ',', '&', '+', '-'
/// CategoryFilter ::= CategoryName | CategoryFilter ',' CategoryName
/// CategoryPrimitive ::= CategoryFilter | '-' CategoryPrimitive
/// CategoryTerm ::= CategoryPrimitive | CategoryTerm '&' CategoryPrimitive
/// </summary>
public class CategoryExpression
{
static readonly char[] ops = new char[] { ',', ';', '-', '|', '+', '(', ')' };
private string text;
private int next;
private string token;
private TestFilter filter;
public CategoryExpression(string text)
{
this.text = text;
this.next = 0;
}
public TestFilter Filter
{
get
{
if( filter == null )
{
filter = GetToken() == null
? TestFilter.Empty
: GetExpression();
}
return filter;
}
}
private TestFilter GetExpression()
{
TestFilter term = GetTerm();
if ( token != "|" )
return term;
OrFilter filter = new OrFilter( term );
while ( token == "|" )
{
GetToken();
filter.Add( GetTerm() );
}
return filter;
}
private TestFilter GetTerm()
{
TestFilter prim = GetPrimitive();
if ( token != "+" && token != "-" )
return prim;
AndFilter filter = new AndFilter( prim );
while ( token == "+"|| token == "-" )
{
string tok = token;
GetToken();
prim = GetPrimitive();
filter.Add( tok == "-" ? new NotFilter( prim ) : prim );
}
return filter;
}
private TestFilter GetPrimitive()
{
if( token == "-" )
{
GetToken();
return new NotFilter( GetPrimitive() );
}
else if( token == "(" )
{
GetToken();
TestFilter expr = GetExpression();
GetToken(); // Skip ')'
return expr;
}
return GetCategoryFilter();
}
private CategoryFilter GetCategoryFilter()
{
CategoryFilter filter = new CategoryFilter( token );
while( GetToken() == "," || token == ";" )
filter.AddCategory( GetToken() );
return filter;
}
public string GetToken()
{
SkipWhiteSpace();
if ( EndOfText() )
token = null;
else if ( NextIsOperator() )
token = text.Substring(next++, 1);
else
{
int index2 = text.IndexOfAny( ops, next );
if ( index2 < 0 ) index2 = text.Length;
token = text.Substring( next, index2 - next ).TrimEnd();
next = index2;
}
return token;
}
private void SkipWhiteSpace()
{
while( next < text.Length && Char.IsWhiteSpace( text[next] ) )
++next;
}
private bool EndOfText()
{
return next >= text.Length;
}
private bool NextIsOperator()
{
foreach( char op in ops )
if( op == text[next] )
return true;
return false;
}
}
}