Ejemplo n.º 1
0
        public List <string> Tokenize()
        {
            tokens = new List <string>();
            value  = String.Empty;
            char valueQuoteCharacter = '\0';
            char listConjunction     = '\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;
                    listConjunction = '\0';
                    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]))
                    {
                        if (listConjunction != '\0' && listConjunction != data[pos])
                        {
                            ParseError("consistent conjunction");
                        }
                        listConjunction = data[pos];
                        tokens.Add(listConjunction.ToString());
                        goto startParsingValue;
                    }
                    else
                    {
                        ParseError("conjunction");
                    }
                }

                if (++pos < data.Length)
                {
                    if (Tokens.IsConjunction(data[pos]))
                    {
                        tokens.Add(data[pos].ToString());
                    }
                    else
                    {
                        ParseError("conjunction");
                    }
                }
                else
                {
                    return(tokens);
                }
            }
        }
Ejemplo n.º 2
0
        public IFilter Parse()
        {
            var tokenizer = new Tokenizer(Filter);

            tokens = tokenizer.Tokenize();
            pos    = -2;

            string conjunction;

            ListFilter.JoinType joinType;
            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))
                {
                    joinType = ListFilter.JoinType.And;
                    var values = new List <string>();
                    while (!Tokens.IsListEnd(tokens[pos]) && !Tokens.IsListEnd(GetNextToken("value")))
                    {
                        values.Add(tokens[pos]);
                        if (GetNextToken("conjunction or list end") == "|")
                        {
                            joinType = ListFilter.JoinType.Or;
                        }
                    }
                    thisFilter = new ListFilter(name, oper, values, joinType);
                }
                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);
        }