Example #1
0
        private ParseErrorType HandleOperator(ParseContext context, out bool isUnary)
        {
            var currentOperator = new TokenOperator(firstInExpression: (_operands.Count == 0));

            currentOperator.Parse(context, null);
            isUnary = currentOperator.IsUnary;

            if (currentOperator.OperatorType == OperatorType.Not)
            {
                //This comes from the fact that
                //  x < -1
                //  y < -1
                //  2 + !x + y
                // yields 2 (i.e. bang applies to the entire expression that follows
                isUnary = true;
                if (!IsInGroup && context.Tokens.IsLineBreakAfter(context.TextProvider, context.Tokens.Position - 1))
                {
                    // Make sure expression that follows is not empty
                    return(ParseErrorType.RightOperandExpected);
                }

                var exp = new Expression(IsInGroup);
                if (!exp.Parse(context, null))
                {
                    return(ParseErrorType.RightOperandExpected);
                }

                _operators.Push(currentOperator);
                _operands.Push(exp);
                return(ParseErrorType.None);
            }
            return(HandleOperatorPrecedence(context, currentOperator));
        }
Example #2
0
        private ParseErrorType HandleOperator(ParseContext context, IAstNode parent, out bool isUnary)
        {
            TokenOperator currentOperator = new TokenOperator(firstInExpression: (_operands.Count == 0));

            currentOperator.Parse(context, null);
            isUnary = currentOperator.IsUnary;

            return(HandleOperatorPrecedence(context, currentOperator));
        }
Example #3
0
        private ParseErrorType HandleOperator(ParseContext context, IAstNode parent, out bool isUnary)
        {
            ParseErrorType errorType = ParseErrorType.None;

            // If operands stack is empty the operator is unary.
            // If operator is preceded by another operator,
            // it is interpreted as unary.

            TokenOperator currentOperator = new TokenOperator(_operands.Count == 0);

            currentOperator.Parse(context, null);
            isUnary = currentOperator.IsUnary;

            IOperator lastOperator = _operators.Peek();

            if (isUnary && lastOperator != null && lastOperator.IsUnary)
            {
                // !!!x is treated as !(!(!x)))
                // Step back and re-parse as expression
                context.Tokens.Position -= 1;
                var exp = new Expression(inGroup: false);
                if (exp.Parse(context, null))
                {
                    _operands.Push(exp);
                    return(ParseErrorType.None);
                }
            }

            if (currentOperator.Precedence <= lastOperator.Precedence &&
                !(currentOperator.OperatorType == lastOperator.OperatorType && currentOperator.Association == Association.Right))
            {
                // New operator has lower or equal precedence. We need to make a tree from
                // the topmost operator and its operand(s). Example: a*b+c. + has lower priority
                // and a and b should be on the stack along with * on the operator stack.
                // Repeat until there are no more higher precendece operators on the stack.

                errorType = this.ProcessHigherPrecendenceOperators(context, currentOperator);
            }

            if (errorType == ParseErrorType.None)
            {
                _operators.Push(currentOperator);
            }

            return(errorType);
        }
Example #4
0
            void Digest(int start, int end)
            {
                // scan tokens
                while (start < end)
                {
                    string s = text.Substring(start, end - start);
                    if (s.StartsWith(")"))
                    {
                        throw new FormatException($"错误的右括号!");
                    }
                    if (s.StartsWith("("))
                    {
                        int bracket = 1;
                        for (int i = 1; i < s.Length; i++)
                        {
                            if (s[i] == ')')
                            {
                                bracket--;
                                if (bracket == 0)
                                {
                                    tokens.Add(Expression.Parse(text, start + 1, start + i));
                                    start += i + 1;
                                    break;
                                }
                            }
                            else if (s[i] == '(')
                            {
                                bracket++;
                            }
                        }
                        if (bracket > 0)
                        {
                            throw new FormatException($"括号未封闭!");
                        }
                        continue;
                    }
                    // operators
                    var ro = TokenOperator.Operators.Find(u => s.StartsWith(u.Simbol));
                    if (ro != null)
                    {
                        tokens.Add(TokenOperator.Parse(ro.Simbol));
                        start += ro.Simbol.Length;
                        continue;
                    }
                    // names and values
                    var m = Regex.Match(s, @"^[\d\p{L}-_]+");
                    if (m.Success)
                    {
                        tokens.Add(new TokenVal(m.Value));
                        start += m.Value.Length;
                        continue;
                    }
                    // error
                    throw new FormatException($"无法解析符号'{s[0]}'");
                }

                // build tree
                List <Token> newTokens = new List <Token>();
                List <Token> list      = new List <Token>();

                foreach (var item in tokens)
                {
                    if (item is TokenLogical)
                    {
                        if (list.Count == 0)
                        {
                            throw new FormatException($"表达式不完整!");
                        }
                        newTokens.Add(new Expression(text, list));
                        newTokens.Add(item);
                        list.Clear();
                    }
                    else
                    {
                        list.Add(item);
                    }
                }
                if (newTokens.Count > 0)
                {
                    if (list.Count == 0)
                    {
                        throw new FormatException($"表达式不完整!");
                    }
                    newTokens.Add(new Expression(text, list));
                    tokens = newTokens;
                }
            }