کامپایلر یک برنامهی خاص برای ترجمه سورس کدهای (Source Code) یک زبان برنامه نویسی، به زبان ماشین یا بایت کد و یا یک زبان برنامه نویسی دیگر است. سورس کد معمولا توسط یک زبان برنامه نویسی سطح بالا و نزدیک به زبان انسان مانند جاواجاوا چیست؟ تعریف، معنی و ویژگی های جاوا (java) از 0تا100جاوا یک زبان برنامه نویسی همه منظوره، مبتنی بر کلاس و شی گرا است که برای داشتن وابستگی های پیاده سازی کمتر طراحی شده است، زبان برنامه نویسی جاوا شبیه ++C است یا سی پلاس پلاسبرنامه نویسی سی پلاس پلاس چیست؟ مزایای برنامه نویسی C++؟برنامه نویسی سی پلاس پلاس چیست و چه کاربردی دارد؟ این صفحه عالی به بررسی مزایای برنامه نویسی C++ پرداخته و نمونه هایی از کدهای زبان برنامه نویسی ++C را آورده نوشته میشود. برنامه نویسان معمولا این سورس کدها را داخل یک ادیتور کد نویسی و یا یک IDE یا Integrated Development Environment مینویسند. IDE دارای یک ادیتور کد نویسی است و سورس کدها را در قالب یک یا چند فایل ذخیره میکند. کامپایلری که زبان برنامه نویسی سورس کد را پشتیبانی میکند، فایل سورس را میخواند، تجزیه و تحلیل میکند و سپس آن را با فرمتی مناسب برای پلفترم هدف ترجمه میکند.
کامپایلرهایی که سورس کد را به کد ماشین ترجمه میکنند، پلتفرم هدف آنها در واقع سیستم عاملها و یا معماریهای کامپیوتری (سخت افزاری) هستند. این نوع هدف، بعضی وقتها با عنوان آبجکت کد (Object code) شناخته میشود ( که البته ربطی به قضیهی برنامه نویسی شی گرا یا Object-Oriented Programming ندارد). خروجی ترجمه شدهی کد برای ماشین، تماما کد های دودویی یا باینری هستند. یعنی تنها از 0 و 1 تشکیل شدهاند. بنابراین پردازندهی کامپیوترهای هدف، قادر به اجرای این کدها میباشند. به عنوان ذکر یک نمونه، خروجی میتواند برای پلتفرم Linux x64 و یا پلفترم Linux ARM 64-bit باشد.
بعضی کامپایلرها میتوانند سورس کدها را به جای کدهای ماشین، به بایت کد (Byte Code) تبدیل کنند. بایت کد نخستین بار توسط زبان برنامه نویسی جاواجاوا چیست؟ تعریف، معنی و ویژگی های جاوا (java) از 0تا100جاوا یک زبان برنامه نویسی همه منظوره، مبتنی بر کلاس و شی گرا است که برای داشتن وابستگی های پیاده سازی کمتر طراحی شده است، زبان برنامه نویسی جاوا شبیه ++C است معرفی شد. بایت کد یک زبان میانی (بین زبان سطح بالا و زبان ماشین) است که میتواند توسط تمامی سیستمهایی که به وسیلهی ماشین مجازی جاوا یا Java virtual machine (JVM) کار میکند، اجرا شود. JVM یک مفسر یا Interpreter است که میتواند بایت کدها را به دستوراتی تبدیل کند که قابل اجرا توسط پردازندههای سخت افزاری است.
همچنین بعضی از کامپایلرها میتوانند سورس کدها را به جای تبدیل به کدهای ماشین یا بایت کد، به یک زبان سطح بالای دیگر ترجمه کنند. این کامپایلرها معمولا با اصطلاحاتی نظیر ترنسپایلر (Transpiler)، ترنسکامپایلر (Transcompiler) و یا Soruce-To-Source Translator شناخته میشوند. به عنوان مثال، یک توسعه دهنده میتواند از این ترانسپایلرها برای تبدیل کد از زبان برنامه نویسی COBOL به زبان Java استفاده کند.
صرف نظر از اینکه برنامه نویس از چه زبان برنامه نویسی استفاده میکند و خروجی کدش قرار است روی کدام پلتفرم باشد، کامپایلر باید از صحیح بودن منطق کد ورودی و مطابقت آن با کد خروجی، اطمینان حاصل کند. هنگام تبدیل کد ورودی، هیچ چیز نباید از بین برود. در غیر این صورت در منطق برنامه مشکل بوجود میآید. یک کامپایلر مثل یک مترجم عمل میکند و باید مطمئن باشد هیچ منطقی در خروجی حذف نمیشود و تغییر نمیکند.+
کامپایلر چگونه کار می کند؟
کامپایلرها متفاوت هستند و از متدهای گوناگونی برای تجزیه و تحلیل و تبدیل سورس کد به کد خروجی استفاده میکنند. اما صرف نظر از این تفاوتها، اکثر کامپایلرها از یکسری مراحل خاص پیروی میکنند که در زیر لیست شدهاند:
- تحلیل لغوی (Lexical Analysis): کامپایلر، سورس کد را به یکسری از واژهها تقسیم میکند که این واژه ها در واقع یک قطعه از کد هستند و از الگوی خاصی پیروی میکنند (هر زبان برنامه نویسی الگوی خاص خود را دارد)، سپس این واژگان توکن سازی میشوند تا به مراحل بعدی یعنی تحلیل نحوی و تحلیل معنایی برسند.
- تحلیل نحوی (Syntax Analysis): با توجه به قواعد مربوط به زبان برنامه نویسی، کامپایلر، سینتکسها و کدها را بررسی و تایید میکند. این مرحله شبیه به صحیح کردن املاء میباشد. به عنوان مثال کامپایلر بررسی میکند که True به اشتباه Treu نوشته نشده باشد. این فرایند همچنین با نام پارسینگ نیز شناخته میشود. در طول این مرحله، کامپایلر ها معمولا درختهای انتزاعی از سینتکسها را ایجاد میکنند که ساختارهای منطقی عناصر یک کد خاص را نشان میدهد. سپس کد یا عبارت مورد نظر را حرف به حرف تطابق میدهد.
- تحلیل معنایی (Semantic Analysis): در این مرحله کامپایلر کدها را بر اساس منطق آنها بررسی میکند. این مرحله فراتر از تحلیل نحوی است. در تحلیل نحوی گفتیم که املای یک واژه بررسی میشود. در این مرحله منطق یک عبارت بررسی میشود. به عنوان مثال ممکن است واژه ی True درست نوشته شده باشد. (رد شدن از مرحلهی تحلیل نحوی) اما این مقدار به یک متغیر از نوع عددی (به جای بولین) نسبت داده شده است. بنابراین از نظر نحوی درست است، اما از نظر معنایی اشتباه میباشد. زیرا متغیر ذکر شده به جای مقدار عددی گرفتن، مقدار True گرفته است.
- تولید کد (IR code generation): بعد از عبور از 3 مرحلهی بالا، کامپایلر کد IR یا Intermediate Representation را از سورس کد تولید میکند. درواقع کد IR یک کد میانی است که مراحل ترجمهی سورس کد به یک فرمت دیگر را راحت تر میکند. لازم به ذکر است که این کد میانی، تمامی قابلیتهای سورس کد را دارد و هیچ قسمتی از آن حذف نشده است.
- بهینه سازی (Optimization): در این مرحله، کامپایلر کد IR را برای تبدیل شدن به خروجی نهایی، بهینه میکند. میزان بهینگی کد بستگی به خود کامپایلر دارد. بعضی از کامپایلرها این اختیار را به کاربران میدهد تا درجهی بهینگی را خودشان به طور دستی تنظیم کنند.
- تولید کد خروجی (Output Code Generation): در این مرحله کامپایلر کد خروجی نهایی را از روی IR کدهای بهینه شده تولید میکند.
نکتهی آخر مربوط به مبحث در مورد کامپایلر و مفسر میشود. بسیاری از افراد این دو برنامه را با هم اشتباه میگیرند. اگرچه هدف این دو برنامه شبیه به هم است، اما یک تفاوت مهم بین آنها وجود دارد. کامپایلر، سورس کدهایی را که با زبانهایی مثل ++Java، C#، C و یا Swift نوشته شدهاند را تجزیه و تحلیل کرده و سپس آنها را با کمک کدهای IR، به کدهای زبان ماشین یا بایت کدها تبدیل میکند. این کد ها قادر به اجرا بر روی سیستم میزبان پلفترم خروجی هستند.
اما مفسرها کد های IR و میانی تولید نمیکنند. همچنین کدهای ماشین تولید شده را نیز ذخیره نمیکنند (برای کمک در کامپایل مجدد به صورت سریع، کامپایلرها اینکار را انجام میدهند). بلکه مفسرها، کدها را به صورت خط به خط در زمان اجرا، پردازش میکنند. همچنین این کدها مرحلهی آماده سازی یا Pre-Converting برای پلتفرم نهایی را ندارند. مفسرها برای زبان های اسکریپتی مثل زبانهای Perl، PHP، Ruby، و یا Python مورد استفاده قرار میگیرند.
انواع کامپایلر
به طور کلی کامپایلر به ۳ نوع تقسیم میشود.:
- کامپایلر های تک گذره یا Single Pass Compilers
- کامپایلر های دو گذره یا Two Pass Compilers
- کامپایلر های چند گذره یا Multipass Compilers
کامپایلر های تک گذره
وقتی تمامی فاز های طراحی کامپایلر که در قسمت قبل بررسی شد را درون تنها یک ماژول قرار دهیم، در واقع کامپایلر تک گذره ساختهایم. کامپایلر های تک گذره سورس کد (Source Code)سورس کد چیست؟ آیا سورس کد یا سورس برنامه قابلیت اجرا دارند؟این مقاله عالی به سورس کد یا سورس برنامه پرداخته؛ همچنین به بررسی اهداف سورس کد، نحوه ساخت سورس کد و اینکه آیا سورس کد ها قابلیت اجرا دارند پرداخته را دریافت کرده و مستقیما به کد های ماشین تبدیل میکنند:
کامپایلر های دو گذره
این کامپایلرها طی دو مرحله سورس کد را به کد مقصد ترجمه میکنند، در مرحلهی اول سورس کد از طریق لایهی Front End به یک Intermediate Representation که در واقع یک نوع کد میانی است و تنها توسط کامپایلر مورد استفاده قرار میگیرد تبدیل شده و سپس از طریق لایهی دوم یا Back End تبدیل به کد نهایی یعنی کد ماشین میشود.
کامپایلر های چند گذره
در این نوع از کامپایلرها، سورس کدها یا در واقع همان درخت سینتکس چندین بار توسط کامپایلرها پردازش میشوند. این کامپایلر ها در واقع یک برنامه ی خیلی بزرگ را به چندین برنامهی کوچکتر تقسیم کرده و این برنامههای کوچک را به طور همزمان اجرا میکنند. خروجی این رویکرد، چندین کد میانی یا Intermediate Code است که توسط کامپایلر تولید شده است. همچنین در هر مرحله یا هر فاز، خروجی آن مرحله میتواند به عنوان ورودی فاز بعدی مورد استفاده قرار گیرد، این کار باعث میشود نیازمان به حافظه یا Memory کمتر شود. نام دیگر این کامپایلر ها Wide Compiler نیز است.
کامپایلر چیست؟
کامپایلر یک برنامه خاص برای ترجمهی سورس کد زبانهای برنامه نویسی مانند Java و ++C به کد های ماشین و بایت کد ها است. زبان های برنامه نویسی ترجمه شده توسط کامپایلر، معمولا زبانهای سطح بالا و نزدیک به زبان انسان است و کدهای تولید شدهی نهایی توسط کامپایلر، بایت کدها یا کدهای ماشین است که توسط پردازشگرهای سیستم خروجی، قابل اجرا میباشد.
آیا کامپایلر همان مفسر است؟
خیر، هدف از این دو برنامه تقریبا شبیه به هم میباشد، اما تفاوتهای اساسی بین این دو برنامه وجود دارد. کامپایلر کدهای زبان های برنامه نویسی را به کدهای میانی یا IR تبدیل میکند و سپس از روی این کدها، خروجی نهایی را برای یک هدف یا پلتفرم مشخص تولید میکند. اما مفسر مخصوص زبانهای اسکریپتی است و سورس کدها را در زمان اجرا به صورت خط به خط اجرا میکند. همچنین یک مفسر، کدها را به زبان IR تبدیل نمیکند.