מבוא לקומפליזציה חלק 1: סקירה

בסדרת מדריכים זו אנסה להסביר בדרך פרקטית ותיאורטית את השלבים בכתיבת מהדר.

לפני שנתחיל מספר הבהרות:

  1. מעולם לא למדתי באוניברסיטה את הנושא לפיכך יכולים להיות אי דיוקים כאלה או אחרים
  2. מטרתי הינה להכיר לקורא את העולם המופלא הזה ולא לכתוב שפת תכנות מ0 ל100 ( אולי אכתוב מדריך בנושא זה בעתיד)

אז בלי חפירות מיותרות בואו נתחיל.

כדי להבין מהו מהדר צריך קודם להבין מה היא הבעיה שהוא בא לפתור,
בראשית המאה ה20, רוב התוכנות (אם לא כולם ) נכתבו ב assembly ותורגמו לקוד מכונה, לאחר שמדעני המחשב והמהנדסים באותה תקופה שמו לב לכך שיש הרבה דפוסי קוד באסמבלי שחוזרים על עצמם (כגון השוואה של שני ערכים, לולאות וכולי) , ומאחר והיה קושי בתחזוק מערכות קוד גדולות , עלה הצורך ביצירת תוכנה אשר תתרגם משפה High-Level אשר מכילה מילים באנגלית (שלא אומרים שום דבר למחשב) לקוד מכונה,

תוכנות אלו נקראו קומפיילרים (compilers) או בעברית מהדרים.

אפשר להסיק אם כך שמהדר בהגדרתו פשוט מתרגם משפה א’ לשפה ב’, אז איך אם כך הוא עושה את הקסם הזה?

כל מהדר מודרני מורכב ממספר חלקים או שלבים (phases) אשר האיגוד שלהם יחדיו יוצר מהדר.

החלקים/שלבים הם:

  1. המנתח הלקסיקלי, אשר נקרא Lexer או Tokenizer
  2. המנתח הסמנטי , אשר נקרא Parser
  3. מנתח סטטי, הוא לרוב חלק מהשלב הרביעי, אבל אני אישית מעדיף להגדיר אותו כשלב נפרד
  4. מחולל קוד ביניים , או בשפה יותר שפויה (כלומר אנגלית ) Intermediate code generator
  5. אופטימיזציה לא תלוית מכונה
  6. מחולל קוד מכונה, Machine code generator
  7. אופטימיזציה תלוית מכונה

הבהרה: לא אגע כלל בחלקים 5 ו7 מאחר והם דורשים ידע מתמטי ותיאורטי רחב (מה שאין לי)

בנוסף לחלקים אלו ישנו חלק חשוב לא פחות אשר נקרא Symbol Table, והוא אחראי על שמירת מידע על symbols לכל אורך תהליך ההידור (בחלקים הבאים אסביר עליו בהרחבה).

לאחר כל מעבר שלב הקלט A עובר טרספרומציה מסוימת ובסופו של כל התהליך נהפך לפלט B.

אתן כאן סקירה זריזה של כל שלב ובחלקים הבאים אסביר על שלב לעומק (עם קוד)

המנתח הלקסיקלי:
מטרתו של המנתח הלקסיקלי היא יצירת זרם מובן של אסימונים (מסתבר שזה תרגום למילה token, גם אני הופתעתי) מתוך הקלט A, הפלט של השלב הזה נקרא tokens או אסימונים ( טוב אני יותר לא אשתמש במילה הזאת) והוא מוזן ישירות לתוך השלב הבא

המנתח הסמנטי:
הליך הפירסור (Parser):
מטרתו של שלב זה הינה יצירת עץ אשר נקרא Syntax tree מתוך זרם הtokens שהגיע מהמנתח הלקסיקלי, אותו עץ משומש בחלקים הבאים של המהדר, אפשר לתאר את התהליך הזה כתהליך ההבנה של הקלט.

בנוסף לדברים אלו המנתח גם אוסף מידע על הסימנים (symbols) ושם אותו בsymbol table
העץ אשר נוצר מועבר לשלב הבא

המנתח הסטטי:
המנתח הסטטי אחראי על ביצוע type checking , וביצוע שלל בדיקות אחרות (כגון dead code elimination וכולי)

והוא מוטמע בתוך השלב הבא

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

לאחר שלב זה לרוב מבוצעת אופטימיזציה מסוג כלשהו על הIR

מחולל קוד מכונה:
בשלב זה ה IR מתורגם לשפת מכונה, לרוב יש בשלב זה עוד בדיקות ואופטימיזציה לפי מכונת היעד (בarm יתבצעו אופטימיזציות שונות מאשר בAVR או בx86 )

אפשר לייצג את כל התהליך באמצעות הדיאגרמה הבאה:

בחלקים הבאים אעבור על כל חלק ואסביר עליו בהרחבה בצירוף פיסות קוד.

אשמח להערות והארות
ותודה רבה שקראתם

מקורות:
Compilers, Principles, techniques and tools
(אחלה ספר מומלץ בחום)

12 לייקים

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

לייק 1

היי, אחלה מאמר, הייתי שמח אם היית מוסיף את הספר שהקנה לך את הידע לספרייה שלנו :slight_smile:

לייק 1