Ejemplo n.º 1
0
        private static MathValue UnrollMathImpl(MathValue value)
        {
            var tokens = new List<object>();
            Unroll(value, tokens);

            var outQueue = new Queue<object>();
            var opStack = new Stack<Operator>();

            foreach (var t in tokens)
            {
                if (t is Value)
                {
                    if (t is GroupedValue)
                    {
                        var grouped =  UnrollMath(((GroupedValue)t).Value);
                        outQueue.Enqueue(grouped);
                        continue;
                    }

                    if (t is LeftExistsValue)
                    {
                        var leftExist = new LeftExistsValue(UnrollMath(((LeftExistsValue)t).IfExists));
                        outQueue.Enqueue(leftExist);
                        continue;
                    }

                    outQueue.Enqueue((Value)t);
                    continue;
                }

                var o1 = (Operator)t;
                while (opStack.Count > 0 && Precedence(o1) <= Precedence(opStack.Peek()))
                {
                    var o2 = opStack.Pop();
                    outQueue.Enqueue(o2);
                }
                opStack.Push(o1);
            }

            while (opStack.Count > 0)
            {
                outQueue.Enqueue(opStack.Pop());
            }

            return DeRPN(outQueue);
        }
Ejemplo n.º 2
0
        internal static Value ParseImpl(ParserStream stream, IPosition forPosition, bool allowSelectorIncludes)
        {
            Value ret = null;

            while (stream.HasMore())
            {
                var c = stream.Peek();

                if (char.IsWhiteSpace(c))
                {
                    stream.AdvancePastWhiteSpace();
                    continue;
                }

                if (ret != null)
                {
                    if (c.In('+', '-', '*', '/', '%'))
                    {
                        ret = ParseMathValue(c, ret, stream, forPosition);
                        continue;
                    }

                    if (c == '?')
                    {
                        stream.Advance(); // skip ?
                        if (stream.HasMore() && stream.Peek() == '?')
                        {
                            if (ret == null)
                            {
                                Current.RecordError(ErrorType.Parser, forPosition, "Expected value, found '??'");
                                throw new StoppedParsingException();
                            }

                            stream.Advance(); // skip second ?
                            var rhs = ParseImpl(stream, forPosition, allowSelectorIncludes);
                            ret = new MathValue(ret, Operator.Take_Exists, rhs);
                            continue;
                        }

                        ret = new LeftExistsValue(ret);
                        continue;
                    }
                }

                if (char.IsDigit(c) || c == '.' || c == '-')
                {
                    ret = Combine(ret, ParseNumber(stream, forPosition));
                    continue;
                }

                if (c == '(')
                {
                    ret = Combine(ret, ParseGroup(stream, forPosition));
                    continue;
                }

                if (c.In('\'', '"'))
                {
                    ret = Combine(ret, ParseQuotedString(c, stream, forPosition));
                    continue;
                }

                if (c == '#')
                {
                    ret = Combine(ret, ParseHashColor(stream, forPosition));
                    continue;
                }

                if (c == '@')
                {
                    ret = Combine(ret, ParseFuncValue(stream, forPosition, allowSelectorIncludes));
                    continue;
                }

                ret = Combine(ret, ParseString(stream, forPosition));
            }

            return ret;
        }