Пример #1
0
 private static int GetHexChar(ref Token token, int index)
 {
     var ch = token.StringValue[index];
     if (ch >= '0' && ch <= '9') return ch - '0';
     if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
     if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
     throw new TokenException("invalid hex color", token);
 }
Пример #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
 private static SelectorExpression ParseAttributeSelector(Token token, TokensQueue tokens)
 {
     var attrName = tokens.Read(TokenType.Literal).StringValue;
     var operation = tokens.Read();
     if (operation.Type == TokenType.CloseSquareBracket) return new AttributeExistsSelector(attrName);
     if (operation.Type == TokenType.Equal) {
         var val = tokens.Read();
         if (val.Type != TokenType.Literal && val.Type != TokenType.String) {
             throw new TokenException("expected literal or string token", val);
         }
         tokens.Read(TokenType.CloseSquareBracket);
         return new AttributeEqualsSelector(attrName, val.StringValue);
     }
     throw new TokenException("unknown attribute operator", operation);
 }
Пример #4
0
 protected static Expression Func(Token nameToken, TokensQueue tokens)
 {
     tokens.Read(TokenType.OpenParenthesis);
     var args = ParseArguments(tokens);
     tokens.Read(TokenType.CloseParenthesis);
     switch (nameToken.StringValue.ToLower()) {
         case "round":
             if (args.Count != 1) {
                 throw new TokenException("expected 1 argument", nameToken);
             }
             return new RoundFunctionExpression(args.First());
         default:
             throw new TokenException("unknown function " + nameToken.StringValue, nameToken);
     }
 }
Пример #5
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);
 }
Пример #6
0
 private static Expression ParseHashColor(ref Token token, TokensQueue queue)
 {
     var val = queue.Read(TokenType.Literal);
     if (val.StringValue.Length == 6) {
         var rh = GetHexChar(ref val, 0);
         var rl = GetHexChar(ref val, 1);
         var gh = GetHexChar(ref val, 2);
         var gl = GetHexChar(ref val, 3);
         var bh = GetHexChar(ref val, 4);
         var bl = GetHexChar(ref val, 5);
         return new ColorExpression(rh * 16 + rl, gh * 16 + gl, bh * 16 + bl);
     }
     if (val.StringValue.Length == 3) {
         var rhl = GetHexChar(ref val, 0);
         var ghl = GetHexChar(ref val, 1);
         var bhl = GetHexChar(ref val, 2);
         return new ColorExpression(rhl * 17, ghl * 17, bhl * 17);
     }
     throw new TokenException("invalid hex color", token);
 }
Пример #7
0
 private static Expression ProcessBinaryExpression(Token opToken, Expression left, TokensQueue tokens)
 {
     var tokenPriority = GetPriority(opToken.Type);
     var other = ParseWithPriority(tokens, tokenPriority + 1);
     switch (opToken.Type) {
         case TokenType.Plus: return new AddExpression(left, other);
         case TokenType.Minus: return new SubExpression(left, other);
         case TokenType.Multiply: return new MulExpression(left, other);
         case TokenType.Divide: return new DivExpression(left, other);
         case TokenType.Percentage: return new ModExpression(left, other);
         case TokenType.Whitespace:
             if (left is SpaceGroupExpression) {
                 return ((SpaceGroupExpression)left).Add(other);
             }
             return new SpaceGroupExpression(left, other);
         case TokenType.Comma:
             if (left is CommaGroupExpression) {
                 return ((CommaGroupExpression)left).Add(other);
             }
             return new CommaGroupExpression(left, other);
         default:
             throw new TokenException("unexpected operator " + opToken.Type, opToken);
     }
 }
Пример #8
0
 private static CssValueType ParseUnit(ref Token token)
 {
     switch (token.StringValue) {
         case "px": return CssValueType.Pixel;
         case "em": return CssValueType.Em;
         case "rem": return CssValueType.Rem;
         case "in": return CssValueType.Inch;
         case "cm": return CssValueType.Centimeter;
         case "%": return CssValueType.Percentage;
         case "vh": return CssValueType.ViewportHeight;
         case "vw": return CssValueType.ViewportWidth;
         default:
             throw new TokenException("invalid unit", token);
     }
 }
Пример #9
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;
 }
Пример #10
0
 protected virtual bool AcceptToken(ref Token token)
 {
     return false;
 }
Пример #11
0
 protected static SelectorExpression ParseTypeSelector(Token token, TokensQueue queue)
 {
     return new TypeSelector(token.StringValue);
 }
Пример #12
0
 protected static SelectorExpression ParseIdSelector(Token token, TokensQueue queue)
 {
     var next = queue.Read(TokenType.Literal);
     return new IdSelector(next.StringValue);
 }
Пример #13
0
 public Token Read()
 {
     LastReadToken = _queue[_index++];
     return LastReadToken;
 }
Пример #14
0
 public CommentNode(Token token)
 {
     Token = token;
 }
Пример #15
0
 private static Token ParseWhitespace(TokenizerContext context)
 {
     var originalPos = context.Position;
     var len = context.File.Content.Length;
     var position = context.CreatePosition();
     while (context.Position < len) {
         var ch = context.File.Content[context.Position++];
         if (ch == '\r' || ch == '\n') {
             if (context.Position < len) {
                 var nextCh = context.File.Content[context.Position];
                 if ((nextCh == '\r' || nextCh == '\n') && nextCh != ch) {
                     context.Position++;
                 }
             }
             context.IncrementLine();
         } else if (ch == ' ' || ch == '\t') {
         } else {
             context.Position--;
             break;
         }
     }
     var res = new Token {
         Type = TokenType.Whitespace,
         StringValue = context.File.Content.Substring(originalPos, context.Position - originalPos),
         Position = position
     };
     return res;
 }
Пример #16
0
 public TokenException(string message, Token token)
     : base($"{message} at line: {token.Position.Line}, column: {token.Position.Column}")
 {
     Token = token;
 }