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; }
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; }