=فرودبر=
{{بهبود منبع}}
'''کامپایلرفرودبر''' {{به انگلیسی|compiler}} [[برنامه (رایانه)|برنامه]] یا مجموعهای از [[برنامه|برنامههای کامپیوتری]] است که متنی از زبان برنامه نویسی سطح بالا (زبان مبدا) را به [[زبان برنامهنویسی سطح پایین|زبانی سطح پایین]] (زبان مقصد)، مثل [[اسمبلی]] یا زبان سطح ماشین، تبدیل میکند. اصطلاح فرودبر در فارسی به این علت برای این واژه انتخاب شده است که این ابزار، زبان سطح بالا را به سطح پایین بدون این که در روند اجرای رفتار کد تغییری ایجاد کند، فرود میآورد. خروجی این برنامه ممکن است برای پردازش شدن توسط برنامه دیگری مثل [[پیونددهنده]] مناسب باشد یا [[فایل]] متنی باشد که انسان نیز بتواند آنرا بخواند.
مهمترین علت استفاده از ترجمه کد مبدا، ایجاد برنامه اجرایی میباشد. برعکس برنامهای که [[زبان برنامهنویسی سطح پایین]] را به بالاتر تبدیل میکند را [[مترجموارونفرازبر]] گوییم.
ترجمه کامل کد منبع برنامهای از یک زبان سطح بالا به کد شیء، پیش از اجرای برنامه را فرودش، همگردانی و یا کامپایل میگویند.
به بیان ساده، کامپایلرفرودبر برنامهای است که یک برنامه نوشته شده در یک زبان خاص [[ساختیافته]] را خوانده و آن را به یک برنامه مقصد (Target Language) تبدیل مینماید. در یکی از مهمترین پروسههای این تبدیل، کامپایلرفرودبر وجود [[خطا]] را در برنامه مبدأ اعلام مینماید.
[[پرونده:Compiler.GIF|چپ|بندانگشتی|شمایی از یک کامپایلرفرودبر]]
در اولین نگاه، تنوع کامپایلرهافرودبرها ممکن است به چشم نیاید. تعداد بسیار زیادی زبانهای منبع وجود دارند که دامنه آنها از زبانهای شناخته شده مانند [[فرترن]] و [[پاسکال]] تا زبانهای خاص منظوره گسترده است. زبانهای مقصد نیز گستردگی متناظر با این زبانها دارند. یک زبان مقصد ممکن است [[زبان برنامهسازی]] دیگر یا [[زبان ماشین]] یا ... باشد.
کامپایلرهافرودبرها به انواع [[تکگذره]]، [[کامپایلرفرودبر چندگذری|چند گذره]]، [[باردهی و اجرا]]، [[بهینهساز]]، [[غلط یاب]] و ... بسته با عمل انجام شده تقسیم میشوند. علیرغم این تنوع اعمال اساسی که هر کامپایلرفرودبر بایستی انجام دهد، مشابه هم میباشند.
دانستههای ما در مورد سازمانبندی و نوشتن کامپایلرفرودبر نسبت به زمانی که اولین کامپایلرهافرودبرها در اوایل دهه ۱۹۵۰ ایجاد شدند، بسیار افزایش یافته است. تخمین تاریخ دقیق ساخت اولین کامپایلرفرودبر عمل آسانی نیست، زیرا گروههای متفاوتی نسبت به ساخت کامپایلرهافرودبرها در آن زمان اقدام نمودهاند. اولین کارهایی که در ساخت کامپایلرهافرودبرها انجام شد، تبدیل فرمولهای ریاضی به [[زبان ماشین]] بود.
در اواسط دهه ۱۹۵۰ کامپایلرهافرودبرها به عنوان برنامههایی دشوار شناخته شده بودند. اولین کامپایلرفرودبر [[فرترن]]، به عنوان مثال ۱۸ سال زمان برای طراحی صرف نمود. از آن زمان روشهای سیستماتیک برای استفاده از بسیاری اعمال مهم حین عمل کمپایلفرودش ابداع شدهاست. همچنین زبانهای پیادهسازی خوب، محیطهای [[برنامه نویسی]] و ابزارهای نرمافزاری مناسب ایجاد شدهاند. با کمک این پیشرفتها یک کامپایلرفرودبر را میتوان حتی به عنوان پروژه درسی در یک ترم تحصیلی دانشجویی طراحی نمود.
== تاریخچه ==
در اواخر دهه ۱۹۵۰ میلادی ماشینهای دارای زبانهای برنامه نویسی رواج یافتند و کامپایلرهایفرودبرهای آزمایشی ایجاد شدند. زبان [[فرترن]] به سرپرستی [[جان باکوس]] در شرکت [[آیبیام]] به عنوان اولین کامپایلرفرودبر کامل در سال ۱۹۵۷ تولید شد. [[کوبول]] اولین زبان کامپایلیفرودشی با معماری چندگانه در سال ۱۹۶۰ تولید شد. در طی دهه ۶۰ کامپایلرهایفرودبرهای زیادی تولید شد اما بر روی کیفیت کامپایلرهافرودبرها کمتر فکر میشد.
همزمان با تکامل زبانهای برنامه سازی و افزایش قدرت کامپیوترها، کامپایلرهافرودبرها هرچه بیشتر پیچیده میشدند.
یک کامپایلرفرودبر خود برنامهای است که توسط زبان پیادهساز تولید شدهاست. اولین کامپایلرفرودبر خود محور که میتوانست کد خود را کامپایلفرودش کند برای زبان [[Lisp]] و توسط Hart و Levin در سال ۱۹۶۲ و در [[مؤسسه فناوری ماساچوست]] ایجاد شد. در دهه ۷۰ از زبانهای سطح بالایی مثل [[پاسکال (زبان)|پاسکال]] و [[سی]] جهت نوشتن کامپایلرهافرودبرها استفاده شد. ساخت کامپایلرهایفرودبرهای خود محور دارای مشکل راهاندازی است، چونکه هر کامپایلریفرودبری باید توسط کامپایلرفرودبر نوشته شدهای به زبان دیگر کامپایلفرودش شود یا برای این مشکل دست به دامن [[مفسر (رایانه)|مفسری]] بشود.
ساختار کامپایلرهافرودبرها و [[کامپایلرفرودبر بهینهساز]] امروزه بخشی از برنامه درسی دانشجویان کامپیوتر است. برخی کامپایلرهافرودبرها به منظور آموزشی برای زبانهای برنامه نویسی تولید میگردد. مثلاً کامپایلرفرودبر PL/۰ توسط Niklaus Wirth برای آموزش در دهه ۱۹۷۰ به کار رفت. به علت سادگی و دلایل زیر هنوز برای آموزش مورد استفاده قرار میگیرد:
* توسعه گام به گام برنامه
* به کار گیری پارسرهای بازگشتی
* نمایش T-diagram جهت تعارف رسمی
در تاریخچه کامپایلرفرودبر سه دوره میتوان در نظر گرفت:
از ۱۹۴۵تا۱۹۶۰:تولید کد
در این دوره، زبانها به تدریج به وجود آمدند و ماشینها چندان متعارف نبودند. مسئله این بود که چگونه باید کدی را برای یک ماشین تولید کرد. با توجه به اینکه برنامه نویسی به زبان اسمبلی رواج داشت، این مسئله وخیمتر شد. استفاده از کامپایلر،فرودبر، برنامه نویسی خودکار نامیده شد. طرفداران زبانهای سطح بالا میترسیدند که کد تولید شده نسبت به زبان اسمبلی کارایی چندان نداشته باشد. اولین کامپایلرفرودبر فرترن (شریدان ۱۹۵۹) به خوبی بهینهسازی شد.
از ۱۹۶۰تا۱۹۷۵:تجزیه کردن
در دهههای ۱۹۶۰و۱۹۷۰ زبانهای برنامهسازی جدید به وجود آمدند و طراحان زبان معتقد بودند که طراحی سریع کامپایلرفرودبر برای زبان جدید، مهمتر از وجود کامپایلریفرودبری با کد کارآمد است. بدین ترتیب، در ساخت کامپایلرفرودبر به پردازشگر جلویی تاکید شدهاست. در همین زمان، مطالعه زبانهای رسمی، تکنیکهای قدرتمندی را برای ساخت پردازشگر جلوی، بخصوص تولید تجزیه کننده به وجود آورد.
از ۱۹۷۵ تاکنون:تولید کد و بهینهسازی کد
از ۱۹۷۵ تاکنون، تعداد زبانهای جدید و انواع ماشین مختلف کاهش یافت در نتیجه نیاز به کامپایلرهایفرودبرهای سریع و ساده یا سریع و ناقص برای زبانها یا ماشینهای جدید، کاهش یافت. بزرگترین آشفتگی در طراحی زبان و ماشین خاتمه یافت و افراد خواستار کامپایلرهایفرودبرهای قابل اعتماد، کارآمد و با واسط کاربر مناسب شدند. بدین ترتیب، توجه کیفی به کد بیشتر شد زیرا با تغییر اندکی که در ساختار ماشینها ایجاد میشود، طول عمر کدها افزایش مییابد. در همین دوره، مدلهایی در برنامه نویسی به وجود آمدند که برنامه نویسی تابعی، منطقی و توزیعی نمونههای از این مدلها هستند، خواستههای زمان اجرای این زبانها نسبت به زبانهای دستور، افزایش یافت.
== انواع کامپایلرهافرودبرها ==
راههای مختلفی جهت دستهبندی کامپایلرهافرودبرها وجود دارد مثلاً میتوان آنها را با توجه به ورودی، خروجی، ساختار داخلی و یا رفتار زمان اجرای آن تقسیم بندی کرد.
=== کامپایلرهایفرودبرهای Native و cross ===
اکثر کامپایلرهافرودبرها به دو دسته Native و Cross تقسیم میشوند. کامپایلرهاییفرودبرهایی که به منظور اجرای [[برنامه|برنامهها]] کدهای باینری را تولید میکنند، کامپایلرهاییفرودبرهایی با کد محلی یا Native گوییم چرا که تنها در [[کامپیوتر|کامپیوترهای]] یک نوع با [[سیستمعامل|سیستمعاملهای]] یکسان قابل به کارگیری است. از طرف دیگر ممکن است کامپایلرهافرودبرها کدهای باینری را تولید کنند که در سیستمهای مختلف قابل اجرا باشد. به این دسته از کامپایلرهافرودبرها که وابستگی به سختافزار ندارند، کامپایلرهایفرودبرهای عبوری یا Cross گوییم. برای این نوع کاپایلرهافرودبرها تنها کافی است برای بار اول [[سختافزار]] را به آن معرفی نمود؛ بنابراین میتوان نتیجه گرفت که کامپایلرهایفرودبرهای عبوری مفیدتر هستند.
این تقسیم بندی برای [[مفسر (رایانه)|مفسرها]] به کار نمیرود جونکه آنها از نمایش دودویی برای اجرای کد خود استفاده نمیکنند.
ماشینهای مجازی در هیچیک از این دستهبندیها نمیگنجد. هر گاه در ماشینهای مجازی یکسان قابل اجرا باشد میتوان آنرا Native و هرگاه کامپایلرفرودبر قادر به تولید خروجی برای پلت فورمهای مختلف باشد آنرا Cross گوییم.
=== کامپایلرهایفرودبرهای تک فاز و چند فاز ===
فاز بندی کامپایلرهافرودبرها که در پشت زمینه به محدودیتهای منابع سختافزاری وابستهاست. در نتیجه کامپایلرهافرودبرها به مجموعه برنامههای کوچکتر تقسیم میشوند هر یک بخشی از عمل ترجمه یا آنالیز را برعهده میگیرند.
کامپایلفرودش تک فازی به نظر مفید میآید، چراکه سریعتر است. [[زبان پاسکال]] از این امکان استفاده میکند. اما مشکل اینجا است که اگر اعلان جلوتر از دستور به کارگیری باشد، چه کار باید کرد؟ برای حل این مشکل میتوان در فاز اول اعلانها را مشخص کرد و در فاز بعد عمل ترجمه را انجام داد. عیب دیگر کامپایلرفرودبر تک فازی دشواری بهینهسازی کدهای زبان سطح بالا میباشد.
همگردانفرودبر یکگذره (One-Pass Compiler) کامپایلریفرودبری است که برای تولید [[کد]] ماشین، تنها یک مرتبه متن برنامه را میخواند. دستور برخی زبانها به گونهای است که تولید همگردانفرودبر یکگذره برای آنها غیر ممکن است.
مجموعه همگردانهایفرودبرهای گنو یا Gnu complier colection یا به صورت مخفف GCC مجموعهای از همگردانهایفرودبرهای آزاد برای زبانهای برنامه نویسی است.
تقسم بندی کامپایلرهافرودبرها به برنامههای کوچکتر تکنیکی است که همچنان مورد بحث محققان است.
در این نوع دستهبندی کامپایلرها،فرودبرها، انواع دیگری نیز وجود دارد:
* '''کامپایلرفرودبر مبدا به مبدا''' که کدی با زبان سطح بالا را دریافت میکند و خروجی آن نیز زبان سطح بالا میباشد. مثلاً موازی سازی خودکار کامپایلرفرودبر در مواردی که به طور تکراری در برنامه ورودی وجود دارد و سپس تغییر شکل دادن کد و نوشتن کد یا ساختار زبانی موازی (برابر) با آن.(همچون دستور DOALL در [[فورترن]]).
* '''کامپایلرفرودبر Stage''' که به [[زبان اسمبلی]] برای ماشین نظری ترجمه میکند. مثلاً در [[پرولوگ]]
** ماشین پرولوگ معمولاً ماشین انتزائی (WAM) خوانده میشود. بایت کدهای [[جاوا]] و Python زیر مجموعهای از این دستهاند.
* '''کامپایلرفرودبر زمان اجرا'''، برای سیستمهای Smalltalk، Java و زبانهای میانه(CIL) در محصولات NET. استفاده میشود.
=== زبانهای تفسیری و کامپایلیفرودشی ===
بسیاری از افراد زبانهای سطح بالا را به دو دسته تفسیری و کامپایلیفرودشی تقسیم میکنند. کامپایلرهافرودبرها و مفسرها روی زبانها عمل میکنند نه زبانها روی آنها! مثلاً این تصور وجود دارد که الزاماً BASIC تفسیر میشود و C کامپایلفرودش. اما ممکن است نمونههایی از BASIC یا C ارائه شود که به ترتیب کامپایلریفرودبری و تفسیری باشد.
البته استثناهایی نیز وجود دارد، مثلاً برخی زبانها در خصوصیات خود این تقسیم بندی را مشخص کردهاند(C کامپایلریفرودبری است یا SNOBOL۴ و اکثر [[زبانهای اسکریپتی]] که کد منبع زمان اجرا دارند تفسیری میباشد).
== طراحی کامپایلرهافرودبرها ==
تقسیم بندی پروسههای کامپایلفرودش به مجموعهای از فازها مورد حمایت پروژه کامپایلریفرودبری ((تولید کامپایلرهایفرودبرهای باکیفیت))(PQCC) از دانشگاه Carnegie Mellon قرار گرفت. در این پروژه اصطلاحات جلو بندی، میان بندی (امروزه به ندرت به کار میرود) و عقب بندی معرفی شد.
اکثر کامپایلرهایفرودبرهای امروزی بیش از دو فاز دارند. جلوبندی معمولاً با پردازش املایی و معنایی شرح داده میشود. عقب بندی شامل تبدیل نوع و بهینهسازیهای مختلف میباشد. سپس کد برای آن کامپیوتر خاص تولید میشود.
استفاده از جلوبندی و عقب بندی این را ممکن میکند که جلوبندیهای مختلفی برای زبانهای مختلف وجود داشته باشد و عقب بندیهای مختلفی نیز برای [[CPU|CPUهای]] مختلف.
جلوبندی به منظور تولید ''کد میانی'' یا ''IR'' از کد مبدا استفاده میشود. جلوبندی معمولاً جدول نمادها را مدیریت نموده و یک نگاشتگر ساختمان دادهای، هر نماد را از درون کد مبدا به اطلاعات مربوط به آن مثل نوع و دامنه تعریف آن [[نگاشت]] میشود. این امر در چند فاز انجام میگردد:
# '''خط نوسازی'''. زبانهایی که اجازه تعیین فضای اختیاری برای شناسهها را میدهند قبل از عمل تجزیه نیاز به فاز اضافی دارند که کد ورودی را به صورت متعارفی برای تجزیه گر آماده کند. Algol، Coral۶۶، Atlas Autocode وImp نمونههایی از این زبانه هستند که به خط نوسازی (Line Reconstruction) نیازمند است.
# '''پیش پردازش'''. برخی زبانها همچون C احتیاج به فاز پیش پردازش برای جایگزینی شروط کامپایلفرودش و [[ماکرو|ماکروها]] دارند. در زبان C فاز پیش پردازش شامل مرحله [[تحلیل لغوی]] میشود.
# '''تحلیل لغوی''' کد متنی مبدا را به اجزای کوچکی که [[نشانه]](token) نامیده میشود میشکند. هر نشانه واحد سادهای از زبان است مثل [[کلمات کلیدی]] و نام نمادها. نحو نشانهها نوعاً یک [[زبان باقاعده]] است، بنابراین یک [[ماشین حالت متناهی]] که برپایه یک عبارت باقاعده بنا میشود میتواند جهت شناخت آن استفاده شود.
# '''تحلیل نحوی''' شامل تجزیه کردن نشانههای مرتب جهت شناخت ساختار نحوی زبان میباشد.
=== عقب بندی ===
گاهی مرحله عقب بندی با مرحله تولید کد اشتباه گرفته میشود. اما میتوان گفت که عقب بندی به مراحل چند گانه زیر تقسیم میشود:
# '''تحلیل کامپایلرفرودبر''': این پروسه برای بدست آوردن اطلاعات بیشتر از نمایش میانی فایلهای ورودی میباشد. تحلیلگر نوعی تعاریف مختلفی دارد همچون تحلیلگر حلقوی، تحلیلگر وابسطه، تحلیلگر مستعار، تحلیلگر اشارهای یا غیره میباشد. تحلیل دقیق زیر بنای هر کامپایلرهایفرودبرهای بهینهاست. [[گراف]] فراخوانی و نمودار جریان کنترل معمولاً در فاز تجزیه تولید میگردد.
# '''بهینهسازی''': نمایش میانی زبان به معادلهای پر سرعت تر با شکلهای کوتاه تری تبدیل میگردد. از بهینهسازهای محبوبتر میتوان به موارد زیر اشاره نمود: توسعه درون خطی، حذف کدهای مرده، انتشار ثوابت، تبدیل [[حلقه|حلقهها]]، تخصیصهای ثباتی و موازی سازی خودکار.
# تولید کننده کد: زبان میانی تغییر کرده به زبان خروجی مثل [[زبان ماشین]] ترجمه میشود. این شامل تخصیص منابع و تصمیمات ذخیرهسازی است، مثلاً اینکه کدام متغیر به رجیسترها یا [[حافظه]] اختصاص یابد و گزینش و زمانبندی دستورات مناسب ماشین.
«البته در ابتدای امر که در مورد زبانهای تفسیری و کامپایلریفرودبری گفته بودند باید خاطر نشان کرد که زبانهای تفسیری خط به خط خوانده شده و اجرا میگردد در حالیکه در کامپایلریفرودبری ابتدا تمام برنامه ترجمه شده و سپس اجرا میگردد پس در زمان اجرا سرعت اجرا شدن زبانهای کامپایلریفرودبری بیشتر است. اما کشف و تصحیح خطا در تفسیری بهتر و راحت تر است.»
== همگردانهایفرودبرهای نمونه ==
=== مجموعه همگردانفرودبر گنو ===
GCC از ابتدا مخفف Gnu C Compiler بود ولی از زمانی که توانست زبانهای دیگری غیر از C از قبیل C++،Ada،Java،Objective C و Fortran را کامپایلفرودش کند به Gnu Compiler Collection تغییر نام داد.
پدید آورنده اصلی GCC ریچارد استالمن است کسی که بنیانگذار پروژه Gnu محسوب میشود. نخستین نسخه GCC در سال ۱۹۸۷ انتشار یافت که یک پیشرفت مهم محسوب میشد زیرا محصول جدید اولین کامپایلرفرودبر بهینهسازی شده قابل حمل ANSI C به عنوان یک نرمافزار آزاد محسوب میشد.
در سال ۱۹۹۲ نسخه ۲٫۰ کامپایلرفرودبر GCC عرضه شد. نسخه جدید قابلیت کامپایلفرودش کدهای ++C را نیز داشت.
در سال ۱۹۹۷ یک انشعاب آزمایشی در GCC به نام EGCC به منظور بهینهسازی کامپیایلرفرودبر و پشتیبانی کامل تر از ++C ایجاد شد. در ادامه EGCC به عنوان نسل بعدی کامپایلرفرودبر GCC پذیرفته شد و تکامل آن باعث انتشار نسخه سوم GCC در سال ۲۰۰۴ گردید.
چهارمین نسخه از کامپایلرفرودبر GCC در سال ۲۰۰۵ عرضه شد.
== جستارهای وابسته ==
{{رایانه}}
[[رده:فرودبر ها]]
[[رده:کامپایلرها]]
[[رده:اختراعاتفرودبر آمریکاییسازی]]
[[رده:برنامهنویسی]]
[[رده:پیادهسازی زبان برنامهنویسی]]
[[رده:کامپایلرسازیاختراعات آمریکایی]]
[[رده:کتابخانههای رایانه]]
|