Exemplo n.º 1
0
        public static StyleDeclaration ParseStyleDeclaration(ITokenStream tokens, bool nested)
        {
            var selector = ParseOrSelector(tokens, nested);
            var current  = tokens.DrainConsume();

            if (!(current is LCurlyToken))
            {
                throw new FormatException($"Unexpected symbol at {tokens.FormatPosition(current)}, '{{' expected.");
            }

            var statements = new List <StylesheetStatement>();

            while (true)
            {
                current = tokens.DrainPeek();
                if (current is RCurlyToken)
                {
                    tokens.DrainConsume();
                    break;
                }

                statements.Add(ParseStatement(tokens));
            }

            return(new StyleDeclaration(selector, statements));
        }
Exemplo n.º 2
0
        public static ScriptDeclaration ParseScriptDeclaration(ITokenStream tokens)
        {
            var token = tokens.DrainConsume();

            if (!(token is ScriptToken scriptToken))
            {
                throw new FormatException($"Expected script at {tokens.FormatPosition(token)}.");
            }

            return(new ScriptDeclaration(scriptToken.Value));
        }
Exemplo n.º 3
0
        public static StylesheetStatement ParseStatement(ITokenStream tokens)
        {
            var zero = tokens.DrainPeek();

            if (zero is ScriptToken scriptToken)
            {
                return(ParseScriptDeclaration(tokens));
            }

            var one = tokens.PeekOnly(t => !(t is WhitespaceToken), 1);

            if (one is ColonToken)
            {
                tokens.Consume();
                tokens.DrainConsume();

                string key;
                switch (zero)
                {
                case IdentifierToken id:
                    key = id.Value;
                    break;

                case StringToken str:
                    key = str.Value;
                    break;

                default:
                    throw new FormatException($"Expected an identifier or string at {tokens.FormatPosition(zero)}.");
                }

                var stringBuilder = new StringBuilder();
                var ws            = false;
                var counter       = 0;
                foreach (var t in tokens
                         .ConsumeUntil(t => t is SemiColonToken))
                {
                    switch (t)
                    {
                    case IdentifierToken id:
                        stringBuilder.Append(id.Value);
                        counter++;
                        ws = false;
                        continue;

                    case StringToken str:
                        stringBuilder.Append(str.Value);
                        counter++;
                        ws = false;
                        continue;

                    case WhitespaceToken _:
                        if (counter > 0 && !ws)
                        {
                            stringBuilder.Append(" ");
                        }

                        ws = true;
                        continue;

                    default:
                        throw new FormatException($"Invalid value at {tokens.FormatPosition(t)}.");
                    }
                }

                if (counter == 0)
                {
                    throw new FormatException($"Expected an assigned value to {tokens.FormatPosition(zero)}.");
                }

                tokens.Consume();
                if (ws)
                {
                    stringBuilder.Remove(stringBuilder.Length - 1, 1);
                }

                return(new AssignmentStatement(key, stringBuilder.ToString()));
            }

            return(ParseStyleDeclaration(tokens, true));
        }