תורת הקומפילציה תרגול 9: תרגום לקוד ביניים

Slides:



Advertisements
מצגות קשורות
הכרת תוכנת בקרים. כניסה לתוכנה תתבצע בשלבים הבאים: 1
Advertisements

אוגרים ומונים – Registers & Counters
למנוע שגיאות בעזרת הכלים של "האתגר 5": המקרה של נקודת פיתול
חקירת פונקציה נקודות קיצון אקסטרמום(קיצון) בקטע סגור תחומי עליה וירידה
אוגרים ומונים – Registers & Counters
תכנות בשפת C תרגול 11 - קבצים.
פרסום וקידום מכירות בכל שלב במחזור חיי המוצר, משתנה מדיניות התקשורת השיווקית שלו. פרט את מטרת התקשורת השיווקית בשלושה שלבים במחזור חיי מוצר כלשהו שתבחר.
הרצאה 02 סוגי משתנים קרן כליף.
תרגול מס' 1: מנהלות חזרה על ארכיטקטורת ה- MIPS
מבוא לתכנות ב-JAVA מעבדה 1
סוגים של מזגנים.
תרגול 11 מלכודות בניית ה-Debugger
פינוק מסביב לעולם מחזות זמר הסבר הזמנה ומימוש.
נערך ע"י אריק הוד, הגימנסיה העברית הרצליה
Marina Kogan Sadetsky –
רמי כהן, מדעי המחשב, הטכניוןכל הזכויות שמורות ©
Jump tables, review questions
הרצאה 3: משפטים, תנאים ולולאות
מבוא למדעי המחשב הרצאה מספר 12: רקורסיה
תכנות בשפת C תרגול 11 רשימות מקושרות מבנים
פעולות אריתמטיות קרן כליף.
תירגול 11: מיונים וחיפוש בינארי
נערך ע"י אריק הוד הגימנסיה העברית הרצליה

Entity Relationship Diagram – ERD
פרק 5 – ארכיטקטורות של מוצרים לניתוח רב-מימדי
נכתב ע"י אלכס קוגן ניתוח תחבירי Top-Down נכתב ע"י אלכס קוגן סמסטר חורף, תשס"ח.
OOO Execution of Memory Operations
Engineering Programming A
ניתוח עקיבות.
פיתוח מערכת מידע איך ???.
תירגול 2: מבוא לתיכנות ב-C
רובוטיקה תרגול שימוש בלולאות
שימור תנע בהתנגשויות קובץ זה נועד אך ורק לשימושם האישי של מורי הפיזיקה ולהוראה בכיתותיהם. אין לעשות שימוש כלשהו בקובץ זה לכל מטרה אחרת ובכלל זה שימוש מסחרי;
© האוניברסיטה העברית בירושלים, 2008
כל הזכויות שמורות לגבריאל אנקרי © 2017
© המרכז להוראת המדעים האוניברסיטה העברית בירושלים
מבוסס על שקפים מאת יאן ציטרין
מבוא לתכנות למערכות מידע
מבנה מחשבים ספרתיים זכרון וירטואלי מבוסס על תרגול של מורן גביש
Computer Architecture and System Programming Laboratory
כל הזכויות שמורות לגבריאל אנקרי © 2017
Branch Prediction בעריכת אורן קצנגולד Updated by Franck Sala.
תרגול 13 : חזרה נכתב על-ידי לימור ליבוביץ נערך ע"י ישראל גוטר
המודל ההיסטורי של התפתחות אמצעי התקשורת:
Marina Kogan Sadetsky –
Solving Simultaneous Linear Equations Using GPU
© המרכז להוראת המדעים האוניברסיטה העברית בירושלים
תוכנה 1 תשס"ח סמסטר ב' אוהד ברזילי ליאור שפירא
אוטומטים ושפות פורמליות
שימוש בעצם ממחלקה אחרת כמאפיין במחלקה הנוכחית
מבוא לתכנות ב- JAVA מעבדה 4
SQL: מושגים עמודה, תכונה, שדה, אטריביוט טבלה, רלציה סכמה
מבוא למדעי המחשב סמסטר ב' – 2008 מרצה: יעל סיגל מתרגל: ענבל בודובסקי.
מצביעים Pointers – המשך...
מעובד על ידי יוסי לבנון מתוך מצגות שכתב וערך ד"ר שמואל כהן
(או כיצד ללמוד בצורה נכונה מתחילת הסמסטר)
(או כיצד ללמוד בצורה נכונה מתחילת הסמסטר)
מבוסס על שקפים מאת יאן ציטרין
הצג את עצמך, את עמותת תפוח ואת נושא הפעילות.
תרגול מס' 2: Data and Control Hazards
ניהול שינויים במחסן נתונים יש עומק היסטורי הארגון משתנה במשך הזמן
מודל ניהול פרסום.
עקרונות תכנות מונחה עצמים תרגול 9:C++ - תרגילים
מיומנויות תקשורת והקשבה
Java Programming רשימות מקושרות - המשך
Engineering Programming A
תמליל מצגת:

תורת הקומפילציה תרגול 9: תרגום לקוד ביניים עודכן: סמסטר אביב 2012

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

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

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

דוגמה a = b + c + d t1 := b + c t2 := t1 + d a := t2 מדוע צריך את t2?

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

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

פונקציות לפריסת קוד פונקציות עזר: newtemp(): יוצרת משתנה זמני חדש (בעל מזהה ייחודי), כולל הכנסתו לsymbol table. newlabel(): מחזירה תווית חדשה. gen(string) : מקבלת מחרוזת שמייצגת פקודות ומייצרת את הפקודות בשפת הביניים.

שיטות לייצור קוד נציג 2 שיטות לייצור קוד: שיטה ראשונה: הקוד נאגר בתכונה סמנטית בשם code: לכל משתנה בדקדוק יש תכונה סמנטית בשם code, אשר אוגרת את הקוד שנוצר מהמשתנים שכבר נגזרו. בסוף הניתוח התכונה code של המשתנה התחילי מכילה את כל הקוד של התוכנית.

שיטה ראשונה ליצירת קוד - דוגמה דוגמה: תרגום ביטויים אריתמטיים נגדיר למשתנה E את התכונות code ו-place (place יכיל את המשתנה הזמני אליו נשמר ערך הביטוי). E  E1 + E2 { E.place = newtemp(); E.code = E1.code || E2.code || gen (E.place ‘:=‘ E1.place ‘+’ E2.place); } יצירת מקום לתוצאה יצירת הקוד: t1  E1 t2  E2 t3 := t1 + t2

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

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

השוואה בין שתי השיטות בשיטה 1 ניתן לקבוע את הסדר של קטעי הקוד ובשיטה 2 – לא ניתן למשל: E.code = E2.code || E1.code || E.place || “:=“ || E1.place || “+” || E2.place; במקום: E.code = E1.code || E2.code || שיטה 2 פשוטה ומהירה יותר אין שרשורי קוד.

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

הקושי כאשר מתרגמים מבנה בקרה, יעדי הקפיצות לא תמיד ידועים. לדוגמה: if B then S1 else S2 לכאורה, יש יותר מנקודת יציאה אחת: יש לבצע קטע קוד אחד במקרה והתנאי הבוליאני מתקיים, או קטע קוד אחר במקרה והתנאי אינו מתקיים. איך המנתח יידע את מי משני קטעי הקוד עליו למקם מיד אחרי קטע הקוד לבדיקת התנאי B?

פתרון לבעיית if B then S1 else S2 קטע הקוד שאחריו ימשיך לביצוע של S1 או S2 על פי ערכו של המשתנה הזמני. קטע הקוד השקול בשפת ביניים, לאחר תרגום פשוט: code that evaluates some_expression into t13 if t13==0 goto L54 code for some_code_1 goto L55 L54: code for some_code_2 L55:

דוגמה- הקוד לשיערוך הביטוי הבוליאני 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 ':');

דוגמה- תרגום פשוט עבור פקודת תנאי 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 ':');

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

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

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

דוגמה – תרגום משפט if מורכב S → if B then S1 else S2 B → B1 or B2 B → E1 ’>’ E2 התכונות (הנורשות): B.false : התווית אליה תעבור התוכנית במקרה שערך הביטוי הוא false. B.true: התווית אליה תעבור התוכנית אם ערך הביטוי הוא true. S.next: התווית אליה נעבור בסיום הפקודה S.

דוגמה – תרגום משפט if מורכב S → if B then S1 else S2 B → B1 or B2 B → E1 ’>’ E2 התכונות (הנורשות): B.false : התווית אליה תעבור התוכנית במקרה שערך הביטוי הוא false. B.true: התווית אליה תעבור התוכנית אם ערך הביטוי הוא true. S.next: התווית אליה נעבור בסיום הפקודה S.

דוגמה – תרגום משפט if מורכב סכימת התרגום: 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 → E1 ’>’ E2 E1.code E2.code if (E1.place > E2.place) goto B.true goto B.false תזכורת: זהו המשתנה הזמני שהוקצה לביטוי (למשל מיקום במחסנית) 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.code B2.code false true true B1.false: false B → B1 or B2 { B1.true = B.true; B2.true = B.true; B1.false = newlabel(); B2.false = B.false; B.code = B1.code || gen (B1.false ‘:’) || B2.code; }

המשך הדוגמה – הקוד עבור הביטוי הבוליאני B → B1 or B2 B1.code B2.code false true true B1.false: false הערות: הבדיקות מבוצעת בשיטת lazy evaluation : ברגע שהתשובה ידועה מפסיקים לחשב. המשמעות היא כמו של האופרטור || ולא כמו האופרטור | סדר החישוב לא ידוע מראש, והפעולות של אותו כלל לא בהכרח מבוצעות ברצף.

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

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