Пример #1
0
        /// Read expression from string, evaluate it and return the value
        public object Eval(string expression)
        {
            if (expression == null)
            {
                return(null);
            }

            if (_exprCache == null)
            {
                _exprCache = new PrecompiledCache(128);
            }

            IOperation ex = _exprCache[expression];

            if (ex == null)
            {
                using (var sr = new ParsingReader(new StringReader(expression)))
                {
                    ex = new Parser(TokenSpecialCharacters).Parse(sr);
                    sr.SkipWhiteSpace();
                    sr.ReadAndThrowIfNot(-1);
                    _exprCache[expression] = ex;
                }
            }
            if (ex == null)
            {
                return(null);
            }
            return(Eval(ex));
        }
Пример #2
0
 /// Evaluate string and return the result of the evaluation, casted to the type T
 public T Eval <T>(string st)
 {
     using (var sr = new ParsingReader(new StringReader(st)))
     {
         var o = Eval <T>(sr);
         sr.SkipWhiteSpaceAndComments();
         sr.ReadAndThrowIfNot(-1);
         return(o);
     }
 }
Пример #3
0
        /// Parse stream until the end of the expression, evaluate it, and return result of the evaluation converted to type T
        public T Eval <T>(ParsingReader sr)
        {
            var p = Parser.Parse(sr);

            if (p == null)
            {
                return(Utils.To <T>(null));
            }
            return(Eval <T>(p));
        }
Пример #4
0
        /// <summary>
        /// Load script from string
        /// </summary>
        /// <param name="scriptXml">script as XML</param>
        public void Load(string scriptXml)
        {
            Items.Clear();
            bool close = true;
            var  r     = new ParsingReader(new StringReader(scriptXml));

            try
            {
                r.SkipWhiteSpace();
                if (r.Peek() == '<')
                {
                    // Get a script file
                    XmlReaderSettings rs = new XmlReaderSettings();
                    rs.IgnoreWhitespace = false;
                    rs.ValidationType   = ValidationType.None;

                    using (XmlReader xr = XmlReader.Create(r, new XmlReaderSettings()
                    {
                        ConformanceLevel = ConformanceLevel.Fragment
                    }))
                    {
                        close = false;
                        Load(xr);
                        return;
                    }
                }


                if (r.Peek() == '=')
                {
                    r.Read();
                    Items.Add(new Eval {
                        Value = r.ReadToEnd()
                    });
                    return;
                }
                Items.Add(new Code {
                    Value = r.ReadToEnd()
                });
                return;
            }
            finally
            {
                if (close)
                {
                    r.Close();
                }
            }
        }
Пример #5
0
        /// Parse command line into the list of arguments. Mimics .NET command line parsing logic where possible
        public static string[] SplitArgs(string commandLine)
        {
            if (commandLine == null)
            {
                return(null);
            }
            bool          quoted = false;
            List <string> args   = new List <string>();
            StringBuilder sb     = new StringBuilder();

            using (var reader = new ParsingReader(new StringReader(commandLine)))
            {
                int n;
                do
                {
                    n = reader.Read();
                    if (n == '"')
                    {
                        quoted = true;
                        while (!reader.IsEOF)
                        {
                            var ch = (char)reader.Read();
                            if (ch == '"')
                            {
                                break;
                            }
                            sb.Append(ch);
                        }
                    }
                    else if (n == -1 || char.IsWhiteSpace((char)n))
                    {
                        if (sb.Length > 0 || quoted)
                        {
                            args.Add(sb.ToString());
                        }
                        sb.Length = 0;
                        quoted    = false;
                    }
                    else
                    {
                        sb.Append((char)n);
                    }
                } while (n != -1);
            }
            return(args.ToArray());
        }
Пример #6
0
 /// True if str is a number
 public static bool IsNumber(string str)
 {
     if (str == null)
     {
         throw new ArgumentNullException("str");
     }
     using (var sr = new ParsingReader(str))
     {
         if (sr.ReadNumber() == null)
         {
             return(false);
         }
         sr.SkipWhiteSpaceAndComments();
         if (sr.Peek() != -1)
         {
             return(false);
         }
     }
     return(true);
 }
Пример #7
0
        /// <summary>
        /// Try to get variable value
        /// </summary>
        /// <param name="key">Variable name</param>
        /// <param name="value">Where to store found variable value</param>
        /// <returns>true if variable is set</returns>
        public override bool TryGetValue(string key, out object value)
        {
            if (!IsCalculated(key))
            {
                return(base.TryGetValue(key, out value));
            }
            using (var sr = new ParsingReader(key))
            {
                sr.SkipWhiteSpace();
                value = sr.ReadNumber();
                if (value != null)
                {
                    sr.SkipWhiteSpace();
                    sr.ReadAndThrowIfNot(-1);
                    return(true);
                }
            }

            value = EvalMulti(key);
            return(true);
        }
Пример #8
0
 /// Parse string to a number. 10 and hex numbers (like 0x222) are allowed. Suffixes like 20.3f are also allowed.
 public static ValueType ParseNumber(string str)
 {
     if (str == null)
     {
         throw new ArgumentNullException("str");
     }
     using (var sr = new ParsingReader(str))
     {
         sr.SkipWhiteSpaceAndComments();
         ValueType o = sr.ReadNumber();
         if (o == null)
         {
             throw new ParsingException("Invalid numeric expression at " + sr.ReadLine());
         }
         sr.SkipWhiteSpaceAndComments();
         if (sr.Peek() != -1)
         {
             throw new ParsingException("Invalid numeric expression, unexpected characters at " + sr.ReadLine());
         }
         return(o);
     }
 }
Пример #9
0
 /// Returns null if str is not a number, or its value otherwise
 public static ValueType TryParseNumber(string stringToParse)
 {
     if (stringToParse == null)
     {
         return(null);
     }
     using (var sr = new ParsingReader(stringToParse))
     {
         sr.SkipWhiteSpaceAndComments();
         ValueType o = sr.ReadNumber();
         if (o == null)
         {
             return(null);
         }
         sr.SkipWhiteSpaceAndComments();
         if (sr.Peek() != -1)
         {
             return(null);
         }
         return(o);
     }
 }
Пример #10
0
        /// <summary>
        /// Parse stream and return the expression tree
        /// </summary>
        /// <param name="r">Stream</param>
        /// <returns>Parsed expression or null if no expression is found on stream</returns>
        public IOperation Parse(ParsingReader r)
        {
            List <IOperation> data = new List <IOperation>();

            while (!r.IsEOF)
            {
                TokenQueue tokenQueue = new TokenQueue(this, r);
                var        ex         = parseSingleStatement(tokenQueue, -1);
                if (ex == null)
                {
                    break;
                }
                if (data.Count > 0)
                {
                    data.Add(new Operations.OperationPop());
                }
                data.Add(ex);
                r.SkipWhiteSpaceAndComments();
                if (r.Peek() != ';')
                {
                    break;
                }
                do
                {
                    r.Read();
                    r.SkipWhiteSpaceAndComments();
                } while (r.Peek() == ';');
            }
            if (data.Count == 0)
            {
                return(null);
            }
            if (data.Count == 1)
            {
                return(data[0]);
            }
            return(new Operations.OperationExpression(data.ToArray()));
        }
Пример #11
0
        /// Read multi-expression (like ${a|b|=3+5}) from the string, evaluate it and return the value
        public object EvalMulti(string multiExpression)
        {
            if (multiExpression == null)
            {
                return(null);
            }
            if (_exprCache == null)
            {
                _exprCache = new PrecompiledCache(128);
            }
            IOperation o = _exprCache[multiExpression];

            if (o == null)
            {
                using (var sr = new ParsingReader(new StringReader(multiExpression)))
                {
                    o = new Parser(TokenSpecialCharacters).ParseMulti(sr);
                    sr.SkipWhiteSpace();
                    sr.ReadAndThrowIfNot(-1);
                    _exprCache[multiExpression] = o;
                }
            }
            return(Eval(o));
        }
Пример #12
0
        /// <summary>
        /// Try to get variable value
        /// </summary>
        /// <param name="key">Variable name</param>
        /// <param name="value">Where to store found variable value</param>
        /// <returns>true if variable is set</returns>
        public override bool TryGetValue(string key, out object value)
        {
            if (!IsCalculated(key))
            {
                return(base.TryGetValue(key, out value));
            }
            using (var sr = new ParsingReader(key))
            {
                sr.SkipWhiteSpace();
                value = sr.ReadNumber();
                if (value != null)
                {
                    sr.SkipWhiteSpace();
                    sr.ReadAndThrowIfNot(-1);
                    return(true);
                }
            }


            if (!string.IsNullOrEmpty(key))
            {
                switch (key[0])
                {
                case '%':
                    EnvironmentVariableTarget target = getTarget(ref key);
                    value = Environment.GetEnvironmentVariable(key, target);
                    return(value != null);

                case '~':
                    value = Find(key.Substring(1), true);
                    return(true);
                }
            }
            value = EvalMulti(key);
            return(true);
        }
Пример #13
0
 /// Parse stream until the end of the expression, evaluate it, and return result of the evaluation
 public object Eval(ParsingReader sr)
 {
     return(Eval <object>(sr));
 }
Пример #14
0
 public TokenQueue(Parser p, ParsingReader r)
 {
     _reader = r;
     _parser = p;
 }
Пример #15
0
        private static object convertString(string text, Type pt)
        {
            if (pt.IsGenericType && pt.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (String.IsNullOrEmpty(text))
                {
                    return(null);
                }
                return(convertString(text, pt.GetGenericArguments()[0]));
            }
            if (String.IsNullOrEmpty(text))
            {
                if (pt.IsPrimitive || pt.IsEnum || pt == typeof(decimal))
                {
                    text = "0";
                }
            }


            if (pt == typeof(bool))
            {
                int t;
                if (Int32.TryParse(text, out t))
                {
                    return(t != 0);
                }
                return(Boolean.Parse(text));
            }
            if (pt == typeof(byte) ||
                pt == typeof(sbyte) ||
                pt == typeof(short) ||
                pt == typeof(ushort) ||
                pt == typeof(int) ||
                pt == typeof(uint) ||
                pt == typeof(long) ||
                pt == typeof(ulong) ||
                pt == typeof(decimal) ||
                pt == typeof(float) ||
                pt == typeof(double))
            {
                object o = ParsingReader.TryParseNumber(text);
                if (o == null)
                {
                    throw new InvalidCastException("Cannot cast '" + text + "' to " + pt.FullName);
                }
                return(Convert.ChangeType(o, pt));
            }
            if (pt == typeof(char?))
            {
                if (string.IsNullOrEmpty(text))
                {
                    return(null);
                }
                return(text[0]);
            }
            if (pt == typeof(char))
            {
                return(text[0]);
            }
            if (pt == typeof(DateTime))
            {
                return(DateTime.Parse(text));
            }
            if (pt == typeof(Guid))
            {
                return(new Guid(text));
            }
            if (pt == typeof(string))
            {
                return(text);
            }
            if (pt.IsEnum)
            {
                bool hasFlags  = CustomAttributeHelper.Has <FlagsAttribute>(pt);
                bool hasDigits = !string.IsNullOrEmpty(text) && text.IndexOfAny("0123456789".ToCharArray()) != -1;
                bool isempty   = string.IsNullOrEmpty(text);
                if (isempty || hasFlags || hasDigits)
                {
                    long val        = 0;
                    var  names      = Enum.GetNames(pt);
                    var  dictionary = new Dictionary <string, long>(StringComparer.OrdinalIgnoreCase);
                    var  values     = Enum.GetValues(pt);
                    for (int i = 0; i < names.Length; ++i)
                    {
                        long vv = (long)Convert.ChangeType(values.GetValue(i), typeof(long));
                        dictionary[names[i]] = vv;
                        if (isempty && vv == 0)
                        {
                            return(Enum.ToObject(pt, vv));
                        }
                    }
                    if (isempty)
                    {
                        throw new InvalidCastException(String.Format("Unexpected empty enum value"));
                    }

                    int step = 0;
                    foreach (string str in text.Split(s_enumDelimiters))
                    {
                        if (String.IsNullOrEmpty(str))
                        {
                            continue;
                        }
                        step++;
                        if (!hasFlags && step > 1)
                        {
                            throw new InvalidCastException(String.Format("Unexpected enum value {0}", str));
                        }
                        long v;
                        if (char.IsDigit(str[0]))
                        {
                            val |= ParsingReader.ParseNumber <long>(str);
                        }
                        else if (dictionary.TryGetValue(str, out v))
                        {
                            val |= v;
                        }
                        else
                        {
                            throw new InvalidCastException(String.Format("Unexpected enum value {0}", str));
                        }
                    }
                    return(Enum.ToObject(pt, val));
                }
                return(Enum.Parse(pt, text, true));
            }

            throw new InvalidCastException(String.Format("'{0}' cannot be converted to {1}", text, pt.ToString()));
        }
Пример #16
0
        private IEnumerable <Vars> getTransformedRows(string columnsOverride, string sortOverride, string whereExpression)
        {
            bool overrideSort = (sortOverride != null);

            if (!overrideSort)
            {
                sortOverride = Context.TransformStr(SortColumns, Transform);
            }

            //
            ColumnsInfo ci = new ColumnsInfo();

            // Load CSV, if present
            string text      = GetTransformedValueStr();
            string quote     = Context.TransformStr(Quote, Transform);
            string separator = Context.TransformStr(Separator, Transform);
            char?  quoteChar = string.IsNullOrEmpty(quote) ? (char?)null : quote[0];
            bool   trim      = (Options & RowsetOptions.Trim) != 0;
            string colNames  = Context.TransformStr(Columns, Transform);;
            // Read additional column names from the first CSV row, if specified
            ParsingReader csvReader = null;

            if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text.Trim()))
            {
                csvReader = new ParsingReader(new StringReader(text));
                if ((Options & RowsetOptions.Header) == RowsetOptions.Header)
                {
                    csvReader.SkipWhiteSpace();
                    colNames = Context.TransformStr(csvReader.ReadLine(), Verbatim ? TransformRules.None : Transform);
                }
            }

            char sep = string.IsNullOrEmpty(separator) ? '\0' : separator[0];

            // Add these columns
            if (!string.IsNullOrEmpty(colNames))
            {
                ci.AddParsed(Context, colNames, quoteChar, sep, trim);
            }

            // Add extra columns
            if (Cols != null)
            {
                foreach (var col in Cols)
                {
                    ColumnInfo cc = new ColumnInfo();
                    cc.Name      = Context.TransformStr(col.Name, col.Transform);
                    cc.Value     = Context.TransformStr(col.Value, col.Transform);
                    cc.IsDefault = (col.Default != null);
                    if (cc.IsDefault)
                    {
                        cc.Default = Context.Transform(col.Default, col.Transform);
                    }
                    object t = Context.Transform(col.Type, col.Transform);
                    if (t != null)
                    {
                        if (t is Type)
                        {
                            cc.Type = (Type)t;
                        }
                        else
                        {
                            cc.Type = Context.FindType(t.ToString());
                        }
                    }
                    ci.Add(cc);
                }
            }

            SortInfos si = new SortInfos(sortOverride, quoteChar, sep, trim);

            if (!overrideSort && SortCols != null)
            {
                foreach (var col in SortCols)
                {
                    var ss = new SortInfo
                    {
                        Name = Context.TransformStr(col.Name, col.Transform),
                        Sort = col.Sort
                    };

                    var cmp = Context.Transform(col.Comparer, Transform);
                    if (cmp != null)
                    {
                        object c1 = null;
                        if (cmp is Type)
                        {
                            ss.Comparer = (IComparer)Utils.CreateInstance((Type)cmp);
                        }
                        else if (cmp is string && !string.IsNullOrEmpty((string)cmp))
                        {
                            string smp = (string)cmp;
                            if (smp.ToUpperInvariant() == "IGNORECASE" || smp.ToUpperInvariant() == "NOCASE" || smp.ToUpperInvariant() == "IC")
                            {
                                ss.Comparer = StringComparer.CurrentCultureIgnoreCase;
                            }
                            else if (Utils.TryGetProperty(null, typeof(StringComparer), smp, null, false, out c1))
                            {
                                ss.Comparer = (IComparer)c1;
                            }
                            else
                            {
                                ss.Comparer = (IComparer)Utils.CreateInstance(Context.FindType(smp));
                            }
                        }
                        else
                        {
                            ss.Comparer = (IComparer)cmp;
                        }
                    }
                    si.Add(ss);
                }
            }

            var ret = si.SortAndFilter(Context, columnsOverride, whereExpression, getTransformedRowsInternal(ci, csvReader));

            if (columnsOverride == null)
            {
                return(ret);
            }


            ci = new ColumnsInfo();
            ci.AddParsed(Context, columnsOverride, quoteChar, separator[0], trim);
            return(ci.Process(ret));
        }
Пример #17
0
        private IEnumerable <Vars> getTransformedRowsInternal(ColumnsInfo ci, ParsingReader csvReader)
        {
            int rowNo = 0;

            string quote     = Context.TransformStr(Quote, Transform);
            string separator = Context.TransformStr(Separator, Transform);
            char?  quoteChar = string.IsNullOrEmpty(quote) ? (char?)null : quote[0];
            bool   trim      = (Options & RowsetOptions.Trim) != 0;

            // Read the rest of CSV, if available
            if (csvReader != null)
            {
                // If there are no columns, treat data as the list of strings
                if (ci.Count == 0)
                {
                    string s;
                    while ((s = csvReader.ReadLine()) != null)
                    {
                        if ((Options & RowsetOptions.Trim) == RowsetOptions.Trim)
                        {
                            s = s.Trim();
                        }
                        if (string.IsNullOrEmpty(s) && (Options & RowsetOptions.IgnoreEmpty) == RowsetOptions.IgnoreEmpty)
                        {
                            continue;
                        }

                        Vars r = new Vars();
                        r[string.Empty] = s;

                        Context.CheckAbort();

                        yield return(r);
                    }
                }
                else
                {
                    // We have columns, and therefore a complete CSV
                    string[] data;
                    while ((data = Utils.ReadCsvRow(csvReader, quoteChar, separator[0], trim)) != null)
                    {
                        if ((Options & RowsetOptions.IgnoreEmpty) != 0 && (data.Length == 0 || (data.Length == 1 && data[0].Length == 0)))
                        {
                            continue;
                        }
                        rowNo++;

                        if (data.Length > ci.Count)
                        {
                            throw new ScriptRuntimeException(string.Format("{0} columns expected in row #{1}, but {2} found.",
                                                                           ci.Count, rowNo, data.Length));
                        }
                        Vars r = new Vars();
                        for (int i = 0; i < Math.Min(ci.Count, data.Length); ++i)
                        {
                            object o = Context.Transform(data[i], Verbatim ? TransformRules.None : Transform);
                            if (i < ci.Count)
                            {
                                r[ci[i].Name] = ci[i].AdjustType(o);
                            }
                            else
                            {
                                r[ci[i].Name] = o;
                            }
                        }

                        ci.ApplyDefaults(r);
                        Context.CheckAbort();

                        var c = checkWhere(r);
                        if (c == null)
                        {
                            yield break;
                        }
                        if (c.Value)
                        {
                            yield return(r);
                        }
                    }
                }
            }

            // Rowset ID
            string id = Context.TransformStr(RowsetId, Transform);

            if (!string.IsNullOrEmpty(id))
            {
                var rs = Context.Find <RowSet>(id, true);
                foreach (var v in rs.GetData())
                {
                    rowNo++;
                    Vars sv1 = null;
                    if (ci.Count == 0)
                    {
                        sv1 = v;
                    }
                    else
                    {
                        sv1 = new Vars();
                        Context.ExecuteWithVars(() =>
                        {
                            foreach (var col in ci)
                            {
                                sv1.Set(col.Name, col.AdjustType(v.GetOrDefault(col.Name, null)));
                            }
                            return(null);
                        }, v, null);
                    }
                    ci.ApplyDefaults(sv1);
                    Context.CheckAbort();

                    var c = checkWhere(sv1);
                    if (c == null)
                    {
                        yield break;
                    }
                    if (c.Value)
                    {
                        yield return(sv1);
                    }
                }
            }

            // Try XmlDoc
            id = Context.TransformStr(XmlDocId, Transform);
            if (!string.IsNullOrEmpty(id))
            {
                XmlDoc doc = Context.Find <XmlDoc>(id, true);
                foreach (XmlNode n in doc.Nodes(Context.TransformStr(XPath, Transform)))
                {
                    Vars sv = new Vars();
                    rowNo++;
                    if (ci.Count > 0)
                    {
                        foreach (var col in ci)
                        {
                            var node = n.SelectSingleNode(col.Value);
                            if (node != null)
                            {
                                sv[col.Name] = col.AdjustType(node.Value);
                            }
                        }
                    }
                    else
                    {
                        foreach (XmlAttribute attr in n.Attributes)
                        {
                            sv[attr.LocalName] = attr.Value;
                        }
                        sv[string.Empty] = n.InnerText;
                    }
                    ci.ApplyDefaults(sv);
                    Context.CheckAbort();

                    var c = checkWhere(sv);
                    if (c == null)
                    {
                        yield break;
                    }
                    if (c.Value)
                    {
                        yield return(sv);
                    }
                }
            }

            foreach (var row in Rows)
            {
                rowNo++;
                Vars sv = new Vars();
                foreach (Var v in row)
                {
                    var val = (Verbatim) ? v.Value : Context.Transform(v.Value, Transform);
                    sv.Set(v.Name, ci.AdjustType(v.Name, val));
                }
                ci.ApplyDefaults(sv);
                Context.CheckAbort();

                var c = checkWhere(sv);
                if (c == null)
                {
                    yield break;
                }
                if (c.Value)
                {
                    yield return(sv);
                }
            }
        }
Пример #18
0
        private object expandVars(TransformRules rules, string s)
        {
            string begin;
            string end;

            if ((rules & TransformRules.ExpandDual) == TransformRules.ExpandDual)
            {
                begin = "${{";
                end   = "}}";
            }
            else if ((rules & TransformRules.ExpandDualSquare) == TransformRules.ExpandDualSquare)
            {
                begin = "[[";
                end   = "]]";
            }
            else if ((rules & TransformRules.ExpandSquare) == TransformRules.ExpandSquare)
            {
                begin = "[";
                end   = "]";
            }
            else if ((rules & TransformRules.Expand) == TransformRules.Expand)
            {
                begin = "${";
                end   = "}";
            }
            else
            {
                return(s);
            }

            if (s.IndexOf(begin, StringComparison.Ordinal) != -1)
            {
                StringBuilder sbNew = new StringBuilder();
                using (var sr = new ParsingReader(new StringReader(s)))
                {
                    int  ptr   = 0;
                    bool first = true;
                    while (!sr.IsEOF)
                    {
                        char ch = (char)sr.Read();
                        if (ch != begin[ptr])
                        {
                            sbNew.Append(begin, 0, ptr);
                            sbNew.Append(ch);
                            ptr   = 0;
                            first = false;
                            continue;
                        }
                        ptr++;
                        if (ptr < begin.Length)
                        {
                            continue;
                        }
                        if (sr.Peek() == '{' || sr.Peek() == '[')
                        {
                            sbNew.Append(begin);
                            ptr   = 0;
                            first = false;
                            continue;
                        }
                        //
                        object sv = EvalMulti(sr);
                        sv = ((rules & TransformRules.ExpandTrimOnly) == TransformRules.ExpandTrimOnly)
                                 ? Utils.TransformStr(Utils.To <string>(sv), rules & TransformRules.TrimMask)
                                 : sv;
                        sv = ((rules & TransformRules.ExpandReplaceOnly) == TransformRules.ExpandReplaceOnly)
                                 ? Utils.TransformStr(Utils.To <string>(sv), rules & TransformRules.ReplaceMask)
                                 : sv;

                        // Now read the trailing stuff
                        sr.SkipWhiteSpace();
                        for (ptr = 0; ptr < end.Length; ++ptr)
                        {
                            sr.ReadAndThrowIfNot(end[ptr]);
                        }
                        if (sr.IsEOF && first)
                        {
                            return(sv);
                        }
                        ptr   = 0;
                        first = false;
                        sbNew.Append(Utils.To <string>(sv));
                    }
                    for (int i = 0; i < ptr; ++i)
                    {
                        sbNew.Append(begin[i]);
                    }
                }


                return(sbNew.ToString());
            }
            return(s);
        }
Пример #19
0
 /// Read multi-expression (like ${a|b|=3+5}) from the stream and evaluate it
 public object EvalMulti(ParsingReader expressionReader)
 {
     return(Eval(new Parser(TokenSpecialCharacters).ParseMulti(expressionReader)));
 }
Пример #20
0
        /// Parse multi-expression, like ${a|b|=2+3}
        public IOperation ParseMulti(ParsingReader reader)
        {
            Operations.OperationVariableAccess va = new Operations.OperationVariableAccess();
            StringBuilder sb    = new StringBuilder();
            bool          orMet = true;
            int           n;

            while ((n = reader.Peek()) != -1)
            {
                var q = (char)n;
                if (q == '}' || q == ')' || q == ']')
                {
                    break;
                }
                switch (q)
                {
                case '|':
                    reader.Read();
                    va.AddName(sb.ToString());
                    sb.Length = 0;
                    orMet     = true;
                    break;

                case '\'':
                case '\"':
                case '`':
                    orMet = false;
                    if (sb.Length != 0)
                    {
                        reader.ThrowParsingException("Quote must be a first character");
                    }
                    va.AddValue(reader.ReadQuote());
                    reader.SkipWhiteSpaceAndComments();
                    if (reader.Peek() != '}' && reader.Peek() != '|')
                    {
                        reader.ThrowParsingException("Unexpected character '" + (char)reader.Peek() + "'");
                    }
                    sb.Length = 0;
                    break;

                case '=':
                    orMet = false;
                    reader.Read();
                    var v = Parse(reader);
                    if (v != null)
                    {
                        va.AddExpression(v);
                    }
                    else
                    {
                        va.AddValue(null);
                    }
                    break;

                default:
                    orMet = false;
                    sb.Append(q);
                    reader.Read();
                    break;
                }
            }
            if (sb.Length > 0 || orMet)
            {
                va.AddName(sb.ToString());
            }
            return(va);
        }