Presentation is loading. Please wait.

Presentation is loading. Please wait.

תרגום לקוד ביניים 1. מבנה סכמתי של קומפיילר עד כה ראינו: בפועל: ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי backend ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי.

Similar presentations


Presentation on theme: "תרגום לקוד ביניים 1. מבנה סכמתי של קומפיילר עד כה ראינו: בפועל: ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי backend ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי."— Presentation transcript:

1 תרגום לקוד ביניים 1

2 מבנה סכמתי של קומפיילר עד כה ראינו: בפועל: ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי backend ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי backendאופטימיזציה שפת ביניים Front-endBack-end 2

3 שפת ביניים מדוע לא לתרגם ישר לשפת היעד? –פיתוח מהיר יותר של קומפיילר למערכת חדשה נדרש לכתוב רק Back-end –פיתוח אופטימיזציות כלליות שפת ביניים איתה נעבוד בקורס: שפת הרביעיות –דומה מאד לשפת אסמבלר –סדרה של פקודות מהצורה x := y OP z 3

4 שפת ביניים (המשך) נעבוד עם 4 סוגי פקודות בלבד: 1.פעולה אריתמטית:t 1 := t 2 + t 3 2.קפיצה לא-מותנית:goto label 3.קפיצה מותנית:if t 1 relop t 2 goto label 4.תווית:label: קיימות פקודות רבות נוספות.... 4

5 דוגמה a = b + c + d t 1 := b + c t 2 := t 1 + d a := t 2 מדוע צריך את t 2 ? 5

6 טעויות נפוצות דברים שאינם קוד ביניים if … else … –בשפת ביניים אין else if (x > 1 && y > 1) goto … –התנאי בקפיצה אינו מורכב x = 1000 goto x –ניתן לקפוץ רק לתוויות קבועות 6

7 פונקציות לפריסת קוד נצטרך את התכונות הבאות: –code: הקוד הנוצר –place: לביטויים אריתמטיים: זהו המשתנה הזמני שהוקצה לביטוי –תכונות נורשות: תכונה לכל נקודת המשך אפשרית פונקציות עזר: –newtemp(): יוצרת משתנה זמני חדש –newlabel(): יוצרת תווית חדשה 7

8 שיטות לייצור קוד 1.לכל משתנה בדקדוק תהיה תכונה בשם code שתאגור את הקוד ש"מבצע מה שצריך" עבורו דוגמה: תרגום ביטויים אריתמטיים –נניח שלמשתנה E קיימות התכונות code ו-place (המשתנה הזמני אליו נשמר ערך הביטוי) E  E 1 + E 2 { E.place = newtemp(); E.code = E 1.code || E 2.code || E.place || “:=“ || E 1.place || “+” || E 2.place; } יצירת מקום לתוצאה יצירת קוד t 1  E 1 t 2  E 2 t 3 := t 1 + t 2 8

9 שיטות לייצור קוד (המשך) 2.נחזיק buffer גלובלי עם כל הקוד שנוצר עד כה ונדפיס את הקוד ישר לתוכו בעת ביצועי reduce דוגמה: תרגום ביטויים אריתמטיים –ל-E תכונה place (אין צורך בתכונת code) –הפונקציה emit מדפיסה פקודה ל-buffer E  E 1 + E 2 { E.place = newtemp(); emit(E.place || “:=“ || E 1.place || “+” || E 2.place); } היכן הקוד של E 1 ו-E 2 ? 9

10 השוואה בין שתי השיטות בשיטה 1 ניתן לקבוע את הסדר של קטעי הקוד ובשיטה 2 - לא שיטה 2 פשוטה ומהירה יותר –אין שרשורי קוד 10

11 תרגום במבני בקרה הבעיה: כאשר מתרגמים מבנה בקרה, יעדי הקפיצות לא תמיד ידועים דוגמה: if B then S 1 else S 2 כאשר מתרגמים את B, עדיין לא יודעים מהו הקוד של S 1 ו-S 2 ומה גודלו (והיכן ימוקם) 11

12 הגדרה (תרגום פשוט) : לכל קטע קוד (המתאים למשתנה מסויים) נקודת כניסה אחת (בראשיתו) ונקודת יציאה בסופו התוצאה היא שבתום ביצוע קטע קוד, מבוצע קטע הקוד ששורשר אחריו פיתרון לבעיית if B then S 1 else S 2 : קטע הקוד של בדיקת התנאי יחשב את התנאי לתוך משתנה זמני (לקטע קוד זה יציאה אחת בסופו). קטע הקוד שאחריו יבדוק את המשתנה הזמני וימשיך לביצוע S1 או S2 לפי ערכו תרגום פשוט 12

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 ':'); תרגום פשוט 13

14 לא תמיד אפשר (או נוח) לדאוג ליציאה אחת מכל קטע קוד –Break (בלולאה) –Switch תרגום פשוט - חסרונות 14

15 שיטת התוויות הנורשות הרעיון: –יהיו כמה יציאות מקטע הקוד של משתנה כלשהו –מהיכן לצאת ? - חלק מסמנטיקת אותו המשתנה –לאן ללכת ? - חלק מסמנטיקת האב נייצג כל נקודת יציאה בעזרת תכונה נורשת (מסוג תווית) –לדוגמה: B.false, B.true –פירוש: "היכן להמשיך אם נבחרה נקודת יציאה מסוימת" ברגע שנסיים לתרגם את כל המבנה הבוליאני, נדע רק אז לחשב את התכונות. אין צורך לחשב את ערכי התנאים הבוליאניים 15

16 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; המשתנה B יגזור ביטוי בוליאני. יש לו 2 יציאות אפשריות: אחת true ואחת false בהתאם לערך הביטוי 16

17 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; לקטע הקוד של המשתנה S צריכה להיות יציאה אחת (לפי תכונת next). אלא ש-S יכול לצאת גם אל הפקודה הבאה 17

18 חסרונות השיטה לא מתאימה לניתוח סמנטי בזמן bottom-up –לא כל התכונות נוצרות –צריך לבנות עץ גזירה, למיין טופולוגית את חישובי התכונות על פי התלויות ולחשב אותן במעבר נוסף פיתרון: –להמנע מהורשת תוויות! –אבל...משתנה לא יכול לדעת באופן עצמאי לאן לקפוץ פיתרון לפיתרון: –במקום שהאבא יגיד לבן: נקודת היציאה שלך exit מופנית לתווית label –הבן יגיד לאב: אם הייתי יודע לאן exit מופנה הייתי רושם ערך זה "כאן, כאן,... וכאן". אתה לא מספר לי כלום! לכן אני מעביר אליך את האחראיות למלא את החורים שהשארתי! 18


Download ppt "תרגום לקוד ביניים 1. מבנה סכמתי של קומפיילר עד כה ראינו: בפועל: ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי backend ניתוח לקסיקלי ניתוח תחבירי ניתוח סמנטי."

Similar presentations


Ads by Google