User:S Moeen/sandbox

نمایش میانی داده‌ساختار و یا کدی است که کامپایلر یا ماشین مجازی کد کاربر را پس از پردازش به آن تبدیل می‌کند و در نهایت به کد اسمبلی تبدیل می‌‌شود. می‌توان از نمایش میانی استفاده نکرد و کد کاربر را مستقیما به نمایش مقصد تبدیل کرد اما از نمایش میانی برای ساده کردن برخی از تغییرات در کد، مانند ترجمه به نمایش اسمبلی و بهینه سازی، استفاده می‌شود. نمایش میانی باید بتواند بدون از دست دادن اطلاعات کد مبدا را توصیف کند و بتواند به راحتی و به نمایش مقصد تبدیل شود.

از آنجایی که نمایش میانی نمایش درونی کامپایلر است، هیچ‌گاه کاربر برنامه‌ساز با آن ارتباطی ندارد، پس نیازی نیست که نمایش میانی از ساخت‌های پیچیده که برنامه‌نویسی را برای کاربر برنامه ساز آسان می‌کنند بهره‌ای ببرد. این ساده‌سازی راه را برای بهینه‌سازی بهتر کد باز می‌کند.

عملیات یک کامپایلربه دو مرحله‌ٔ کلی اولیه و ثانویه تقسیم می‌شود. در مرحله‌ٔ اولیه پس از پردازش کد کاربر، کد به نمایش میانی برده می‌شود و در مرحله‌ٔ دوم کد از نمایش میانی به نمایش مقصد برده می‌شود. در صورتی که ویژگی‌های نمایش میانی مستقل از نمایش کاربر باشد، می‌توان از مرحلهٔ دوم مشترکی برای کامپایلرهای مختلف استفاده کرد. بنابراین نمایش میانی خوب نمایش میانی‌ای است که مستقل از هر ویژگی نمایش مبدا، و یا مقصد باشد. بنابراین اگر نیاز داشته باشیم n نمایش را به m نمایش ترجمه کنیم، بدون داشتن IR مناسب به mn کامپایلر نیاز داریم اما در صورت داشتن IR مناسب این امر با داشتن n مرحله‌ٔ اولیه و m مرحله‌ٔ ثانویه قابل حل هست.

نمایش میانی می‌تواند اشکال متفاوتی داشته باشد اعم از داده‌ساختاری موجود در رم یا کدی که توسط برنامه خوانده می‌شود که به مورد دوم زبان میانی نیز گفته می‌شود.

اهمیت نمایش میانی
وظیفهٔ ترجمه‌ٔ زبان‌های متفاوت به یکدیگر وظیفه‌ای پیچیده است که با شکسته شدن به دو بخش ساده‌تر می‌شود و می‌تواند بهتر صورت بپذیرد.

زبان میانی مناسب سطح‌ معنایی‌ای نزدیک به اسمبلی دارد و باید بتواند با حفظ معنا در مسیر تبدیل کد مبدا به کد مقصد ( که عموما کد اسمبلی است ) قرار بگیرد. نمایش میانی‌ای که به درستی این خاصیت را داشته باشد می‌تواند به ماجولاریتی کامپایلر کمک کند. در همچنین شرایطی کامپایلر به دو بخش کلی عقب و جلو تقسیم می‌شود که کارشان از یکدیگر مجزا است. با رخ دادن این جدایی در کامپایلر می‌توان علاوه بر بهره بردن از طراحی ساده‌تر و قابل‌ نگه‌داری‌تر، از یک کد چند بار استفاده کرد و به این صورت هزینهٔ توسعه‌ٔ کامپایلرها را کاهش داد. بخش جلو که وظیفه‌ٔ ترجمه‌ٔ دقیق حافظ معنا از زبان مبدا به نمایش میانی را بر عهده دارد تنها به زبان مبدا وابسته است و کاملا از بخش عقب که وظیفه‌ٔ ترجمه‌ دقیق از نمایش میانی به زبان مقصد را برعهده دارد و به زبان مقصد وابسته است جداست. بنابراین می‌تواند برای زبان‌های مبدا و مقصد متفاوت به صورت مجزا بخش عقب و جلو را طراحی کرد و در نهایت به یکدیگر متصلشان کرد. از آنجایی که زبان مقصد عموما زبان ماشین است عموما بخش عقب به زبان ماشین وابسته است.

با طراحی بخش‌های عقب متفاوت برای هر ماشین می‌توان زبان مبدا را به صورت مجزا از طراحی داخلی ماشین، بر روی ماشین‌های مختلف اجرا کرد و برای زبان‌های برنامه‌نویسی جدید تنها کافی است که با طراحی بخش جلو زبان مبدا به نمایش میانی تبدیل شود و مابقی مسیر با بخش‌های عقبی که پیش از این وجود داشته است طی خواهد شد.

دوری نمایش میانی از زبان مبدا و سادگی ذاتی آن زمینه را برای بهینه‌سازی کد فراهم می‌کند که نمایش میانی را تبدیل به یکی از مهمترین پیش‌نیازهای بهینه‌سازی مناسب می‌کند و با گسترش استفاده‌ از یک نمایش میانی و استاندارد شدن آن زمینه‌ برای بهبود پردازشگران شرکت‌های مختلف در سایه‌‌ٔ این دانش فراهم می‌شود. نمایش میانی استاندارد می‌تواند به حل مشکل سازگاری نرم‌افزارها کمک کند. همچنین نمایش میانی استاندارد می‌تواند به بهبود روش‌های بهینه‌سازی کد با متمرکز کردن گروه‌های مختلف بر یک مساله بیانجامد.

در حل مسائل توزیع شده نیز نمایش میانی به عنوان کدی مجزا از پلتفرم می‌تواند مورد استفاده قرار بگیرد و بر روی تمامی کامپیوترهای مجموعه اجرا شود.

نمایش میانی در برابر زبان میانی
در گونه‌های متفاوت کامپایلرها نمایش‌میانی چهره‌های متفاوتی به خود می‌گیرد. در صورتی که بخش عقب به عنوان یک زیرکد توسط بخش جلو صدا زده بشود احتمالا نمایش میانی یک درخت تجزیه‌ٔ علامت‌گزاری شده به همراه جدول مربوطه خواهد بود اما در صورتی که بخش عقب برنامه‌ای مجزا از بخش جلو باشد، احتمالا نمایش میانی زبان ماشینی مجازی است که زبان میانی نام دارد. به دلیل جدایی بیشتر و بیشتر میان بخش عقب و بخش جلو به مرور زمان نمایش‌های میانی تبدیل به زبان میانی شده‌اند.

ویژگی‌های نمایش میانی

 * کامل بودن
 * نمایش میانی باید بتواند نمایشی کامل و تمیز از ویژگی‌های زبان مبدا برای تبدیل دقیق به زبان مقصد ارائه دهد.
 * فاصله‌ٔ معنایی
 * فاصله‌ٔ معنایی نمایش میانی با زبان مبدا باید آنقدر زیاد باشد که با استفاده از کد نمایش میانی نتوان کد زبان مبدا را به دست آورد به این طریق حفظ مالکیت معنوی برنامه‌ها آسان‌تر می‌شود.
 * بی‌توجهی به سخت‌افزار
 * نمایش میانی نباید هیچ پیش‌فرض و بایاسی در مورد سخت‌افزار مورد استفاده داشته باشد. این مساله به این معنا است که زبان میانی نمی‌تواند خیلی سطح پایین باشد اما در عوض تضمین می‌کند که زبان میانی بر روی طیف گسترده‌ای از سخت‌افزار‌ها قابل استفاده باشد.
 * قابلیت برنامه‌نویسی دستی
 * برنامه‌نویس باید بتواند همانگونه که به صورت دستی کد اسمبلی را تولید می‌کند و تغییر می‌دهد نمایش‌میانی را نیز تولید کند و تغییر بدهد. این مساله به بهینه‌سازی کد توسط کاربر برنامه‌ساز کمک می‌کند و در زمان توسعه‌ٔ کامپایلر به توسعه‌دهندگان کامپایلر امکان تست و برنامه‌سازی را می‌دهد.
 * گسترش‌پذیری
 * با پیشرفت تکنولوژی و به وجود آمدن تکنولوژی‌ها و پارادایم‌های جدید نیاز به گسترش و توسعه‌ٔ زبان برنامه برنامه‌نویسی نیز به وجود می‌آید. ساختار نمایش میانی مناسب باید به گونه‌ای باشد که بدون به وجود آوردن مشکلات سازگاری برای برنامه‌های مطابق با نسخه‌های پیشین بتواند تغییرات را بپذیرد و رو به جلو حرکت کند.
 * سادگی
 * هرچه نمایش میانی از ساختارهای کمتری پشتیبانی کند کد آن تنوع کمتری خواهد داشت که فرایند بهینه‌سازی را برای کامپایلر ساده می‌کند و دیگر طراح نیازی به در نظر گرفتن حالات متفاوت پیچیده برای بهینه‌سازی ندارد.
 * حفظ اطلاعات برنامه
 * کد منبع اطلاعات کامل برنامه را در خود دارد که با هر مرحله ترجمه مقدار از آن از دست می‌رود. نمایش میانی مناسب نمایشی است که علاوه بر حفظ اطلاعات لازم برای اجرای برنامه، اطلاعات لازم برای بهینه‌سازی برنامه را نیز در خود نگه‌دارد.

انواع مختلف نمایش میانی
نمایش میانی انواع مختلفی دارد که به دو دسته‌ٔ کلی داده ساختار‌ها و زبان میانی تقسیم می‌شوند. داده‌ساختارها عموما به صورت گراف و یا درخت به همراه توضیحات مربوطه که در جدول قرار دارند هستند. گراف معنا و گراف کنترل جریان از این دسته به شمار می‌آیند. زبان میانی نیز زبان یک ماشین فرضی است که عمدتا به صورت پشته‌ای و یا سه آدرسه است.

نمایش میانی می‌تواند سطوح مختلفی داشته باشد. در مثال زیر سه نمایش میانی در سه سطح متفاوت برای یک قطعه کد نمایش‌ داده‌ شده اند.

قطعات کد به ترتیب نشانگر سطح بالا، سطح میانی و سطح پایین هستند.

در سطح بالا ساختار زبان منبع به صورت صریح حفظ می‌شود، برنامه‌ٔ منبع قابل بازسازی است، عملوندها اشیأ معنادار هستند، آرایه‌ها و محاسبات ساده نمی‌شوند، رجیستری در کار نیست و به زمان اجرای ماشین توجهی نمی‌شود.

در سطح میانی نمایش از زبان و ماشین مستقل است، دیتا به اعداد صحیح و ممیز شناور فروکاسته می‌شود و بهینه‌سازی مستقل از معماری ماشین صورت می‌پذیرد.

در سطح پایین نمایش میانی به معماری ماشین نزدیک است و به معماری وابسته است، تفاوت اندکی با زبان مقصد دارد، درگیر مسائل زمان اجرا مانند مدیریت حافظه است و بهینه‌سازی وابسته به معماری انجام می‌دهد.

مثال‌هایی از زبان میانی

 * java bytecode
 * C: هرچند زبان سی به عنوان زبان میانی طراحی نشده است، نزدیکی آن به زبان ماشین در عین استقلال آن از ماشین سی را به زبان میانی‌ای مناسب تبدیل کرده است.
 * CIL: زبان میانی مشترک ماکروسافت زبان میانی‌ای است که برای استفاده در تمامی کامپایلرهای زبان‌های .Net طراحی شده است.
 * Parrot intermediate representation: زبان میانی پرت برای استفاده در زبان‌های dynamically typed مانند پایتون و پرل طراحی شده است.
 * TIMI
 * O-Code
 * Microsoft P-Code
 * LLVM IR