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