Пример #1
0
 public static IList<Expression> ParseArguments(TokensQueue tokens)
 {
     var res = new List<Expression>();
     while (!tokens.Empty) {
         var preview = tokens.Peek();
         if (preview.Type == TokenType.CloseParenthesis) return res;
         var arg = Parse(tokens);
         res.Add(arg);
         preview = tokens.Peek();
         if (preview.Type != TokenType.Comma) break;
         tokens.Read(TokenType.Comma);
     }
     return res;
 }
Пример #2
0
 protected static Expression ParseLiteral(ref Token token, TokensQueue queue)
 {
     if (!queue.Empty) {
         var preview = queue.Peek();
         if (preview.Type == TokenType.OpenParenthesis) {
             return Func(token, queue);
         }
     }
     return new LiteralExpression(token.StringValue);
 }
Пример #3
0
 protected static SelectorExpression ParsePseudoSelector(Token token, TokensQueue queue)
 {
     var next = queue.Read(TokenType.Literal);
     if (next.StringValue == "not") {
         var preview = queue.Peek();
         if (preview.Type == TokenType.OpenParenthesis) {
             queue.Read(TokenType.OpenParenthesis);
             var expr = Parse(queue);
             if (!(expr is SimpleSelector)) throw new TokenException("simple selector expected", preview);
             queue.Read(TokenType.CloseParenthesis);
             return new NotExpression((SimpleSelector)expr);
         }
     }
     return new PseudoClassSelector(next.StringValue);
 }
Пример #4
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;
        }
Пример #5
0
 private static Expression ParseNumber(ref Token token, TokensQueue queue)
 {
     var inner = new NumberExpression(token.NumberValue);
     if (!queue.Empty) {
         var preview = queue.Peek();
         if (preview.Type == TokenType.Literal || preview.Type == TokenType.Percentage) {
             var unitToken = queue.Read();
             var unit = ParseUnit(ref unitToken);
             return new UnitExpression(inner, unit);
         }
     }
     return inner;
 }
Пример #6
0
 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;
 }
Пример #7
0
        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;
        }