public IFilter Parse() { var tokenizer = new Tokenizer(Filter); tokens = tokenizer.Tokenize(); pos = -2; string conjunction; FilterSet filter = new FilterAndSet(); IFilter thisFilter; IFilter last; FilterOrSet orSet; while (++pos < tokens.Count) { conjunction = pos == -1 ? "," : tokens[pos]; var name = GetNextToken("field name"); var oper = GetNextToken("operator"); var value = GetNextToken("value"); if (Tokens.IsListStart(value)) { var values = new List <string>(); while (!Tokens.IsListEnd(GetNextToken("value"))) { values.Add(tokens[pos]); } thisFilter = new ListFilter(name, oper, values); } else { thisFilter = new Filter(name, oper, value); } if (conjunction == ",") // and { filter.Add(thisFilter); } else if (conjunction == "|") // or { last = filter.Last(); if (!(last is FilterOrSet)) { filter.RemoveAt(filter.Count - 1); orSet = new FilterOrSet(); orSet.Add(last); orSet.Add(thisFilter); filter.Add(orSet); } else { ((FilterOrSet)last).Add(thisFilter); } } else { throw new ParseException("Parser: Unexpected '{0}', expected conjunction instead.", conjunction); } } return(filter); }
public List <string> Tokenize() { tokens = new List <string>(); value = String.Empty; char valueQuoteCharacter = '\0'; bool valueIsQuoted = false; bool inList = false; pos = -1; while (true) { ResetValue(); while (++pos < data.Length && ExpectToken(Tokens.IsFieldName)) { value += data[pos]; } if (String.IsNullOrWhiteSpace(value)) { ParseError(true, "field name"); } tokens.Add(value); ResetValue(); while (++pos < data.Length && ExpectToken(Tokens.IsOperator)) { value += data[pos]; } if (String.IsNullOrWhiteSpace(value)) { ParseError(true, "operator"); } tokens.Add(value.Trim()); startParsingValue: ResetValue(); valueIsQuoted = Tokens.IsQuote(GetNextCharacter("value")); if (valueIsQuoted) { valueQuoteCharacter = data[pos]; } else if (!inList && Tokens.IsListStart(data[pos])) { inList = true; tokens.Add(data[pos].ToString()); goto startParsingValue; } else { value += data[pos]; } while (++pos < data.Length) { if (Tokens.IsEscapeCharacter(data[pos])) { value += GetNextCharacter("any character"); } else if ((valueIsQuoted && data[pos] == valueQuoteCharacter) || (!valueIsQuoted && NotExpectToken(Tokens.IsConjunction)) || (inList && NotExpectToken(Tokens.IsListEnd))) { break; } else { value += data[pos]; } } if (valueIsQuoted ? String.IsNullOrEmpty(value) : String.IsNullOrWhiteSpace(value)) { ParseError(true, "value"); } if (valueIsQuoted && pos >= data.Length) // if the value is quoted, we want a closing quote { ParseError(valueQuoteCharacter.ToString()); } tokens.Add(valueIsQuoted ? value : value.Trim()); ResetValue(); if (inList) { if (Tokens.IsListEnd(GetNextCharacter("conjunction or list end"))) { tokens.Add(data[pos].ToString()); inList = false; } else if (!Tokens.IsConjunction(data[pos])) { ParseError("conjunction"); } else { goto startParsingValue; } } if (++pos < data.Length) { if (Tokens.IsConjunction(data[pos])) { tokens.Add(data[pos].ToString()); } else { ParseError("conjunction"); } } else { return(tokens); } } }