פרק 7 סביבת הריצה
DESCRIPTION
פרק 7 סביבת הריצה. ניתוח ( analysis ). מנתח לקסיקאלי lexical analyser. מנתח תחביר syntax analyser. מנתח משמעות semantic analyser. מייצר קוד ביניים intermediate code generator. מייעל קוד code optimizer. חיבור ( synthesis ). מייצר קוד code generator. - PowerPoint PPT PresentationTRANSCRIPT
2תורת הקומפילציהאיתן אביאור
ניתוח(analysis)
חיבור(synthesis)
syntax analyserמנתח תחביר
semantic analyserמנתח משמעות
מייצר קוד ביניים intermediate code generator
code optimizerמייעל קוד
code generatorמייצר קוד
lexical analyserמנתח לקסיקאלי
סביבה – ייצור קוד ביניים
מייצר קוד ביניים intermediate code generator
3תורת הקומפילציהאיתן אביאור
נושאים לדיוןמיקום עצמים בזיכרון•
שיטות הקצאת זיכרון•
פניה לעצמים•
קריאה לשגרות והעברת פרמטרים•
טבלת סמלים•
4תורת הקומפילציהאיתן אביאור
(Routinesשגרות ) – קטע קוד שיש לו תפקיד מסוים, ואשר(routineשגרה )
ניתן להעביר לו פרמטרים )אופציונלית(•
ניתן לקבל ממנו ערך מסוים )אופציונלית(•
שמות בשפות שונות
(routineשגרה )–
(subroutineתת-שגרה )–
(procedureנוהל )–
(functionפונקציה )–
כולם שקוליםלעניינו
5תורת הקומפילציהאיתן אביאור
מונחים הקשורים לשגרותשם השגרה, שמות הפרמטרים, טיפוסי ( headerכותרת )•
הפרמטרים והערך המוחזר.פסוק )מורכב בד"כ( המכיל את הקוד לביצוע ( bodyגוף )•כותרת שלאחריה גוף ( definitionהגדרה )•כותרת ללא גוף ( declarationהצהרה )•המקום בתוכנית בו מופיע שם השגרה ע"מ ( callקריאה )•
שתופעל שםהשגרה )או התוכנית הראשית( בה מופיעה ( callerקוראת )•
הקריאה לשגרה מסוימתהשגרה המסוימת שנקראה ( calleeנקראת )•
6תורת הקומפילציהאיתן אביאור
מונחים הקשורים לשגרות 2
( formal parametersפרמטרים פורמלים )•
שמות בהם מוזכרים הפרמטרים בהגדרת השגרהה
פרמטרים אקטואליים, ארגומנטים •
(actual parameters, arguments )
הערכים הספציפים שניתנו לפרמטרים בקריאה מסוימת
7תורת הקומפילציהאיתן אביאור
דוגמה לשגרות Pascal)נהלים ופונקציות( ב-
program sort (input, output); var a : array [0..10] of integer;
procedure readarray; var i : integer; begin for i := 1 to 9 do read ( a [ i ] ) end;
function partition (y, z : integer) : integer; var i, j, x, v: integer; begin ... end; procedure quicksort (m, n: integer); var i : integer; begin
if ( n > m ) then begin i := partition (m, n); quicksort (m,i-1); quicksort (i+1,n) end end;
begin a[0] := -9999; a[10] := 9999; readarray; quicksort(1,9) end.
8תורת הקומפילציהאיתן אביאור
הנחות יסוד לגבי שגרות ביצוע תוכנית מורכב הבקרה זורמת באופן סדרתי 1.
מסדרת צעדים, ובכל שלב הבקרה נמצאת במקום מסוים בתוכנית
ביצוע שגרה מתחיל בתחילתה, ובשלב מסויים 2.כשביצוע השגרה מסתיים הבקרה חוזרת לנקודה
שמיד לאחר המקום בו נקראה השגרה
9תורת הקומפילציהאיתן אביאור
עוד מונחיםקריאה מסוימת לשגרה בזמן הרצת ( activationהפעלה )•
התוכניתמשך הזמן בחיי התוכנית מרגע ( lifetimeזמן חיים )•
ששגרה הופעלה בהפעלה מסויימת, ועד שהיא הסתיימהאבחנה
: שני זמני חיים של שגרותעל סמך הנחות היסוד זרים זה לזה
אחד מהם מכיל ממש את השני אומסקנה
ניתן לצייר עץ של זרימת הבקרה בין השגרותבריצה מסוימת של תוכנית
10תורת הקומפילציהאיתן אביאור
(Recursionרקורסיה )שגרה ( non-recursive routineשגרה לא רקורסיבית )•
שעבורה זמני חיים של כל שתי הפעלות שלה זרים זה לזה
שגרה שעבורה זמן ( recursive routineשגרה רקורסיבית )•חיים של הפעלה אחת שלה עשויי להיות מוכל בתוך זמן חיים
של הפעלה אחרת
השגרה מפעילה את עצמה ( self-recursionרקורסיה עצמית )•
שגרה א' מפעילה ( mutual-recursionרקורסיה הדדית )•שגרה ב' ושגרה ב' שבה ומפעילה את שגרה א'
11תורת הקומפילציהאיתן אביאור
עץ הפעלה(Activation Tree)
עץ הפעלה הינו עץ אשר בו:
כל צומת מציין הפעלה של שגרה )שם וארגומנטים(1.
השורש הוא שגרה התחילית )או התוכנית הראשית(2.
צומת א' הינו ההורה של צומת ב' אם ורק אם הפעלת ב' 3.נעשתה מתוך הפעלת א'
צומת א' מופיע משמאל לצומת ב' אם ורק אם זמן החיים 4.של א' קדם לזמן החיים של ב'
12תורת הקומפילציהאיתן אביאור
עץ הפעלה – דוגמה
s
q (1, 9)r
p (1, 9) q (1, 3)
p (1, 3) q (2,3)q (1,0)
p (2,3) q (3,3)q (2,1)
q (5,9)
p (5,9) q (7,9)q (5,5)
p (7,9) q (9,9)q (7,7)
13תורת הקומפילציהאיתן אביאור
מחסנית הבקרה(Control Stack)
( על עץ ההפעלהDFTביצוע תוכנית הינו מעבר לעומק )•ניתן לשמור במחסנית את המסלול מהשורש עד המקום •
הנוכחי בעץ(control stackמחסנית הבקרה )מחסנית זו נקראת: •
דוגמה
המצב הנוכחי בעץ
מחסנית הבקרה
sq)1,9(q)1,3(q)2,3(
s
q ( 1, 9 )r
p ( 1, 9 ) q ( 1, 3 )
p ( 1, 3 ) q ( 2, 3 )q ( 1, 0 )
14תורת הקומפילציהאיתן אביאור
(Declarationהכרזה )( declarationהכרזה )•
משפט בשפה המכריז על קיומו של עצם )משתנה, קבוע, שגרה((nameשם העצם )–(typeטיפוס )–(static, auto, registerמחלקת זיכרון )–(const, volatileמאפיינים )– טיפוסי הפרמטריםלשגרות –
משפט ההכרזה המופיע ( explicit declarationהכרזה מפורשת )•בתוכנית
כאשר האזכור הראשון של ( implicit declarationהכרזה סתומה )•עצם בתוכנית מהווה את הכרזתו בברירת מחדל
INTEGER הם I..N עצמים ששמם מתחיל ב-Fortran ב-לדוגמה )אלא אם כן היתה הכרזה מפורשת REALובשאר האותיות הם
אחרת(
15תורת הקומפילציהאיתן אביאור
תחום הכרזה(Scope of Declaration)
( scope of definitionתחום הכרזה )•האזור בתוכנית בו עצם מוכר על סמך הכרזה מסוימת
( scope rulesחוקי תחום )•חוקי המשמעות של שפת התכנות הקובעים את תחומי
ההכרזות השונות
( localשם מקומי )•שם שתחום הכרזתו מוכל בשגרה )או הגוש( אותו בוחנים
( non-localשם לא-מקומי )•שם שתחום הכרזתו חורג מהשגרה )או הגוש( אותו בוחנים
16תורת הקומפילציהאיתן אביאור
קשירת שמות(Binding of Names)
( environmentסביבה )•הפונקציה הממפה שם )של עצם( לאזור בזיכרון בו ממומש העצם
הפונקציה הממפה אזור בזיכרון לערך המוחזק בו ( stateמצב )•
( bindingקשירה )•הפעולה המתבצעת ע"י הסביבה
s למקום בזיכרון Xכאשר הסביבה קושרת את השם )s )X is bound to s קשור ל-Xנאמר ש-
שם עשוי להיות קשור למספר עצמים שונים בזיכרון בעת ובעונהאחת
name storage value
environment state
Static NotionDynamic Counterpartdefinition of a procedureactivations of the procedure
declaration of a namebindings of the namescope of a declarationlifetime of a binding
17תורת הקומפילציהאיתן אביאור
הגורמים המשפיעים עלחלוקת הזיכרון והקשירה
האם שגרות עשויות להיות רקורסיביות?1.
מה קורה לערך של שם מקומי לאחר שהסתיימה הפעלת 2.השגרה בה הוא מוצהר?
האם שגרה יכולה לפנות לשמות לא-מקומיים?3.
איך מעבירים פרמטרים לשגרות?4.
האם ניתן להעביר שגרות כפרמטרים?5.
האם ניתן להחזיר שגרות כערך מוחזר?6.
האם ניתן להקצות זיכרון דינמי בשליטת התוכנית?7.
האם חייבים לשחרר זיכרון באופן מפורש?8.
18תורת הקומפילציהאיתן אביאור
ארגון הזיכרון
קוד = הוראות
נתונים סטטים
heapערמה
זיכרון חופשי stackמחסנית
כתובותנמוכות
כתובותגבוהות
19תורת הקומפילציהאיתן אביאור
רשומת הפעלה(Activation Record)
( frame( או מסגרת )activation recordרשומת הפעלה )שטח )בד"כ רצוף( המכיל את כל המידע הנחוץ להפעלה של
השגרה:
יכולים השדות המסומנים ב-•להיות כולם או חלקם באוגרים
האוגרים )שערכם הקודם נשמר •בשדה המצב( יכולים לשמש
כ"הרחבה" של רשומת ההפעלה
משתנים זמניים
משתנים מקומיים
מצב המכונה הקודם
קישורית גישה )אופ'(
קישורית בקרה )אופ'(
ערך מוחזר
ארגומנטים
21תורת הקומפילציהאיתן אביאור
הקצאה סטטיתלכל שגרה קיימת רשומת הפעלה אחת,
שבה משתמשים בכל הפעלה של השגרה
יתרונותחיסכון במקום ובזמן ריצה לבניית הרשומה•ערכי המשתנים המקומיים נשמרים מהפעלה להפעלה•הכתובות המדויקות של כל הפרמטרים והמשתנים ידועות •
בזמן התרגום וניתן להשתמש בהן ישירות
מגבלותחייבים לדעת מראש בזמן התרגום את הגודל של כל •
העצמיםהפעלה רקורסיבית מוגבלת•אין אפשרות להקצאה דינמית תוך כדי ריצה•
22תורת הקומפילציהאיתן אביאור
דוגמההקצאה סטטית PROGRAM CNSUME
CHARACTER 50 BUFINTEGER NEXTCHARACTER C, PRDUCEDATA NEXT /1/, BUF /’ ‘/
6 C = PRDUCE) ( BUF ) NEXT : NEXT ( = C NEXT = NEXT + 1 IF ) C .NE. ‘ ‘ ( GOTO 6 WRITE ) , ‘)A(’ ( BUF END
CHARACTER FUNCTION PRDUCE) (CHARACTER 80 BUFFERINTEGER NEXTSAVE BUFFER, NEXTDATA NEXT /81/ IF ) NEXT .GT. 80 ( THEN
READ ), ‘)A(’ ( BUFFER NEXT = 1
END IF PRODUCE = BUFFER ) NEXT : NEXT ( NEXT = NEXT + 1 END
קוד
נתוניםסטטיים
רשומת ההפעלהCNSUMEשל
רשומת ההפעלהPRDUCEשל
CNSUME הקוד של
PRDUCE הקוד של
CHARACTER50 BUFINTEGER NEXTCHARACTER C
CHARACTER80 BUFFERINTEGER NEXT
23תורת הקומפילציהאיתן אביאור
הקצאה במחסניתלכל הפעלה של שגרה, נבנית רשומה במחסנית, ובסיום השגרה הרשומה
מתבטלתהרשומה הפעילה נמצאת בראש המחסנית• המצביע אל אוגר המסגרת אפשר שיהיה אוגר נוסף spבנוסף לאוגר ה-•
מקום קבוע בתוך רשומת ההפעלה–VAX: Frame Pointer, Argument Pointer–8086 :Base Pointerמעבדים אחרים: אוגר כללי כלשהו המוקצה לצורך כך–
כלומר נוצרת רשימה מקושרת קישורית הבקרה היא ערכו הקודם של אוגר זה של רשימות הפעלה
בסיס + הגישה לעצמים שבתוך רשומת ההפעלה תיעשה בשיטת מיעון•, מפני שכל עצם נמצא במרחק ידוע מראש (base-displacementהעתק )
בתוך רשומת ההפעלה )בהנחה שגודל מערכים ידוע בזמן התרגום(
24תורת הקומפילציהאיתן אביאור
הקצאה במחסנית מיקוםדוגמה
בעץ ההפעלהרשומות הפעלה
על המחסנית הערות
s sa : array s מסגרת עבור
s
r
sa : array
ri : integer
r הופעלה
s
q (1,9)r
sa : arrayq ( 1, 9 )i: integer
נשלפה r המסגרת של נדחפה q (1,9) וזאת של
s
q (1,9)r
p (1,9) q (1,3)
p (1,3) q (1,0)
sa : arrayq ( 1, 9 )i: integerq ( 1, 3 )i: integer
הבקרה זה עתה q (1,3) חזרה אל
25תורת הקומפילציהאיתן אביאור
בנית רשומת ההפעלה במחסנית
חלק מהשדות ברשומה בונה השגרה הקוראת וחלק הנקראת, למשל:
הקוראתהמקום לערך מוחזר ואת הפרמטרים •מפני שהיא יודעת כמה פרמטרים מעבירה לשגרה, ואילו
השגרה עשויה להיות מופעלת בכל פעם עם מספר משתנה של פרמטרים
הנקראתהמקום למשתנים מקומיים וזמניים •מפני שהמידע על גודלם נמצא רק בידיה
יכולים להיבנות הן ע"י הקוראת והן הקישורים + מצב הנשמר •ע"י הנקראת
בד"כ עדיף שהשגרה הנקראת תבצע בעצמה כמה שיותר מפני שאז הקוד מופיע רק פעם אחת
26תורת הקומפילציהאיתן אביאור
סדר קריאה וחזרה(Calling end Return Sequence)סדר הפעולות המוסכם המתבצע בקריאה לשגרה ע"י •
(calling sequenceסדר קריאה )הקוראת והנקראת נקרא סדר הפעולות המוסכם המתבצע בחזרה משגרה ע"י •
(return sequenceסדר חזרה )הקוראת והנקראת נקרא
:מוסכמות אלה תלויות בשפת המקור–מכונת המטרה–מערכת ההפעלה–טעם אישי של בונה המהדר–
27תורת הקומפילציהאיתן אביאור
דוגמה לסדר קריאההשגרה הקוראת
מחשבת ערכי ארגומנטים ומכניסה למחסניתא.
מקצה מקום במחסנית לערכים מוחזריםב.
שומרת את המצב ומפעילה את השגרה הנקראתג.
השגרה הנקראת
ממשיכה לשמור מצב )אוגרים נוספים( במידת הצורךד.
מעדכנת את אוגר המסגרת להצביע על הרשומה שלה ה.
מקצה מקום למשתנים מקומיים וזמנייםו.
מתחילה ביצועז.
28תורת הקומפילציהאיתן אביאור
דוגמה לסדר חזרההשגרה הנקראת
מחשבת ערך מוחזר ומציבהא. משחררת את המקום של המשתנים המקומיים והזמנייםב. משחזרת את אוגר המסגרת ושאר האוגרים ששמרהג. חוזרת לשגרה הקוראתד.
השגרה הקוראתמשחזרת מצב )אם לא נעשה אוטומטית( ה.מעתיקה את הערכים המוחזרים ליעדם, ומשחררת את המקום ו.
שלהם במחסניתמשחררת את המקום של הארגומנטיםז.
29תורת הקומפילציהאיתן אביאור
מבנה המחסנית ורשומות ההפעלה
מצביעהמסגרת
רשומתההפעלה
של הנקראת
רשומתההפעלה
של הקוראת
באחריותהנקראת
באחריותמשתנים מקומיים וזמנייםהקוראת
קישורית בקרהמצב שמור )אוגרים(
ארגומנטים וערכים מוחזרים
משתנים מקומיים וזמנייםקישורית בקרה
מצב שמור )אוגרים(ארגומנטים וערכים מוחזרים
30תורת הקומפילציהאיתן אביאור
רשומות ללא מערכיםבגודל משתנה
, מערכים אינם מועברים כפרמטרים ע"י ערך )אלא Cבשפת •ע"י כתובת( וגודלם של מערכים מקומיים חייב להיות ידוע בזמן
התרגום
באופן זה, מבנה רשומת ההפעלה והמיקום היחסי של כל עצם •בתוכה ידוע מראש
כאשר מדובר באפשרות להעביר לשגרה מספר משתנה של •(, הארגומנט הראשון )שבו printfארגומנטים )כמו למשל
המפתח להבנת שאר הארגומנטים( יימצא הכי קרוב )ולכן במרחק קבוע( לקישורית הבקרה
כדאי להכניס את הארגומנטים למחסנית ב"סדר כלומר הפוך"
31תורת הקומפילציהאיתן אביאור
מערכים בגודל משתנהישנן שפות בהן ניתן לכתוב:
int func ( int n, char a[n] ){char b[n];...
}כלומר גודלו של מערך מקומי נקבע ע"פ ערך פרמטר שהשגרה מקבלת•קיומם של מערכים בגודל שאינו ידוע מראש בזמן התרגום בתוך אזור •
המשתנים המקומיים ישבש את חישובי ההעתק של העצמים השונים ברשומת ההפעלה, ולא ניתן יהיה לקבוע אותם חד-משמעית בזמן
התרגוםיהיה צורך בחישובים "מיותרים" בזמן ריצה•
32תורת הקומפילציהאיתן אביאור
רשומת הפעלה עם מערכיםבגודל משתנה
המערך יימצא •מעבר לחלק
הקבוע של רשומת ההפעלה
בחלק הקבוע יהיה •מצביע אל המערך
B מערך
A מערך
משתנים
מקומיים
וזמניים
קישורית בקרה
מצב קודם
ערכים מוחזרים
וארגומנטים
מצביעמסגרת
Aמצביע ל-Bמצביע ל-
33תורת הקומפילציהאיתן אביאור
מחוונים מתנדנדים(Dangling References)
שחרור אוטומטי של זיכרון עלול לגרום לשגיאות אם לא מביאים
את קיומו בחשבון:
main(){
int p;p = dangle( );
}
int dangle( ){
int i = 23;return &i;
}
תיקון אפשרי: צריך להיות סטטיiהמשתנה
static int i = 23 ;
תיקון נוסף: יוקצה באופן דינמיiהמשתנה
return new int(23) ;
34תורת הקומפילציהאיתן אביאור
הקצאה בערימהאפשר להקצות את רשומת ההפעלה מתוך הערימה כאשר:
הערכים של עצמים מקומיים חייבים להישמר גם לאחר סיום 1.ההפעלה של השגרה
זמן החיים של ההפעלה של השגרה הנקראת חורג מזמן 2.החיים של השגרה הקוראת
בלתי אפשרי במודל שהנחנו מקודם–אפשרי כאשר השגרה הנקראת מופעלת כתהליך –
(process( או משימה )task( או תהליכון )thread במקביל )לשגרה הקוראת
35תורת הקומפילציהאיתן אביאור
דוגמההקצאה בערימה מיקום
בעץ ההפעלהרשומות הפעלה
על המחסנית הערות
s
q (1,9)r
רשומת ההפעלהrשל השגרה
נשמרת
s
קישורית בקרה
r
קישורית בקרה
q( 1, 9)
קישורית בקרה
36תורת הקומפילציהאיתן אביאור
ניהול הערימהמאחר וסדר השחרורים בערימה אינו תמונת ראי של סדר •
ההקצאות נוצרים אזורים מבודדים של זיכרון חופשי
(fragmentationשיבוב )מצב זה נקרא •מאחר וההקצאות הדרושות הינן של שטחים רציפים, השיבוב •
עשוי לגרום לבזבוז וחוסר מדומה של מקוםישנן אסטרטגיות שונות להקצאה במטרה להקטין את תוחלת •
המקום המבוזבז( שבהן המערכת התומכת lisp, javaישנן מערכות ושפות )•
אוטומטי(garbage collectionאיסוף זבל )מבצעת במערכות אלה אובייקט חי עשוי לשנות את מקומו בזיכרון, ויש •
צורך לשנות את ערכי המצביעים אליו
used freeused freeused freeused
37תורת הקומפילציהאיתן אביאור
גישה לשמות לא-מקומייםחוקי הגישה של השפה קובעים כיצד ניגשים לשמות לא-מקומיים
static( או תחום סטטי )lexical scope תחום לקסיקאלי )חוק•
scope)
C, Pascal, Ada, Perlמקובל יותר ― למשל בשפת –
(dynamic scope תחום דינמי )חוק•
Lisp, APL, Snobol, Perlפחות מקובל ― למשל –
38תורת הקומפילציהאיתן אביאור
(Blockגוש ) (blockגוש )
פסוק מורכב היכול להכיל הצהרות של שמות מקומיים
גוש נתחם ע"י סימנים של השפה–C } { –Pascal begin end
חפיפה בין גושים אפשרית אך ורק אם גוש אחד מכיל בשלמותו את גוש השני
39תורת הקומפילציהאיתן אביאור
חוקי תחום של גושיםB כוללת את Bהתחום של הצהרה המופיעה בגוש 1.
B ב-x, אזי הופעה של B איננו מוגדר בגוש xאם השם 2.
כך B הכולל את B בבלוק 'xתהיה בתחום של הצהרה על
ש:
B בגוש 'xישנה הצהרה על א.
מבין כל x הינו הגוש הקטן ביותר המכיל ההצהרה על B'ב.
Bהגושים הכוללים את
40תורת הקומפילציהאיתן אביאור
דוגמהגושים main( ){
int a = 0 ;int b = 0 ;{
int b = 1 ;{
int a = 2 ;printf (“%d %d\n”, a, b);
}{
int b = 3 ;printf (“%d %d\n”, a, b);
}printf (“%d %d\n”, a, b);
}printf (“%d %d\n”, a, b);
}
B0 B1B2
B3
DeclarationScopeint a = 0 ;B0 B2
int b = 0 ;B0 B1
int b = 1 ;B1 B3
int a = 2 ;B2
int b = 3 ;B3
41תורת הקומפילציהאיתן אביאור
הקצאת הזיכרון לגושיםשתי שיטות אפשריות:
נתייחס לגוש כאל שגרה חסרת פרמטרים•
נקצה זיכרון בכניסה לגוש~
נשמור זיכרון ביציאה מהגוש~
יתרוןחיסכון במקום
חסרון )עלות בזמן )הקצאה ושחרור במיוחד כשהגוש נמצא בתוך לולאה
נקצה את כל הזיכרון הנחוץ לכלל הגושים של שגרה עם הכניסה לשגרה•
הזיכרון שלהם יכול להיות חופףגושים שאינם מכילים זה את זה ~
יתרוןחיסכון בזמן הקצאה/שחרור
חסרון)בזבוז מקום )למשל בהקצאת זיכרון גדול לגוש שאיננו מופעל
a0
b0
b1
a2,b3
42תורת הקומפילציהאיתן אביאור
תחום לקסיקאליללא קינון שגרות
אין אפשרות להגדיר שגרות מקוננות, Cבשפת ועל כן חוקי התחום פשוטים יותר
(1) int a[11];
(2) readarray( ) { … a … }
(3) int partition(int y,int z) { … a … }
(4) quicksort(int m,int n) { … }
(5) main( ) { … a … }מת ההפעלה בראש המחסניתושמות מקומיים נמצאים ברש•שמות לא-מקומיים )גלובליים( נמצאים בזיכרון סטטי, בכתובת •
קבועה
43תורת הקומפילציהאיתן אביאור
תחום לקסיקאלי עם קינון שגרות ניתן לקנן הגדרת שגרותPascalבשפת
program sort(input, output); var a : array [0..10] of integer; x : integer; procedure readarray; var i : integer; begin . . . a . . . end { readarray } ;
procedure exchange(i, j : integer); begin x := a[i]; a[i] := a[j]; a[j] := x end { exchange };
procedure quicksort(m, n: integer); var k, v : integer; function partition(y, z: integer):integer; var i, j :integer; begin . . . a . . . . . . v . . . . . . exchange(i, j); . . . end { partition } ; begin . . . end { quicksort }; begin . . . end { sort } .
44תורת הקומפילציהאיתן אביאור
תחום לקסיקאלי המשך עם קינון שגרות
השגרות המקוננותשמות מקומיים
שמות לא-מקומיים
)בשימוש(
sorta, x
read arrayia)sort(
exchangei, jx)sort(
quicksortm, n, k, v
partitiony, z, i, ja)sort(, v)quicksort(
45תורת הקומפילציהאיתן אביאור
(Nesting Depthעומק קינון )1עומק הקינון של התוכנית הראשית הוא •, q, המוגדרת בתוך שגרה pעומק הקינון של השגרה •
qהינו אחד יותר מעומק הקינון של
sort 1
readarray 2
exchange 2
quicksort 2
partition 3
46תורת הקומפילציהאיתן אביאור
Accessקישורית גישה )Link)
nמצביע מרשומת ההפעלה של שגרה בעומק קינון •n-1לרשומת ההפעלה של שגרה בעומק קינון
עשויה להופיע מספר n-1מאחר והשגרה בקינון •במחסנית )רקורסיה(, יש לקשר פעמים
לרשומה של ההפעלה האחרונה
s
a, xq)1,9(
access linkk, v
s
a, xq)1,9(
access linkk, v
q)1,3(access link
k, v
s
a, xq)1,9(
access linkk, v
q)1,3(access link
k, vp)1,3(
access linki, j
s
a, xq)1,9(
access linkk, v
q)1,3(access link
k, vp)1,3(
access linki, j
e)1,3(access link
47תורת הקומפילציהאיתן אביאור
איתור בעזרת קישוריות גישההנחות
בזמן התרגום ידוע עומק הקינון של כל שגרה•בזמן התרגום ידוע באיזה גוש/שגרה נמצאת ההצהרה של כל •
שם שתחום ההגדרה שלו כולל את הגוש/שגרה אליה מתייחסים כרגע
המשימה
a יש לאתר את הזיכרון של לא-מקומי pבשגרה
( ידועים בזמן תרגוםa )של na( ו-p )של npעומק הקינון
48תורת הקומפילציהאיתן אביאור
איתור בעזרת קישוריות גישה 2
השיטה
צעדים בעקבות קישוריות הגישה, ומצא את np – naלך •aהרשומה בה הוקצה הזיכרון ל-
a ברשומה ע"מ לאתר את aהשתמש בהסט )הקבוע( של •
אבחנה
(np – na, offsetכל שם )לא-מקומי( יש לייצג ע"י זוג מספרים )
הפרש עומקי הקינון בין השגרה המשתמשת והשגרה •המצהירה
הסט בין העוגן )קישורית הגישה( של הרשומה ובין מיקומו של •הזיכרון המקושר לאותו שם
49תורת הקומפילציהאיתן אביאור
בניית קישוריות גישהnq בעומק קינון q מפעילה את שגרה np בעומק קינון pשגרה
)1np < nq
np +1 = nq, ועל כן p מוגדרת ישירות בתוך qע"פ חוקי התחום –
p תצביע ישירות לקישורית של qהקישורית של –
•np nq
pעבור זהות nq-1 …1,2 השגרות בעומקים ,ע"פ חוקי התחום1(qו-
nq-1 תצביע לקישורית של השגרה בעומק qהקישורית של 2(p צעדים מהקישורית של np-nq+1שאותה ניתן לאתר ע"י
)3np-nq+1הוא מספר הידוע בזמן התרגום
50תורת הקומפילציהאיתן אביאור
שגרות כפרמטריםמועברתומעבירה כפרמטר שגרה נקראתמפעילה שגרה קוראתשגרה
דוגמה
program param(input, output);
procedure b(function h(n:integer): integer);
begin writeln(h(2)) end { b };
procedure c;
var : integer; function f(n : integer) : integer;
begin f := + n end { f }; begin := 0; b(f) end { c }; begin
c
end.
c קוראתb נקראתf מועברת
51תורת הקומפילציהאיתן אביאור
שגרות כפרמטרים המשך
השגרה המועברת לא תוכל לבנות בעצמה את קישורית •הגישה
לשגרה הנקראת אין מידע כיצד לבנות לשגרה המועברת את •קישורית הגישה
המידע הנחוץ לבנית קישורית הגישה לשגרה המועברת נתון •בידי השגרה הקוראת
מסקנה
יחד עם העברת כתובת השגרה המועברת יש להעביר גם את קישורית הגישה שלה
52תורת הקומפילציהאיתן אביאור
(Displayצג )המעבר על הרשימה המקושרת של קישוריות הגישה צורך זמן•
המכיל את אותה סדרהdניתן לבנות מערך •
–d[i] כתובת הרשומה )האחרונה ביותר( בעומק iבמחסנית
53תורת הקומפילציהאיתן אביאור
עדכון הצגצורה פשוטה
סדר הקריאה והחזרה משגרה כולל העברת קישוריות •הגישה מהמחסנית למערך הצג
בזבוז של זמן•
צורה יותר יעילההצג נשמר במערך גלובלי•:iבכניסה לשגרה בעומק קינון •
ברשומת ההפעלהd[i]שמור את תוכן – להצביע על הרשומת ההפעלה החדשהd[i]שנה את –
:iביציאה משגרה בעומק קינון • ע"פ הערך שנשמר ברשומת ההפעלהd[i]שחזר את –
54תורת הקומפילציהאיתן אביאור
תחום דינמי(Dynamic Scope)
#!/usr/local/bin/perl$s = 10;$d = 20;
sub show {print “$s $d “;
}
sub small {my $s = 11;local $d = 21;&show;
}
&show; &small; print “\n”;&show; &small; print “\n”;
output: 10 20 10 21 10 20 10 21
דוגמה
55תורת הקומפילציהאיתן אביאור
גישה לפי תחום דינמי(deep accessגישה לעומק )•
החיפוש במחסנית נערך ע"פ קישוריות הבקרה )ולא –קישוריות הגישה(
בגלל אפשרויות הרקורסיה, אין אפשרות לדעת בזמן –התרגום כמה צעדים יש לבצע עד שמוצאים את רשומת
ההפעלה הרלוונטית(shallow accessגישה רדודה )•
הערך של כל שם מוחזק בזיכרון סטטי–, היא שומרת את ערכו n מגדירה מחדש שם pכאשר שגרה –
הקודם ברשומת ההפעלה שלה ומשתלטת על המקום הגלובלי שלו
nביציאה מהשגרה משחזרים את הערך הקודם שהיה ל-–
56תורת הקומפילציהאיתן אביאור
העברת פרמטרים
(call by valueקריאה ע"י ערך )•
(call by referenceקריאה ע"י מראה מקום )•
(call by nameקריאה ע"י שם )•
57תורת הקומפילציהאיתן אביאור
העברה ע"י ערך(Call By Value)
int min (int a, int b) {
return a < b ? a : b ;
}
int x = 10, y = 20;
min (x, y) 10min (y, 30) 20min (30, 10) 10
השגרה הקוראת מחשבת
(r-valueאת ערכי הארגומנטים )
ומעבירה אותם לשגרה הנקראת
58תורת הקומפילציהאיתן אביאור
void swap(int a, int b)
{
int t;
t = a;
a = b;
b = t;
}
int x = 10, y = 20;
swap (x, y);
כישלון בקריאה ע"י ערך
ערכי הפרמטרים
a-ו bמתחלפים
ערכי
הארגומנטים
x-ו yמתחלפים
59תורת הקומפילציהאיתן אביאור
פתרון לקריאה ע"י ערך(copy-in copy-outהעתקה פנימה והחוצה )•(copy-restoreהעתקה ושחזור )•(value-resultערך ותוצאה )•
swap(x, y) push ypush x העברה ע"י ערךcall swappop xpop y העתקת
התוצאהFortranשיטה זו מיושמת ע"י חלק ממהדרי
הערה:ברוב שפות התכנות ישנו רק פרמטר תוצאה אחד
שהוא הערך המוחזר מהשגרה
60תורת הקומפילציהאיתן אביאור
קריאה ע"י מצביעים(Call By Pointer)
Cשפת
void swap( int a, int b) { int t;
t = a; a = b; b = t;
}
int x = 10, y = 20 ;
swap(&x,&y);
הארגומנטים עצמם )ערכי המצביעים( אינם מתחלפים
אלא הערכים עליהם הם מצביעים מתחלפים
מתחלפיםy ו-xערכי
61תורת הקומפילציהאיתן אביאור
קריאה ע"י מראה מקום(Call By Reference)
++C; שפת Fortran, Pascalחלק ממהדרי ה-
void swap( int &a, int &b)
{
int t;
t = a;
a = b;
b = t;
}
int x = 10, y = 20 ;
swap(x,y);
מתורגם ע"י המהדרכאילו היתה זו
העברה ע"י מצביעים
מתחלפיםy ו-xולכן ערכי
62תורת הקומפילציהאיתן אביאור
הבדלי משמעות בין ערך-תוצאה ומראה מקום
program copyout(input,output);
var a : integer;
procedure unsafe(var x : integer);
begin x := 2; a:= 0 end;
begin
a := 1; unsafe(a); writeln(a)
end.2אם ימומש בשיטת ערך-תוצאה הערך הסופי יהיה •0אם ימומש בשיטת מראה מקום הערך הסופי יהיה •
63תורת הקומפילציהאיתן אביאור
השוואת שיטות הקריאהערךערך-תוצאהמצביעיםמראה מקום
העתקה בכניסהכןכןלאלא
העתקה ביציאהלאכןלאלא
לאכןכןכן
ניתן לשינוי ע"י
השגרה
הנקראת
תחביר נוחכןכןלאכן
אובייקטים
גדולים
שחבל/אסור
להעתיק
אובייקטים שצריך
לשנות ובהעדר
שיטות אחרות
אובייקטים
קטנים
שצריך
לשנות
אובייקטים
קטניםשימושי
64תורת הקומפילציהאיתן אביאור
קריאה ע"י שם(Call By Name)
הארגומנטים מועברים בשמם, •והשגרה הנקראת מבצעת את הקישור למקום בזיכרון
דומה לקריאה למאקרו•שמות מקומיים נבדלים משמות לא-מקומיים•Algolהשיטה של שפת •
swap(i, a[i] )הקריאהתתפרש כ:
t = i; i = a[i]; a[i] = t;
( i )ערכו המקורי של t הפסוק האחרון יציב את המקורי(i )עם a[i] במקום לתא a[a[i]]לתא
65תורת הקומפילציהאיתן אביאור
המשךהעברה ע"י שם
באופן מלא בשיטת קריאה ע"י swapכנראה שלא ניתן לממש •
שם
מימוש קריאה ע"י שם נעשה ע"י העברת שגרה ללא פרמטרים •
ואשר תפקידה לחשב עבור השגרה הנקראת thunkהנקראת
של הפרמטר בכל פעם שיש r-value ו/או l-valueאת ערכי
צורך לעשות בו שימוש
66תורת הקומפילציהאיתן אביאור
Inlineשגרות דומה למאקרו ועל כן עלול ליצר קריאה ע"י inlineמימוש שגרות •
שםאם רוצים לשמור על המשמעות המקורית יש לייצר משתנים זמנים•
inline void swap(int &a, int &b){ int t; t = a; a = b; b = t;
}ניתן לבצע אופטימיזציה אח"כ במידת הצורך•
t1 = a ;t2 = b ;t = t1 ;t1 = t2 ;t2 = t ;b = t2 ;a = t1 ;
67תורת הקומפילציהאיתן אביאור
טבלת סמלים(Symbol Table)
הטבלה המרכזת מידע לגבי השמות שהוצהרו והתכונות שלהם•
שמות מסוגים שונים עשויים להיות בעלי תכונות שונות•
(double ומחזירה int לשגרה המקבלת שלושה int)השווה
ניתן ליישם ע"י רשומה אחידה המכילה תכונות משותפות לכל •
סוגי השמות ומצביע לחלק המשתנה
או לחילופין ע"י מחלקת בסיס ומחלקות יורשות•
68תורת הקומפילציהאיתן אביאור
השימוש בטבלת הסמליםבמידת הצורך )ע"פ חוקי השפה וצרכי המתרגם( הטבלה •
מאותחלת להכיל את מלות מפתחכאשר הסורק נתקל בשם הוא מחפש אותו בטבלת הסמלים•
מייצר כניסה חדשה בטבלהאם לא מצא –מעביר הלאה )לפורס( מצביע לכניסה–
הטבלה עשויה להכיל מספר עצמים שונים שיש להם אותו שם•הסורק שאיננו מודע לחוקי התחביר והתחום לא מסוגל –
לדעת לאיזה עצם ספציפי השם מתכווןמבנה הטבלה צריך לאפשר:–
איחוד כל העצמים בעלי אותו שם )עבור הסורק(•הפרדה בין העצמים עבור שאר חלקי המהדר•
69תורת הקומפילציהאיתן אביאור
אורך השמות
שפות שונות באות בגישות שונות
, . . . (L = 6, L = 8) תוויםLשם חייב להיות קצר מ-1.
תווים הינם Lשם יכול להיות באורך כלשהו אך רק 2.
משמעותים
(L = 31) . . . ,
שם יכול להיות באורך כלשהו וכל התווים משמעותים3.
(L < 256, L < 1024). . . ,
70תורת הקומפילציהאיתן אביאור
השמות בתוך טבלת הסמלים
כאשר ישנו חסם קטן על אורך השמות או על החלק הרלוונטי שלהם
כאשר אין חסם על אורך השמותאו החלק הרלוונטי שלהם
s o r t a r e a d a r r a y i
Name Attributes
Name Attributes
s o r t EOS a r e a d a r r a y iEOS EOS EOS
71תורת הקומפילציהאיתן אביאור
טבלה ליניאריתלאחר שלב הסריקה
הכניסות נשמרות במערך•בכל פעם שמתגלה שם חדש, נוספת כניסה בסוף המערך•כשמחפשים שם, הולכים מסוף המערך חזרה,•
וכך מוצאים את ההגדרה האחרונה שלו O(n)זמן גישה לחיפוש • O(n)זמן גישה להכנסה )עם וידוא שאין הגדרה כפולה( • O(n(n+e)) חיפושים e סמלים וביצוע nזמן להכנסת • הזמן סביר )תוכניות הכתובות בידי אדם( n < 100כאשר • הזמן עשוי )תוכניות המיוצרות ע"י תוכניות( n > 1000כאשר •
להיות ארוך מדי
72תורת הקומפילציהאיתן אביאור
(Hash Tableטבלת ערבול )הכניסות נשמרות ברשימות מקושרות•קיימת טבלה המכילה מצביעים לרשימות מקושרות•מחרוזת שם משמשת בסיס לחישוב ערך ערבול והוא אינדקס •
בטבלה, הרשומות של כל השמות שיש להם אותו ערך ערבול נמצאות באותה רשימה מקושרת
O(n(n+e)/m) גישות e סמלים ו-nזמן גישה ליצירת • גדול כרצוננו )חליפין זמן-מקום( גודל הטבלה m כאשר
. . .
. . .
. . .
. . .
0
9
20
32
210
cp
match
last action ws
איברי הרשימות הנוצריםעבור השמות המוצגים
מערך שלראשי רשימות
שהאינדקסאליו הוא
ערך הערבול
n
73תורת הקומפילציהאיתן אביאור
ייצוג חוקי התחוםבטבלת הסמלים
הסמלים חייבים להיות קיימים גם לאחר סיום התרגום, למשל •(debuggerלצורך העברה למנפה )
רצוי שהמהדר "יראה" רק את הסמלים שתחום הגדרתם קיים •כרגע
נגדיר שלוש פעולות•–lookup חיפוש הכניסה האחרונה ביותר של שם –insert הוספת כניסה חדשה –deleteהסרת כניסה האחרונה ביותר של שם
הכניסות של שם תהיינה ברשימה מקושרת•הכנסה לראש הרשימה )זמן קבוע(–הוצאה מראש הרשימה )זמן קבוע(–
74תורת הקומפילציהאיתן אביאור
ייצוג חוקי התחום 2בטבלת הסמלים
לכל כניסה יהיו שני סוגי קישורים:•
קישור ברשימות שמות המוכרים כרגע )עליו פועלות הפעולות –
הנ"ל(
קישור ברשימת השמות המקומיים לגוש מסויים–
בכניסה לגוש הם מוכרים ביחד•
)מקביל ליצירת רשומות הפעלה בזמן ריצה(
ביציאה מהגוש הם נמחקים יחד•
)מקביל למחיקת רשומת הפעלה בזמן ריצה(