Download presentation
Presentation is loading. Please wait.
1
נכתב ע"י קירה רדינסקי ((kirar@cs
תרגום לקוד ביניים נכתב ע"י קירה רדינסקי סמסטר אביב, תשס"ט
2
מבנה סכמתי של קומפיילר עד כה ראינו: בפועל: Back-end Front-end ניתוח
לקסיקלי תחבירי סמנטי backend ניתוח לקסיקלי תחבירי סמנטי backend אופטימיזציה שפת ביניים Back-end Front-end
3
שפת ביניים מדוע לא לתרגם ישר לשפת היעד?
פיתוח מהיר יותר של קומפיילר למערכת חדשה נדרש לכתוב רק Back-end פיתוח אופטימיזציות כלליות שפת ביניים איתה נעבוד בקורס: שפת הרביעיות דומה מאד לשפת אסמבלר סדרה של פקודות מהצורה x := y OP z
4
שפת ביניים (המשך) נעבוד עם 4 סוגי פקודות בלבד:
פעולה אריתמטית: t1 := t2 + t3 קפיצה לא-מותנית: goto label קפיצה מותנית: if t1 relop t2 goto label תווית: label: קיימות פקודות רבות נוספות
5
דוגמה a = b + c + d t1 := b + c t2 := t1 + d a := t2 מדוע צריך את t2?
6
טעויות נפוצות דברים שאינם קוד ביניים if … else …
if (x > 1 && y > 1) goto … התנאי בקפיצה אינו מורכב x = 1000 goto x ניתן לקפוץ רק לתוויות קבועות
7
פונקציות לפריסת קוד נצטרך תכונות הבאות: פונקציות עזר: code: הקוד הנוצר
place: לביטויים אריתמטיים, המשתנה הזמני שהוקצה לביטוי תכונות נורשות: תכונה לכל נקודת המשך אפשרית פונקציות עזר: newtemp(): יוצרת משתנה זמני חדש newlabel(): יוצרת תווית חדשה
8
שיטות לייצור קוד לכל משתנה בדקדוק תהיה תכונה code שתאגור את הקוד ש"מבצע מה שצריך" עבורו דוגמה: תרגום ביטויים אריתמטיים נניח שלמשתנה E קיימות התכונות code ו-place (המשתנה הזמני אליו נשמר ערך הביטוי) E E1 + E2 { E.place = newtemp(); E.code = E1.code || E2.code || E.place || “:=“ || E1.place || “+” || E2.place; } יצירת מקום לתוצאה יצירת קוד t1 E1 t2 E2 t3 := t1 + t2
9
שיטות לייצור קוד (המשך)
נחזיק buffer עם כל הקוד שנוצר עד כה ונדפיס את הקוד ישר לתוכו דוגמה: תרגום ביטויים אריתמטיים ל-E תכונה place (אין צורך בתכונת code) הפונקציה emit מדפיסה פקודה ל-buffer E E1 + E2 { E.place = newtemp(); emit(E.place || “:=“ || E1.place || “+” || E2.place); } היכן הקוד של E1 ו-E2?
10
השוואה בין שתי השיטות בשיטה 1 ניתן לקבוע את הסדר של קטעי הקוד ובשיטה 2 - לא שיטה 2 פשוטה ומהירה יותר אין שרשורי קוד
11
תרגום במבני בקרה הבעיה: כאשר מתרגמים מבנה בקרה, יעדי הקפיצות לא תמיד ידועים דוגמה: if B then S1 else S2 כאשר מתרגמים את B, עדיין לא יודעים את הקוד (והיכן הוא ימוקם) של S1 ו-S2
12
תרגום פשוט הגדרה (תרגום פשוט): פיתרון לבעיה:
לכל קטע קוד (המתאים למשתנה מסויום) נקודת כניסה אחת (בראשיתו) ונקודת יציאה בסופו התוצאה היא שבתום ביצוע קטע קוד, מבוצע קטע הקוד ששורשר אחריו פיתרון לבעיה: קטע הקוד של בדיקת התנאי יחשב את התנאי לתוך משתנה זמני (לקטע קוד זה יציאה אחת בסופו). קטע הקוד שאחריו יבדוק את המשתנה הזמני וימשיך לביצוע S1 או S2 לפי ערכו
13
תרגום פשוט E → E1 '>' E2 label tmplabel = newlabel(); E.place = newtemp(); E.code = E1.code || E2.code || gen(E.place '= 0') || gen('if' E1.place '<=' E2.place 'goto' tmplabel) || gen(E.place '= 1') || gen(tmplabel ':'); S → if E then S1 else S2 label falseLabel = newlabel(), endLabel = newlabel(); S.code = E.code || gen('if' E.place '== 0' 'goto' falseLabel) || S1.code || gen('goto' endLabel) || gen(falseLabel ':') || S2.code || gen(endLabel ':');
14
תרגום פשוט - חסרונות לא תמיד אפשר (או נוח) לדאוג ליציאה אחת מכל קטע קוד Break (בלולאה) Switch
15
שיטת התוויות הנורשות הרעיון:
כמה יציאות מקטע הקוד של משתנה כלשהו מהיכן לצאת - חלק מסמנטיקת אותו המשתנה לאן ללכת - חלק מסמנטיקת האב נייצג כל נקודת יציאה בעזרת תכונה נורשת (מסוג תווית) לדוגמה: B.false, B.true פירוש: "היכן להמשיך אם נבחרה נקודת יציאה מסוימת" ברגע שנסיים לתרגם את כל המבנה, נדע לחשב את התכונות אין צורך לחשב את ערכי התנאים הבוליאניים
16
המשתנה B יגזור ביטוי בולאני.
B → E1 '>' E2 B.code = E1.code || E2.code || gen('if' E1.place '>' E2.place 'goto' B.true) || gen('goto' B.false); B → B1 or B2 B1.true = B.true; B1.false = newlabel(); B2.true = B.true; B2.false = B.false; B.code = B1.code || gen(B1.false ':') || B2.code; S → if B then S1 else S2 B.true = newlabel(); B.false = newlabel(); S1.next = S.next S2.next = S.next S.code = B.code || gen(B.true ':') || S1.code || gen('goto' S.next) || gen(B.false ':') || S2.code; המשתנה B יגזור ביטוי בולאני. יש לו 2 יציאות אפשריות: אחת true ואחת false בהתאם לערך הביטוי Or is done in lazy-evaluation לקטע הקוד של המשתנה S צריכה להיות יציאה אחת (לפי תכונת next). אלא ש-S יכול לצאת גם אל הפקודה הבאה
17
חסרונות השיטה פיתרון: פיתרון לפיתרון:
לא מתאימה לניתוח סמנטי בזמן bottom-up לא כל התכונות נוצרות צריך לבנות עץ גזירה, למיין טופולוגית את חישובי התכונות על פי התלויות ולחשב אותן במעבר נוסף פיתרון: להמנע מהורשת תוויות! אבל...משתנה לא יכול לדעת באופן עצמאי לאן לקפוץ פיתרון לפיתרון: במקום שהאבא יגיד לבן: נקודת היציאה שלך exit מופנית לתווית label הבן יגיד לאב: אם היתי יודע לאן exit מופנה היתי רושם ערך זה "כאן, כאן וכאן". אתה לא מספר לי כלום! לכן אני מעביר אליך את האחראיות למלא את החורים שהשארתי! וזה למה בבר-מיצווה אומרים "ברוך שפטרני מעונשו של זה" אבל זה כבר לשיעור הבא- מתרגשים?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.