300 likes | 499 Views
שפות ביניים: יצירת הקוד. Aho, Sethi and Ullman – Ch. 8. int fib(int n) { if (n<=1) return 1; return fib(n-1) + fib(n-2); } “gcc –S fib.c” creates fib.s: .fib: mflr 0 ; r0 := lr stw 29,-12(1) ; *r1-12 := r29 stw 31,-4(1) ; *r1-4 := r31 stw 0,8(1) ; *r1+8 := r0 (lr)
E N D
שפות ביניים: יצירת הקוד Aho, Sethi and Ullman – Ch. 8
int fib(int n) { if (n<=1) return 1; return fib(n-1) + fib(n-2); } “gcc –S fib.c” creates fib.s: .fib: mflr 0 ; r0 := lr stw 29,-12(1) ; *r1-12 := r29 stw 31,-4(1) ; *r1-4 := r31 stw 0,8(1) ; *r1+8 := r0 (lr) stwu 1,-72(1) ; r1 := r1-72, *r1=r1 mr 31,1 ; r31 := r1 stw 3,96(31) ; *r31+96 := r3 (‘n’) lwz 0,96(31) ; r0 := *r31+96 (‘n’) cmpwi 0,0,1 ; cr0 := r0 ~ 1 bgt 0,L..3 ; if cr0.gt goto L..3 li 3,1 ; r3 := 1 b L..2 ; goto L..2 (return 1) L..3: L..3: lwz 9,96(31) ; r9 := *r31+96 (‘n’) addi 0,9,-1 ; r0 := r9 - 1 mr 3,0 ; r3 := r0 bl .fib ; call fib(n-1) mr 29,3 ; r29 := r3 lwz 9,96(31) ; r9 := *r31+96 (‘n’) addi 0,9,-2 ; r0 := r9 - 2 mr 3,0 ; r3 := r0 bl .fib ; call fib(n-2) mr 9,3 ; r9 := r3 add 0,29,9 ; r0 := r29 + r9 mr 3,0 ; r3 := r0 b L..2 ; goto L..2 L..2: lwz 1,0(1) ; r1 := *r1 lwz 0,8(1) ; r0 := *r1+8 mtlr 0 ; lr := r0 lwz 29,-12(1) ; r29 := *r1-12 lwz 31,-4(1) ; r31 := *r1-4 blr ; goto lr (return) יצירת קוד – דוגמא פשוטה 'מהחיים'
יצירת קוד • אפשרות א' –צבירת קוד במשתני ביניים של המהדר (בתכונות מסוג code) • אפשרות ב' –יצירת קובץ המכיל את הקוד תוך כדי תהליך הקומפילציה • אפשרות זו מעשית אם לכל חוק דקדוק תכונת ה- code של אגף שמאל של החוק מתקבלת משרשור תכונות ה- code של הלא-טרמינלים באגף ימין של החוק על פי סדר הופעתן (אולי בצירוף מחרוזות נוספות)
הכרזות מקוננות משפטי השמה • דקדוק המסגרת • ביטויים ומשפטי השמה • הערה – ניתן לעשות שימוש חוזר במשתנים זמניים על ידי ניהולם במחסנית
ייצוג נומרי ביטויים בוליאניים false – 0 true – 1 • הערה – כתובת המטרה ניתנת לחישוב תוך כדי יצירת הקוד
E E or E a < b E and E c < d e < f ביטויים בוליאניים בייצוג מספרי – דוגמא
E E or E a < b E and E c < d e < f ביטויים בוליאניים בייצוג מספרי – דוגמא
E E or E a < b E and E c < d e < f ביטויים בוליאניים בייצוג מספרי – דוגמא
E E or E a < b E and E c < d e < f ביטויים בוליאניים בייצוג מספרי – דוגמא
E E or E a < b E and E c < d e < f ביטויים בוליאניים בייצוג מספרי – דוגמא
E E or E a < b E and E c < d e < f ביטויים בוליאניים בייצוג מספרי – דוגמא
ביטויים בוליאניים – חישוב מקוצר • בניגוד לביטויים אריתמטיים, בביטויים בוליאניים ניתן לעיתים לדעת מה התוצאה כבר באמצע הדרך. • למשל, בביטוי E1or E2, אם E1 הוא true הרי שלא חשוב לנו מה ערכו של E2! • חישוב כזה נקרא lazy evaluation אוshort circuit boolean evaluation.
100: if a < b goto 103 101: T1 := 0 102: goto 104 103: T1 := 1 104: if c < d goto 107 105: T2 := 0 106: goto 108 107: T2 := 1 108: if e < f goto 111 109: T3 := 0 110: goto 112 111: T3 := 1 112: T4 := T2 andT3 113: T5 := T1 andT4 100: if a < b goto 105 101: if !(c < d) goto 103 102: if e < f goto 105 103: T := 0 104: goto 106 105: T := 1 106: ביטויים בוליאניים – חישוב מקוצר a < b or (c < d and e < f)
ביטויים בוליאניים – חישוב מקוצר • האם החישוב המקוצר שקול לחלוטין לחישוב הרגיל? • מתי אסור להשתמש בחישוב מקוצר? • מתי חייבים להשתמש בחישוב מקוצר?
ביטויים בוליאניים – ייצוג באמצעות הפניית בקרה • ההקשר – משפטים מותנים • השיטה – לכל ביטוי נצמיד שתי תויות • B.true – התווית אליה החישוב צריך לעבור אם B הוא true • B.false – התווית אליה החישוב צריך לעבור אם B הוא false
→ to B.true B.code → to B.false B.true: S1.code B.false: . . . משפטים מותנים • if–then • הערה – B.false ו- S.next הן תכונות נורשות • הערה – צריך להוסיף קוד ליצירת התווית S.next: מיד אחרי הקוד של S • הערה – המדובר בכתובות סימבוליות
משפטים מותנים • if–then–else →to B.true →to B.false
חישוב ביטויים בוליאניים על ידי הפנית בקרה • איזו צורת חישוב מוצגת כאן?
backpatching – תיקון לאחור • קושי – זו אינה סכימה ש"קל לחשב": • היא לא S-attributed (יש גם תכונות נורשות) • היא לא L-attributed (התכונות הנורשות אינן בהכרח נורשות-משמאל) • לכן צריך לחשב אותה בעזרת האלגוריתם הכללי, ואי אפשר לעשות זאת תוך כדי הניתוח. • דרך מקובלת לפתור בעיה זו – ניהול רשימת התחייבויות ותיקונן בהמשך • זו דרך כללית להמיר כל תכונה נורשת בתכונה נוצרת
backpatching – תיקון לאחור • ה"תיקון בהמשך" נקרא backpatching. • טכניקה • makelist ( i ) – יצירת רשימת התחייבויות חדשה המכילה את i. התוצאה – מצביע לרשימה • i הוא מספר שורה ברשימת הרביעיות שלנו • merge ( p1, p2 ) – איחוד הרשימות אליהם מצביעים p1ו- p2. מחזיר מצביע לתוצאה. • backpatch ( p, i ) – הכנסת i כתווית בכל אחת מהרביעיות שברשימה אליה מצביע p
backpatching – תיקון לאחור • אגירת הקוד הנוצר: • בשיטה הקודמת לא ידענו מה יהיה סדר החישוב של התכונות • זה היה תלוי במיון טופולוגי • לכן היינו צריכים לאגור את הקוד הנוצר בתכונה code, ולדאוג בעצמנו שהוא יופיע בסדר הנכון (ע"י שרשור) • לדוגמא:
backpatching – תיקון לאחור • אגירת הקוד הנוצר: • כעת סדר החישוב ידוע: • הניתוח הסמנטי יתבצע במהלך הניתוח התחבירי • הסדר יהיה bottom-up (נניח תמיד ניתוח LR) • לא חייבים לאגור את הקוד בתכונה code • אפשר מייד להדפיס אותו ל- buffer (emit) • צריך לדאוג להדפיס את הקוד בסדר הנכון • "אין חרטות", פרט ל- backpatch • ההבדל בין emit ל- gen: genמחזירה את הפקודה שנוצרה; emit מדפיסה אותה ל- buffer.
תיקון לאחור • nextquad – הרביעיה הבאה • truelist – רשימת התחייבויות למקרה true • falselist – רשימת התחייבויות למקרה false
B.t = {100, 104} B.f = {103, 105} B.t = {100} B.f = {101} or M.q = 102 B.t = {104} B.f = {103, 105} a < b and M.q = 104 B.t = {102} B.f = {103} B.t = {104} B.f = {105} c < d e < f תיקון לאחור
B.t = {100, 104} B.f = {103, 105} B.t = {100} B.f = {101} or M.q = 102 B.t = {104} B.f = {103, 105} a < b and M.q = 104 B.t = {102} B.f = {103} B.t = {104} B.f = {105} c < d e < f תיקון לאחור
B.t = {100, 104} B.f = {103, 105} B.t = {100} B.f = {101} or M.q = 102 B.t = {104} B.f = {103, 105} a < b and M.q = 104 B.t = {102} B.f = {103} B.t = {104} B.f = {105} c < d e < f תיקון לאחור
B.t = {100, 104} B.f = {103, 105} B.t = {100} B.f = {101} or M.q = 102 B.t = {104} B.f = {103, 105} a < b and M.q = 104 B.t = {102} B.f = {103} B.t = {104} B.f = {105} c < d e < f תיקון לאחור
B.t = {100, 104} B.f = {103, 105} B.t = {100} B.f = {101} or M.q = 102 B.t = {104} B.f = {103, 105} a < b and M.q = 104 B.t = {102} B.f = {103} B.t = {104} B.f = {105} c < d e < f תיקון לאחור
B.t = {100, 104} B.f = {103, 105} B.t = {100} B.f = {101} or M.q = 102 B.t = {104} B.f = {103, 105} a < b and M.q = 104 B.t = {102} B.f = {103} B.t = {104} B.f = {105} c < d e < f תיקון לאחור