private static CombinatorType ReadCombinatorType(TokensQueue queue)
 {
     var hasWhite = false;
     while (!queue.Empty) {
         queue.SkipComments();
         var preview = queue.Peek();
         switch (preview.Type) {
             case TokenType.Whitespace:
                 queue.Read();
                 hasWhite = true;
                 break;
             case TokenType.Plus:
                 queue.Read();
                 return CombinatorType.Sibling;
             case TokenType.Greater:
                 queue.Read();
                 return CombinatorType.Child;
             case TokenType.Comma:
                 queue.Read();
                 return CombinatorType.Group;
             case TokenType.OpenCurlyBracket:
             case TokenType.CloseParenthesis:
                 return CombinatorType.Stop;
             default:
                 return hasWhite ? CombinatorType.Descendant : CombinatorType.Combine;
         }
     }
     return CombinatorType.Stop;
 }
示例#2
0
        private static Expression ParseWithPriority(TokensQueue tokens, int priority)
        {
            var left = ParseOperand(tokens);
            Token? whiteToken = null;
            while (!tokens.Empty) {
                tokens.SkipComments();
                var preview = tokens.Peek();
                switch (preview.Type) {
                    case TokenType.Semicolon:
                    case TokenType.CloseParenthesis:
                    case TokenType.ExclamationPoint:
                        return left;
                }

                var tokenPriority = GetPriority(preview.Type);
                if (tokenPriority < priority) {
                    return left;
                }

                switch (preview.Type) {
                    case TokenType.Plus:
                    case TokenType.Minus:
                    case TokenType.Multiply:
                    case TokenType.Divide:
                    case TokenType.Percentage:
                    case TokenType.LeftShift:
                    case TokenType.RightShift:
                    case TokenType.Comma:
                        var token = tokens.Read();
                        left = ProcessBinaryExpression(token, left, tokens);
                        whiteToken = null;
                        break;
                    case TokenType.Whitespace:
                        whiteToken = tokens.Read();
                        break;
                    default:
                        if (whiteToken.HasValue) {
                            left = ProcessBinaryExpression(whiteToken.Value, left, tokens);
                            whiteToken = null;
                            break;
                        }
                        throw new TokenException("unexpected token " + preview.StringValue, preview);
                }
            }

            return left;
        }
        private static SelectorExpression ParseWithPriority(TokensQueue tokens, int priority, SelectorExpression parent = null)
        {
            var left = ParseOperand(tokens, parent);
            while (!tokens.Empty) {
                tokens.SkipComments();
                var preview = tokens.Peek();
                switch (preview.Type) {
                    case TokenType.CloseParenthesis:
                    case TokenType.OpenCurlyBracket:
                        return left;
                }
                var combinatorType = PeekCombinatorType(tokens);

                var tokenPriority = GetPriority(combinatorType);
                if (tokenPriority < priority) {
                    return left;
                }
                combinatorType = ReadCombinatorType(tokens);
                if (combinatorType == CombinatorType.Stop) return left;
                left = ProcessBinaryExpression(combinatorType, left, tokens);
            }

            return left;
        }