לדלג לתוכן

מהדר

מתוך ויקיפדיה, האנציקלופדיה החופשית
(הופנה מהדף קומפילציה)
תרשים המתאר פעולת מהדר בעל מספר שפות ומספר יעדים

מְהַדֵּראנגלית: Compiler) הוא תוכנית מחשב המתרגמת משפת מחשב אחת לשפת מחשב אחרת. המהדר הקלאסי מקבל כקלט תוכנית הכתובה בשפה עילית ומתרגם אותה לתוכנית בשפת מכונה. מהדר תואם בדרך כלל לסוג מעבד מסוים בלבד, ולגרסת שפה מסוימת, ותוצריו לא יהיו תואמים למעבד אחר. פעולת המהדר קרויה הידוּר.

המהדר ממיר פקודות משפה המוגדרת על ידי דקדוק אחד לפקודות שמוגדרות על ידי דקדוק אחר. המרה זו בדרך כלל איננה פונקציה חד-חד-ערכית, כלומר את התוצר של מהדר לרוב לא ניתן לתרגם חזרה לקוד המקור: מקודי מקור שונים אפשר להגיע לאותו תוצר סופי.

תהליך בניית תוכנת מחשב מתחלק לשני שלבּים עיקריים - הידור וקישור. המהדר אחראי על תהליך ההידור. בתהליך ההידור ממיר המהדר את הקוד שכתב המתכנת, לשפת מכונה, כך שעבור כל קובץ שעבר הידור נוצר קובץ מקביל בשפת מכונה. קובץ זה מסומן בדרך כלל כקובץ OBJ (או O במהדרים אחרים). תהליך ההידור מורכב ממספר תת-שלבים עיקריים: ניתוח מילולי, ניתוח תחבירי, ניתוח סמנטי, ולבסוף שלב יצירת קוד המכונה.

בתהליך הקישור מקושרים ביחד קבצים אלה לתוצר סופי - תוכנה שניתנת לביצוע במעבד ובמערכת הפעלה מסוימת.

מהדרים של שפות תכנות מסוימות מפיקים קוד למעבד וירטואלי שאינו מיושם באופן ישיר בחומרה. דוגמה לשפות כאלה - ‏Java‏, ‎C#‎ ו-Smalltalk. היתרון בשיטה זו הוא היכולת להריץ את אותו קובץ מהודר במעבדים מסוגים שונים.[1]

מחשבים אינם בעלי בינה ואינם מבצעים דבר פרט למספר מוגבל של פקודות חישוב אלקטרוניות. כל מחשב בנוי על שבב אלקטרוני אחד או יותר הקרוי מעבד המסוגל לקבל בצורה בינארית נתוני קלט, לבצע עליהם פעולה מסוימת ולחשב את הפלט. הכנסת הנתונים והפקודות למעבד מתבצעת בצורה של הכנסת קוד (מספר) של פקודה, יחד עם הנתונים שיעובדו. רצף הפקודות שניתן למעבד נקרא שפת מכונה. אותה שפת מכונה היא התוכנה המורצת במחשב.

בשל הקושי לתכנת את המחשב בשפת מכונה, פותחו עם השנים שפות תכנות מופשטות יותר, הנקראות בשם הקיבוצי שפות עיליות. הדקדוק המגדיר שפה עילית הוא מורכב יותר מדקדוק שפת המכונה, ועם זאת הוא ברור יותר ומאפשר התייחסות מופשטת יותר להיבטים שונים של החומרה והתוכנה, תחזוקתיות קלה יותר, ופיתוח מהיר יותר.

תפקידו של המהדר, אם כך, הוא להמיר את הדקדוק העילי לדקדוק שפת המכונה. באופן כללי ניתן לומר שככל ששפת התכנות מופשטת יותר, כך על המהדר להיות מותאם ומורכב יותר.

שלבי הקומפילציה

[עריכת קוד מקור | עריכה]

לפני שתוכנית C יכולה לרוץ, היא עוברת תהליך שנקרא קומפילציה. התהליך כולל ארבעה שלבים עיקריים: קדם-מעבד, קומפיילר, אסמבלר ולינקר.

  1. קדם-מעבד (Pre-processor) מכין את קוד המקור לתרגום על ידי הקומפיילר. הקדם-מעבד פועל על הוראות (directives) שמתחילות בסימן "#". הוא מבצע הרחבה טקסטואלית, מחליף ומצרף קטעי קוד, אך לא מנתח את התחביר או ההיגיון של התוכנית. כאשר הקדם-מעבד נתקל בשורה כמו #include <stdio.h>, הוא מעתיק ומדביק את כל התוכן של הקובץ stdio.h ישירות לתוך קובץ המקור, שכולל הצהרות על הפונקציות. זה יוצר קובץ אחד גדול ומורחב, שבו כל הפונקציות וההצהרות הנדרשות מהקובץ החיצוני זמינות ישירות לקומפיילר. כך גם בכל מופע של #define הוא פשוט מחליף מופעים של מזהה מסוים בטקסט אחר (לדוגמה, החלפת שם קבוע בערך מספרי). התוצר הוא קובץ מקור יחיד, מורחב, שעדיין מכיל קוד בשפת C, אך ללא הוראות קדם-מעבד.
  2. מהדר (Compiler)מתרגם את קוד המקור המורחב לשפת אסמבלי ומבצע אופטימיזציות. הקומפיילר מבצע ניתוח תחבירי וסמנטי של הקוד. הוא בודק האם הקוד תקין מבחינת כללי השפה (syntax) וכן האם הוא הגיוני מבחינת סוגי הנתונים (semantic). אם מתגלה שגיאה, כמו שימוש במשתנה שלא הוגדר או שגיאת הקלדה, התהליך נעצר ומחזיר הודעת שגיאה. הוא גם מבצע אופטימיזציות שונות כדי לשפר את ביצועי הקוד, למשל על ידי שינוי סדר הפקודות או פישוט ביטויים מתמטיים. התוצר הוא קובץ המכיל קוד בשפת אסמבלי, שהיא שפה קרובה לשפת מכונה.
  3. אסמבלר (Assembler) מתרגם את קוד האסמבלי לשפת מכונה. האסמבלר מקבל את קוד האסמבלי שנוצר על ידי הקומפיילר. הוא מתרגם כל פקודה בשפת אסמבלי לפקודה בינארית מקבילה שמובנת ישירות על ידי המעבד (CPU). נוצר קובץ אובייקט (.o או .obj) שמכיל קוד מכונה בינארי, אך אינו ניתן להרצה בפני עצמו כיוון שחסרים בו קישורים לספריות חיצוניות.
  4. מקשר (Linker) יוצר קובץ הרצה סופי ושלם. הוא מחבר יחד את כל קבצי האובייקט של התוכנית, יחד עם ספריות חיצוניות (כמו ספריות תקניות של C) שמכילות פונקציות כמו printf, malloc ועוד. הוא ממפה כתובות ומטפל בכל הקישורים החיצוניים, כך שכל הפונקציות והמשתנים הדרושים לתוכנית יהיו זמינים. התוצר הוא קובץ הרצה בינארי יחיד ושלם (.exe) שמוכן להפעלה ישירה.

שגיאות זמן הידור

[עריכת קוד מקור | עריכה]

שגיאות זמן הידור הן שם כולל לשגיאות שעל המהדר לזהות כבר בשלב ההידור. שגיאות מסוגים שונים יתגלו בשלבים שונים בזמן ההידור.

זיהוי שגיאת זמן הידור לא בהכרח תעצור את פעולת ההידור – הדבר תלוי באופי השגיאה.

מהדר לעיתים יפיק גם אזהרות על בעיות פוטנציאליות בקוד שלא מונעות את הידורו, אולם פוגעים בקריאות הקוד, כגון חלקים מיותרים שאינם משפיעים כלל על ריצת הקוד.

ההבדל בין מהדר למפרש

[עריכת קוד מקור | עריכה]

ההבדל העיקרי בין מהדר (compiler) לבין מפרש (interpreter) הוא בדרך ובזמן שבו הם מתרגמים את קוד המקור שנכתב על ידי מתכנת לשפת מכונה שהמחשב מבין.

מהדר (Compiler)

[עריכת קוד מקור | עריכה]
  • תרגום מוקדם: מהדר מתרגם את כל תוכנית קוד המקור בבת אחת, לפני שהיא מורצת.
  • פלט: כתוצאה מהתרגום נוצר קובץ בינארי עצמאי (קובץ הרצה, כמו .exe) שמכיל את הקוד המתורגם לשפת מכונה.
  • ביצוע: הקובץ הבינארי יכול לרוץ ישירות על המעבד, ללא צורך במתורגמן נוסף.
  • מהירות: תוכנות מהודרות רצות בדרך כלל מהר יותר, מכיוון שתהליך התרגום נעשה פעם אחת מראש.
  • איתור שגיאות: כל השגיאות התחביריות (syntax errors) מתגלות יחד בתהליך ההידור. אם יש שגיאה אחת, כל התוכנית לא תהודר ולא תרוץ.
  • דוגמאות לשפות: C, C++, C#.

מפרש (Interpreter)

[עריכת קוד מקור | עריכה]
  • תרגום בזמן אמת: מפרש מתרגם ומריץ את התוכנית שורה אחר שורה, בזמן שהיא פועלת.
  • פלט: לא נוצר קובץ בינארי. בכל פעם שמריצים את התוכנית, הקוד מתורגם מחדש.
  • ביצוע: המפרש עצמו צריך להיות פעיל על מנת להריץ את התוכנית, מכיוון שהוא מפרש את הקוד בכל פעם מחדש.
  • מהירות: תוכנות מפורשות רצות בדרך כלל לאט יותר, מכיוון שתהליך התרגום חוזר על עצמו בכל הרצה.
  • איתור שגיאות: שגיאות מתגלות בזמן ריצה, שורה אחר שורה. אם מתגלה שגיאה בשורה מסוימת, התוכנית מפסיקה לפעול באותה נקודה.
  • דוגמאות לשפות: Python, JavaScript, Ruby.
מאפיין מהדר (Compiler) מפרש (Interpreter)
זמן תרגום לפני הרצה, את כל התוכנית בזמן הרצה, שורה אחר שורה
פלט קובץ בינארי (קובץ הרצה) אין קובץ בינארי
מהירות מהיר איטי יותר
איתור שגיאות כל השגיאות יחד בהתחלה שגיאה אחר שגיאה בזמן ריצה
ניידות פחות נייד (תלוי פלטפורמה) נייד יותר (דורש מפרש בכל פלטפורמה)

קישורים חיצוניים

[עריכת קוד מקור | עריכה]
ויקישיתוף מדיה וקבצים בנושא מהדר בוויקישיתוף

הערות שוליים

[עריכת קוד מקור | עריכה]
  1. ^ Chengnian Sun, Vu Le, Qirun Zhang, Zhendong Su, Toward understanding compiler bugs in GCC and LLVM, Proceedings of the 25th International Symposium on Software Testing and Analysis, ISSTA 2016, Association for Computing Machinery, 2016-07-18, עמ' 294–305 doi: 10.1145/2931037.2931074