موضوع مقاله: کامپایلر | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # کامپایلر | مقدمه: همگردان یا مترجم برنامه یا مجموعه‌ای از برنامه‌های رایانه‌ای است که متنی از زبان برنامه‌نویسی سطح بالا (زبان مبدأ) را به زبانی سطح پایین (زبان مقصد)، مانند زبان اسمبلی یا زبان ماشین، تبدیل می‌کند. | ## بخش 1: کامپایلر | خروجی این برنامه ممکن است برای پردازش شدن توسط برنامه دیگری مانند پیونددهنده مناسب باشد یا پرونده متنی باشد که انسان نیز بتواند آن را بخواند. به برنامه‌ای که زبان برنامه‌نویسی سطح پایین را به بالاتر تبدیل می‌کند مترجم‌وارون گفته می‌شود. ترجمه کامل کد منبع برنامه‌ای از یک زبان سطح بالا به کد شیء، پیش از اجرای برنامه را هم‌گردانی یا کامپایل می‌گویند. در یکی از مهم‌ترین پروسه‌های این تبدیل، کامپایلر وجود خطا را در برنامه مبدأ اعلام می‌نماید. تعداد بسیار زیادی زبان‌های منبع وجود دارند که دامنه آن‌ها از زبان‌های شناخته‌شده مانند فرترن و پاسکال تا زبان‌های خاص منظوره گسترده است. کامپایلرها به انواع تک‌گذره، چندگذره، باردهی و اجرا، بهینه‌ساز، غلط‌یاب و … بسته با عمل انجام‌شده تقسیم می‌شوند. علی‌رغم این تنوع اعمال اساسی که هر کامپایلر بایستی انجام دهد، مشابه هم می‌باشند. دانسته‌های ما دربارهٔ سازمان‌بندی و نوشتن کامپایلر نسبت به زمانی که اولین کامپایلرها در اوایل دهه ۱۹۵۰ ایجاد شدند، بسیار افزایش یافته است. برآورد تاریخ دقیق ساخت نخستین کامپایلر عمل آسانی نیست، زیرا گروه‌های متفاوتی نسبت به ساخت کامپایلرها در آن زمان اقدام نموده‌اند. اولین کارهایی که در ساخت کامپایلرها انجام شد، تبدیل فرمول‌های ریاضی به زبان ماشین بود. از آن زمان روش‌های سیستماتیک برای استفاده از بسیاری اعمال مهم حین عمل کامپایل ابداع شده است. همچنین زبان‌های پیاده‌سازی خوب، محیط‌های برنامه‌نویسی و ابزارهای نرم‌افزاری مناسب ایجاد شده‌اند. با کمک این پیشرفت‌ها یک کامپایلر را می‌توان حتی به عنوان پروژه درسی در یک ترم تحصیلی دانشجویی طراحی کرد. تاریخچه در اواخر دهه ۱۹۵۰ میلادی ماشین‌های دارای زبان‌های برنامه‌نویسی رواج یافتند و کامپایلرهای آزمایشی ایجاد شدند. زبان فرترن به سرپرستی جان باکوس در شرکت آی‌بی‌ام به عنوان اولین کامپایلر کامل در سال ۱۹۵۷ تولید شد. در طی دهه ۶۰ کامپایلرهای زیادی تولید شد، اما بر روی کیفیت کامپایلرها کمتر فکر می‌شد. هم‌زمان با تکامل زبان‌های برنامه‌سازی و افزایش قدرت کامپیوترها، کامپایلرها هرچه بیشتر پیچیده می‌شدند. در دهه ۷۰ از زبان‌های سطح بالایی مثل پاسکال و سی جهت نوشتن کامپایلرها استفاده شد. ساخت کامپایلرهای خودمحور دارای مشکل راه‌اندازی است، چون هر کامپایلری باید توسط کامپایلر نوشته‌شده‌ای به زبان دیگر کامپایل شود یا برای این مشکل دست به دامن مفسری بشود. ساختار کامپایلرها و کامپایلر بهینه‌ساز امروزه بخشی از برنامه درسی دانشجویان کامپیوتر است. | ## بخش 2: کامپایلر | به علت سادگی و دلایل زیر هنوز برای آموزش مورد استفاده قرار می‌گیرد: توسعه گام به گام برنامه به‌کارگیری پارسرهای بازگشتی استفاده از EBNF جهت تعریف نحو زبان استفاده از P-Code در جریان تولید کد خروجی قابل حمل نمایش T-diagram جهت تعارف رسمی در تاریخچه کامپایلر سه دوره می‌توان در نظر گرفت: از ۱۹۴۵تا۱۹۶۰:تولید کد(m.h.sزبان ماشیی) در این دوره، زبان‌ها به تدریج به وجود آمدند و ماشین‌ها چندان متعارف نبودند. طرفداران زبان‌های سطح بالا می‌ترسیدند که کد تولیدشده نسبت به زبان اسمبلی کارایی چندان نداشته باشد. از ۱۹۶۰تا۱۹۷۵:تجزیه کردن در دهه‌های ۱۹۶۰و۱۹۷۰ زبان‌های برنامه‌سازی جدید به وجود آمدند و طراحان زبان معتقد بودند که طراحی سریع کامپایلر برای زبان جدید، مهم‌تر از وجود کامپایلری با کد کارآمد است. در همین زمان، مطالعه زبان‌های رسمی، تکنیک‌های قدرتمندی را برای ساخت پردازشگر جلوی، به‌خصوص تولید تجزیه‌کننده به وجود آورد. از ۱۹۷۵ تاکنون:تولید کد و بهینه‌سازی کد از ۱۹۷۵ تاکنون، تعداد زبان‌های جدید و انواع ماشین مختلف کاهش یافت در نتیجه نیاز به کامپایلرهای سریع و ساده یا سریع و ناقص برای زبان‌ها یا ماشین‌های جدید، کاهش یافت. بزرگ‌ترین آشفتگی در طراحی زبان و ماشین خاتمه یافت و افراد خواستار کامپایلرهای قابل اعتماد، کارآمد و با واسط کاربر مناسب شدند. بدین‌ترتیب، توجه کیفی به کد بیشتر شد، زیرا با تغییر اندکی که در ساختار ماشین‌ها ایجاد می‌شود، طول عمر کدها افزایش می‌یابد. در همین دوره، مدل‌هایی در برنامه‌نویسی به وجود آمدند که برنامه‌نویسی تابعی، منطقی و توزیعی نمونه‌های از این مدل‌ها هستند، خواسته‌های زمان اجرای این زبان‌ها نسبت به زبان‌های دستور، افزایش یافت. انواع کامپایلرها راه‌های مختلفی برای دسته‌بندی کامپایلرها وجود دارد، مثلاً می‌توان آن‌ها را با توجه به ورودی، خروجی، ساختار داخلی یا رفتار زمان اجرای آن تقسیم‌بندی کرد. کامپایلرهایی که به منظور اجرای برنامه‌ها کدهای باینری را تولید می‌کنند، کامپایلرهایی با کد محلی یا Native گوییم چرا که تنها در کامپیوترهای یک نوع با سیستم‌عاملهای یکسان قابل به‌کارگیری است. از طرف دیگر ممکن است کامپایلرها کدهای باینری را تولید کنند که در سیستم‌های مختلف قابل اجرا باشد. به این دسته از کامپایلرها که وابستگی به سخت‌افزار ندارند، کامپایلرهای عبوری یا Cross گوییم. برای این نوع کامپایلرها تنها کافی است برای بار اول سخت‌افزار را به آن معرفی نمود؛ بنابراین می‌توان نتیجه گرفت که کامپایلرهای عبوری مفیدتر هستند. این تقسیم‌بندی برای مفسرها به کار نمی‌رود زیرا آن‌ها از نمایش دودویی برای اجرای کد خود استفاده نمی‌کنند. هر گاه در ماشین‌های مجازی یکسان قابل اجرا باشد می‌توان آن را Native و هرگاه کامپایلر قادر به تولید خروجی برای پلتفرم‌های مختلف باشد، آن را Cross گوییم. در نتیجه کامپایلرها به مجموعه برنامه‌های کوچک‌تر تقسیم می‌شوند هر یک بخشی از عمل ترجمه یا آنالیز را برعهده می‌گیرند. اما مشکل اینجا است که اگر اعلان جلوتر از دستور به‌کارگیری باشد، چه کار باید کرد؟ برای حل این مشکل می‌توان در فاز اول اعلان‌ها را مشخص کرد و در فاز بعد عمل ترجمه را انجام داد. دستور برخی زبان‌ها به گونه‌ای است که تولید همگردان یک‌گذره برای آن‌ها غیرممکن است. تقسم بندی کامپایلرها به برنامه‌های کوچکتر تکنیکی است که همچنان مورد بحث محققان است. | ## بخش 3: کامپایلر | در این نوع دسته‌بندی کامپایلرها، انواع دیگری نیز وجود دارد: کامپایلر مبدأ به مبدأ که کدی با زبان سطح بالا را دریافت می‌کند و خروجی آن نیز زبان سطح بالا می‌باشد؛ مثلاً موازی‌سازی خودکار کامپایلر در مواردی که به‌طور تکراری در برنامه ورودی وجود دارد و سپس تغییر شکل‌دادن کد و نوشتن کد یا ساختار زبانی موازی (برابر) با آن. کامپایلر Stage که به زبان اسمبلی برای ماشین نظری ترجمه می‌کند؛ مثلاً در پرولوگ ماشین پرولوگ معمولاً ماشین انتزاعی (WAM) خوانده می‌شود. زبان‌های تفسیری و کامپایلی(m.h.sزبان ماشیی بسیاری از افراد زبان‌های سطح بالا (m.h.sزبان ماشیی) را به دو دسته تفسیری و کامپایلی تقسیم می‌کنند. اما ممکن است نمونه‌هایی از BASIC یا C ارائه شود که به ترتیب کامپایلری و تفسیری باشد. البته استثناهایی نیز وجود دارد، مثلاً برخی زبان‌ها در خصوصیات خود این تقسیم‌بندی را مشخص کرده‌اند(C کامپایلری است یا SNOBOL۴ و اکثر زبانهای اسکریپتی که کد منبع زمان اجرا دارند تفسیری می‌باشد). در این پروژه اصطلاحات جلو بندی، میان بندی (امروزه به ندرت به کار می‌رود) و عقب بندی معرفی شد. استفاده از جلوبندی و عقب بندی این را ممکن می‌کند که جلوبندی‌های مختلفی برای زبان‌های مختلف وجود داشته باشد و عقب بندی‌های مختلفی نیز برای CPUهای مختلف. جلوبندی معمولاً جدول نمادها را مدیریت نموده و یک نگاشت گر ساختمان داده‌ای، هر نماد را از درون کد مبدأ به اطلاعات مربوط به آن مثل نوع و دامنه تعریف آن نگاشت خطی می‌شود. زبان‌هایی که اجازه تعیین فضای اختیاری برای شناسه‌ها را می‌دهند قبل از عمل تجزیه نیاز به فاز اضافی دارند که کد ورودی را به صورت متعارفی برای تجزیه گر آماده کند. برخی زبان‌ها همچون C احتیاج به فاز پیش پردازش برای جایگزینی شروط کامپایل و ماکروها دارند. تحلیل لغوی کد متنی مبدأ را به اجزای کوچکی که نشانه(token) نامیده می‌شود می‌شکند. نحو نشانه‌ها نوعاً یک زبان باقاعده است، بنابراین یک ماشین حالت متناهی که برپایه یک عبارت باقاعده بنا می‌شود می‌تواند جهت شناخت آن استفاده شود. اما می‌توان گفت که عقب بندی به مراحل چند گانه زیر تقسیم می‌شود: تحلیل کامپایلر: این پروسه برای بدست آوردن اطلاعات بیشتر از نمایش میانی فایل‌های ورودی می‌باشد. تحلیلگر نوعی تعاریف مختلفی دارد همچون تحلیلگر حلقوی، تحلیلگر وابسته، تحلیلگر مستعار، تحلیلگر اشاره‌ای یا غیره می‌باشد. بهینه‌سازی: نمایش میانی زبان به معادل‌های پر سرعت تر با شکل‌های کوتاه تری تبدیل می‌گردد. از بهینه‌سازهای محبوبتر می‌توان به موارد زیر اشاره نمود: توسعه درون خطی، حذف کدهای مرده، انتشار ثوابت، تبدیل حلقه‌ها، تخصیص‌های ثباتی و موازی‌سازی خودکار. «البته در ابتدای امر که دربارهٔ زبان‌های تفسیری و کامپایلری گفته بودند باید خاطر نشان کرد که زبان‌های تفسیری خط به خط خوانده شده و اجرا می‌گردد در حالیکه در کامپایلری ابتدا تمام برنامه ترجمه شده و سپس اجرا می‌گردد پس در زمان اجرا سرعت اجرا شدن زبان‌های کامپایلری بیشتر است. پدید آورنده اصلی GCC ریچارد استالمن است کسی که بنیان‌گذار پروژه Gnu محسوب می‌شود. نخستین نسخه GCC در سال ۱۹۸۷ انتشار یافت که یک پیشرفت مهم محسوب می‌شد زیرا محصول جدید اولین کامپایلر بهینه‌سازی شده قابل حمل ANSI C به عنوان یک نرم‌افزار آزاد محسوب می‌شد. | ## جمع‌بندی | در سال ۱۹۹۷ یک انشعاب آزمایشی در GCC به نام EGCC به منظور بهینه‌سازی کامپایلر و پشتیبانی کامل‌تر از ++C ایجاد شد.