תורת הקומפילציה 236360
This presentation is the property of its rightful owner.
Sponsored Links
1 / 63

תורת הקומפילציה 236360 הרצאה 9 שפות ביניים Intermediate Languages/Representations PowerPoint PPT Presentation


  • 88 Views
  • Uploaded on
  • Presentation posted in: General

תורת הקומפילציה 236360 הרצאה 9 שפות ביניים Intermediate Languages/Representations. Aho, Sethi and Ullman – Chapter 6 Cooper and Torczon – Chapter 5. יצירת קוד ביניים. syntax analysis. syntax tree. semantic analysis. decorated syntax tree. intermediate code generator. intermediate code.

Download Presentation

תורת הקומפילציה 236360 הרצאה 9 שפות ביניים Intermediate Languages/Representations

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


236360 9 intermediate languages representations

תורת הקומפילציה 236360הרצאה9

שפות ביניים

Intermediate Languages/Representations

Aho, Sethi and Ullman – Chapter 6

Cooper and Torczon – Chapter 5


236360 9 intermediate languages representations

יצירת קוד ביניים

syntax analysis

syntax tree

semantic analysis

decorated syntax tree

intermediate code generator

intermediate code

machine independent optimizations

intermediate code

code generator


236360 9 intermediate languages representations

חשיבות קוד הביניים

  • שימוש בשיטות אופטימיזציה שאינן תלויות במכונה מסויימת

  • אפשרות לייצר קוד עבור מכונות שונות באמצעות אותו front end

  • שימוש באותו back end עבור שפות שונות – מספר front ends

  • אם כתבנו mfront-ends ו-nback ends, אז ניתן לשלב אותם ולקבל n*m קומפיילרים.

C

Java

Pascal

C#

Intermediate Language

Cray

PowerPC

Intel


Intermediate representation

ייצוג ביניים – intermediate representation

  • ייצוגים אפשריים

    • syntax tree

    • postfix notation

    • three address code – זו הצורה שאנו נבחר לעבוד איתה.

      • שני אופרנדים ותוצאה אחת.

  • בד"כ עובדים בשני שלבים:

    • תרגום מונחה דקדוק יוצר עץ ניתוח תחבירי + סימונים בצמתים

    • את העץ מתרגמים ל- three address code

  • נדבר ראשית על ייצוג העץ, לפעמים נשתמש ב- DAG(Directed Acyclic Graph) במקום בעץ.


Decorated syntax trees dags postfix

שלושה ייצוגים אפשריים:decorated syntax trees, DAGs, ו-postfix

  • נתון:a := b * –c + b * –c

  • ייצוג כ- DAG

ייצוג כעץ

ייצוג ב- postfix

a b c uminus * b c uminus * + assign


236360 9 intermediate languages representations

דוגמה:תרגום מונחה דקדוק ליצירת עץ מעוטר

  • פונקציות עזר

    • mkleaf – יצירת עלה

    • mkunode – יצירת צומת חדש עבור אופרטור אונרי

    • mknode – יצירת צומת חדש עבור אופרטור בינארי

    • id.place – מצביע לטבלת הסמלים

  • הערה – אפשר להחליף את mkleaf, mkunode, ו- mknode בפונקציות המחזירות מצביע לצמתים קיימים על מנת ליצור DAG


236360 9 intermediate languages representations

assign

*

*

id

a

id

id

b

b

+

uminus

uminus

id

id

c

c

ייצוג בזיכרון של עץ מעוטר

a := b * –c + b * –c


Three address code

אופרטור

3 הכתובות

three address code

  • אחרי שבונים את העץ, צריך לתרגם לשפת הביניים שבחרנו.

  • אנו נעבוד עם three-address-code.

  • הצורה הכללית של פקודה:

    x := y op z

  • x, y, ו-z הם 3 שמות, קבועים, או משתנים זמניים שנוצרו ע"י הקומפיילר.

  • op הוא אופרטור כלשהו.

  • האופרטורים שנשתמש בהם יהיו פשוטים, כך שיהיה קל לעבור מהם לשפת מכונה.


Three address code1

assign

assign

a

+

a

+

*

*

*

b

unimus

b

unimus

b

unimus

c

c

c

t1

:=

– c

t1

:=

– c

t2

:=

b * t1

t2

:=

b * t1

t3

:=

– c

t3

:=

t2 + t2

t4

:=

b * t3

a

:=

t3

t5

:=

t2 +t4

a

:=

t5

three address code


236360 9 intermediate languages representations

קוד ביניים – סוגי המשפטים

relop = relational op (==, >=, etc.)

n = actual number of parameters

קריאה לפרוצדורה:

param x1

param xn

call p,n


236360 9 intermediate languages representations

איך בוחרים אופרטורים?

  • הבחירה של אוסף פקודות מתאים היא חשובה.

  • אוסף מצומצם:

    • קל ליצור קוד מכונה,

    • הקוד יהיה פחות יעיל, ומעמסה גדולה יותר תיפול על ה- optimizer

    • הקוד יהיה ארוך והטיפול בו יהיה מסורבל

    • אי ניצול יכולות של מכונות חכמות

  • אופרטורים רבים:

    • קוד יותר יעיל אך קשה יותר לייצרו וממנו קשה לייצר קוד עבור מכונות פשוטות.


236360 9 intermediate languages representations

יצירת קוד ביניים בעל 3 כתובות על ידי תרגום מונחה דקדוק

ככלל, נניח bottom-up parsing כך שדברים מחושבים לפני שמשתמשים בתוצאת החישוב.

השיטה – שימוש במשתנים זמניים

  • S.code (או E.code)– תכונה המכילה את הקוד הנוצר עבור S (או E).

  • E.var – שם של משתנה שעתיד להכיל את הערך של E

  • newtemp – פונקציה המחזירה שם של משתנה חדש


236360 9 intermediate languages representations

יצירת קוד ביניים בעל 3 כתובות על ידי תרגום מונחה דקדוק


While labels

production

semantic rule

S →while E do S1

S.begin := newlabel ;

S.after := newlabel ;

S.code := gen ( S.begin ' : ' ) || E.code ||

gen ( ' if ' E.var ' = '' 0 '' goto ' S.after ) ||

S1.code || gen ( ' goto ' S.begin ) || gen (S.after ' : ' )

פסוק while:דוגמא לשימוש בתוויות (labels)

S →while E do S1

  • נוסיף תכונות למשתנים, ותוויות.

  • newlabel– פונקציה היוצרת תווית חדשה

  • S.begin – תווית המסמנת את תחילת הקוד

  • S.after – תווית המסמנת את סוף הקוד

  • 0 – מייצג את false


3 address code

מצביעים לטבלת הסמלים

op

arg 1

arg 2

result

(0)

uminus

c

t1

(1)

*

b

t1

t2

(2)

uminus

c

t3

(3)

*

b

t3

t4

(4)

+

t2

t4

t5

(5)

=:

t5

a

מבנה נתונים לייצוג של 3-address code:

  • ייצוג סטנדרטי הוא ע"י רביעיות כך שכל שורה נכתבת לתוך משתנה זמני.

    op, arg1, arg2, result

  • יתרון:פשוט + אין בעיה להעתיק ולהזיז קטעי קוד (וזה חשוב לאופטימיזציות).

  • עלות – מחייב לשמור את ה- temporaries בטבלת הסמלים

t1 = - c

t2 = b * t1

t3 = - c

t4 = b * t3

t5 = t2 * t4

a = t5


3 address code1

op

arg 1

arg 2

מצביעים לטבלת הסמלים או למספר הסידורי של השורה המחשבת את הערך

(0)

uminus

c

(1)

*

b

(0)

(2)

uminus

c

(3)

*

b

(2)

(4)

+

(1)

(3)

(5)

assign

a

(4)

op

op

arg 1

arg 1

arg 2

arg 2

(0)

(0)

[ ] =

= [ ]

x

y

i

i

(1)

(1)

assign

assign

x

(0)

(0)

y

x [ i ] := y

x := y [ i ]

ייצוג נוסף של 3-address code

  • שלשות : op, arg1, arg2(התוצאה מובנת כמספר השורה)

  • אין צורך ב- result

  • אבל: אי אפשר להזיז קוד +פעולה טרנרית כמו x [ i ] := y דורשת שתי שורות


3 address code2

op

arg 1

arg 2

uminus

c

0

*

b

(0)

1

uminus

c

2

*

b

(2)

3

+

(1)

(3)

4

assign

a

(4)

5

ייצוג שלישי של 3-address code

  • indirect triples – השלשות מופרדות מהסדר ביניהן

  • עתה ניתן לשנות סדר ביצוע, להזיז קטעי קוד, ולחסוך במקום אם קיימות שלשות זהות

  • (לא פותר את הפעולה הכפולה עבור פעולות טרנריות.)

רשימת פקודות לפי סדר הביצוע הרצוי שלהן

Execution

Order

10

11

0

1

15

12


Types

Types והקצאות זיכרון למשתנים

  • ניתוח ה-types חשוב מאד לבדיקת שגיאות,

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

...

משתנים קודמים ל-employee

Offset for variable employee

רשומת הפעלה למתודה

employee

מקום למשתנה employee

...


236360 9 intermediate languages representations

הכרזות והקצאת זכרון

  • דוגמא:תרגום מונחה דקדוק עם פעולות סמנטיות לחישוב ה- offset.

  • נשמור משתנה גלובלי offset עם גודל השטח שהוקצה עד עתה.

  • לכל משתנה בפרוצדורה – נכניס לטבלת הסמלים ונקבע לו offset.


236360 9 intermediate languages representations

enter(money, real, 4) offset = offset + 4

הכרזות

enter(count, int, 0) offset = offset + 4

P

D4

D1

D5

D2

id

T1

id

T2

T3

id

int

count

real

money

]

balances

num

[

T4

T1.type = int

T1.width = 4

T2.type = real

T2.width = 4

int

98

id.name = count

id.name = money


236360 9 intermediate languages representations

הכרזות והקצאת זיכרון

  • האיפוס של offset בהתחלה עובד מצוין לניתוח top-down שבו נפעיל את P → Dבתור הכלל הראשון. אך מה עושים עם ניתוח bottom-up?

  • טריק סטנדרטי:נוסיף marker וכלל שתמיד נראה ראשון, גם ב-LR parsing


236360 9 intermediate languages representations

הכרזות והקצאת זיכרון

  • השיטה עובדת מצוין לניתוח top-down שבו נפעיל את P → Dבתור הכלל הראשון ונאפס את offset כנדרש. אך מה עושים עם ניתוח bottom-up?

  • טריק סטנדרטי:נוסיף marker וכלל שתמיד נראה ראשון, גם ב-LR parsing

_____________

P

M

D

Є


236360 9 intermediate languages representations

לסיכום – ייצוג של קוד ביניים

  • קוד ביניים סטנדרטי הוא חשוב, ניתן להפריד בין ה-front-end שתלוי בשפת המקור, לבין ה-back-end שתלוי במכונת היעד, ולשלב כל front-end עם כל back-end.

  • השלבים הקודמים בונים עץ מעוטר (עם attributes)

  • נתרגם אותו אל three-address-code שהיא שפת ביניים סטנדרטית.

  • אפשר לעשות זאת ע"י פעולות סמנטיות בתרגום מונחה דקדוק.

    • אוספים את הקוד לתוויות של משתני הדקדוק.

  • Three-address-code ניתן לייצוג ע"י רביעיות או שלשות (ישירות או עקיפות).

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


236360 9 intermediate languages representations

יצירת קוד ביניים


236360 9 intermediate languages representations

יצירת קוד

  • אפשרות א' –צבירת קוד ב-attributes של משתנים בעץ הגזירה (למשל, בתכונות מסוג code). כך עשינו עד עתה.

  • אפשרות ב' –יצירת קובץ המכיל את הקוד תוך כדי תהליך הקומפילציה

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

    • חסרון:לא מאפשר מניפולציות על הקוד.

    • במספר שקפים הקרובים נדגים את אפשרות ב'. כמובן שניתן בקלות לחזור לצבירת קוד בתכונות של משתני הדקדוק שבגזירה.


236360 9 intermediate languages representations

ביטויים ומשפטי השמה

  • דקדוק המסגרת:התוכנית מכילה הגדרות של משתנים (כמו קודם) ופרוצדורות.

  • ביטויים ומשפטי השמה:

  • Lookup מחזיר את הכתובת של המשתנה בזיכרון.

  • Emit פולט שורת קוד מתאימה בפורמט three-address-code לתוך הקובץ.

  • הטיפול כאן (ובד"כ בהמשך)הוא לפי bottom-up parsing ולכן מקצים למשתנה מקום בפעם הראשונה שפוגשים אותו = כמשתנה השמאלי בכלל הדקדוק.


236360 9 intermediate languages representations

ביטויים ומשפטי השמה

  • דקדוק המסגרת:התוכנית מכילה הגדרות של משתנים (כמו קודם) ופרוצדורות.

  • ביטויים ומשפטי השמה:

  • ניתן לייעל במקום הדרוש למשתנים זמניים: כשיוצאים מתת-עץ אין יותר שימוש במשתנים הפנימיים שלו. ניתן לנהל את המשתנים במחסנית.


236360 9 intermediate languages representations

ביטויים בוליאניים

נייצג את false כ-0 ואת true כ-1.

  • חשוב לשים לב – כתובת המטרה ניתנת לחישוב תוך כדי יצירת הקוד


236360 9 intermediate languages representations

חישוב ביטויים בוליאניים ע"י קפיצה

נייצג את false כ-0 ואת true כ-1.

  • למה זה מועיל?לחישוב מקוצר... אבל נראה קודם דוגמא.


236360 9 intermediate languages representations

E

E

or

E

a

<

b

E

and

E

c

<

d

e

<

f

ביטויים בוליאניים בייצוג מספרי – דוגמא


236360 9 intermediate languages representations

E

E

or

E

a

<

b

E

and

E

c

<

d

e

<

f

ביטויים בוליאניים בייצוג מספרי – דוגמא


236360 9 intermediate languages representations

E

E

or

E

a

<

b

E

and

E

c

<

d

e

<

f

ביטויים בוליאניים בייצוג מספרי – דוגמא


236360 9 intermediate languages representations

E

E

or

E

a

<

b

E

and

E

c

<

d

e

<

f

ביטויים בוליאניים בייצוג מספרי – דוגמא


236360 9 intermediate languages representations

E

E

or

E

a

<

b

E

and

E

c

<

d

e

<

f

ביטויים בוליאניים בייצוג מספרי – דוגמא


236360 9 intermediate languages representations

E

E

or

E

a

<

b

E

and

E

c

<

d

e

<

f

ביטויים בוליאניים בייצוג מספרי – דוגמא


236360 9 intermediate languages representations

ביטויים בוליאניים – חישוב מקוצר

  • בניגוד לביטויים אריתמטיים, בביטויים בוליאניים ניתן לחסוך בחישוב כי לעיתים ניתן לדעת מה התוצאה כבר באמצע החישוב.

  • למשל, בביטוי E1or E2, אם E1 הוא true הרי שלא חשוב לנו מה ערכו של E2.

  • חישוב כזה נקרא lazy evaluation או short circuit boolean evaluation.


236360 9 intermediate languages representations

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) ניזכר בביטוי של קודם:

חישוב מקוצר:


236360 9 intermediate languages representations

תכונות של חישוב מקוצר

  • האם החישוב מקוצר שקול לחישוב רגיל?

  • מתי אסור להשתמש בחישוב מקוצר?

  • מתי חייבים להשתמש בחישוב מקוצר?

תשובות:

לא – יתכנו side-effects לחישוב ביטוי בוליאני. דוגמא קלאסית: if ( (i > 0) and (i++ < 10) ) A[i]=i else B[i]=i;

כאשר הגדרת השפה לא מרשה זאת.

כאשר הגדרת השפה מחייבת קיצור, והמתכנת עלול להתבסס על כך.דוגמא קלאסית: if ( (file=open(“c:\grades”) or (die) ) printfile(file);


If else while

טיפול בהפניות בקרה:if, else, while.

  • נחזור לאגור את הקוד בתכונה (attribute) בשם קוד. ההבדל בין emit ל- gen: genמחזירה את הפקודה שנוצרה; emit מדפיסה אותה ל- buffer.

  • נתבונן בקפיצות מותנות:

  • אפשרות אחת היא לעבוד כמו קודם, לייצר קוד ל-B לייצר קוד ל-S, ואז לייצר קפיצה לתחילת S או סוף S כתלות בערך של B.

  • אבל באופן יעיל יותר, אפשר פשוט לייצר קוד שבזמן החישוב של B יקפוץ למקום הנכון ברגע שיתגלה מה ערכו של B.


If else while1

טיפול בהפניות בקרה:if, else, while.

  • מסתבר שיש כאן בעיה עם ההחלטה לאן לקפוץ בזמן הניתוח...

  • כאשר מנתחים את העץ שנפרש מ-B עבור "if B then S” לא יודעים למה S יתפתח ואיפה מתחיל ונגמר הקוד של S, אבל צריך לייצר קפיצות למקומות אלו.

  • השיטה – לכל ביטוי B נצמיד שתי תוויות: B.true, ו-B.false שהן התוויות אליהן החישוב צריך לעבור אם B הוא true (או false בהתאמה).

  • לכל פסוק S נחזיק תווית next שאומרת מה הכתובת של הקוד שאחריו.

  • משוואה סמנטיות מתאימה:B.false = S.next

  • לגבי B.true, נייצר label בין הקוד של B לקוד של S ונייחס לו את B.true.

S

if

B

then

S


236360 9 intermediate languages representations

התכונה next

  • בגזירה של פסוק S, נייצר את הקוד עם התווית שאחריו:

  • התכונה S.next היא נורשת: הילד מקבל אותה כשהוא נגזר מאביו.

  • תכונת ה-code היא נוצרת: האבא מקבל אותה בעת גזירת ילדיו.

  • ה-labelS.next היא סימבולית. הכתובת המתאימה לה תיוודע רק אחרי שנגזור את כל הביטוי של S.


If b then s

→ to B.true

קוד לחישוב B עם קפיצות החוצה

→ to B.false

B.true:

קוד לחישוב S

B.false:

. . .

If B then S

  • B.false ו- S1.next הן תכונות נורשות

  • S.code היא תכונה נוצרת


If b then s 1 else s 2

If B then S1 else S2

→to B.true

→to B.false

B.True ו-B.false לא נקבעים ע"י ההורים ולא ע"י הילדים. אבל הם נקבעים בזמן גזירה שבה B הוא ילד ולכן נחשבים נורשים.

נורש

נוצר


236360 9 intermediate languages representations

חישוב ביטויים בוליאניים על ידי הפנית בקרה

  • נייצר קוד שקופץ ל-B.true אם הערך של Btrue ול-B.false אם הוא false.

  • איזו צורת חישוב מוצגת כאן? מקוצרת או מלאה?


236360 9 intermediate languages representations

חישוב ביטויים בוליאניים על ידי הפנית בקרה

  • נייצר קוד שקופץ ל-B.true אם הערך של Btrueול-B.false אם הוא false.

  • נתבונן לדוגמא ב-labelB1.false.

  • הכתובת של ה-label ניתנת לחישוב רק אחרי שנדע את כל הקוד של B1 וכל הקוד שלפני B1.

  • למעשה, אנו נייצר את כל הקוד עם labels סימבוליים, ואחרי כן נבצע מעבר נוסף על העץ כדי לקבוע כתובת לכל label סימבולי, ולעדכן את כתובות הקפיצה בפקודות המתאימות.


Backpatching

Backpatching – תיקון לאחור

  • מטרתנו להסתפק במעבר אחד על העץ בזמן היצירה שלו, ללא המעבר הנוסף.

    • השיטה:נשמור לכל label את אוסף הכתובות של פקודות שמדלגות אליו.

    • ברגע שנדע את הכתובת של ה-label, נלך על רשימת הכתובות ונכניס בפקודות הקפיצה המתאימות את הכתובת האמיתית של ה-label.

    • יתרון:מעבר DFS יחיד יספיק (חישבו על אלפי שורות קוד).

    • חסרון:נצטרך להקצות מקום לרשימות של הכתובות.

  • נדגיש שפתרונות שהזכרנו בעבר לא יעבדו.

    • הגזירה אינה S-attributed (יש גם תכונות נורשות, למשל next).

    • היא לא L-attributed (התכונות הנורשות אינן בהכרח נורשות-משמאל)

    • לכן לא נוכל לחשב את התכונות תוך כדי הניתוח.


236360 9 intermediate languages representations

דוגמא להבהרת הקושי

S

B

then

else

if

S1

S2

  • חישבו על פסוק if-then-else.

  • על-מנת לחשב את S1.next צריך כבר לדעת את הקוד של כל הבלוקים B, S1, ו-S2 (כדי לדעת מהי הכתובת שאחריהם).

  • מצד שני, כדי לחשב את הקוד של S1 צריך להעביר לו את S1.next, או S.next, אבל ערך זה לא ידוע לפני החישוב של S1.

  • כאמור, לא נוכל לחשב את הקוד של S1 עם כל כתובות הקפיצה, אבל נוכל לחשב אותו עד כדי "השארת מקום" להכנסה מאוחרת יותר של S1.next.

  • בשיטת ה-backpatching נבנה את הקוד ונשאיר לעצמנו רשימה עבור ה-label הסימבולי S1.next של כל שורות הקוד שבהן יש קפיצה אליו.

  • כשנדע את ערכו של S1.next, נעבור על הרשימה ונעדכן.


236360 9 intermediate languages representations

פונקציות ליצירה וטיפול בהתחייבויות

  • makelist ( addr ) – יצירת רשימת התחייבויות חדשה המכילה את הכתובת addr. התוצאה – מצביע לרשימה של כתובות של פקודות.

    • addr הוא מספר שורה ברשימת הרביעיות שלנו

    • המשמעות:יש לתקן את הפקודה שבשורה addr כשיתקבל מידע רלוונטי

  • merge ( p1, p2 ) – איחוד הרשימות אליהם מצביעים p1ו- p2. מחזיר מצביע לאיחוד הרשימות.

    • כלומר, שתי הרשימות מכילות פקודות שצריכות לקפוץ לאותו מקום.

  • backpatch ( p, addr ) – קביעת הכתובת addr ככתובת הקפיצה בכל אחת מהפקודות (רביעיות) שברשימה אליה מצביע p


236360 9 intermediate languages representations

אגירת הקוד

  • נניח (כהרגלנו)ניתוח bottom-up כך שהקוד נוצר בסדר הנכון (שמאל לימין, מלמטה למעלה).

  • הניתוח הסמנטי יתבצע במהלך הניתוח התחבירי והקוד ייפלט לתוך buffer עם פקודת emit (פשוט כדי שיהיה נוח לחשוב על כתובות של פקודות).

  • אפשר גם לאסוף את הקוד בתוך תכונה, כל עוד יש דרך לשמור מצביע על שורת קוד (שעליה יתבצע backpatch).

  • כזכור, לכל ביטוי B הצמדנו שתי תוויות: B.true, ו-B.false שהן התוויות אליהן החישוב צריך לעבור אם B הוא true (או false בהתאמה).

  • עתה תהיינה לנו גם זוג רשימות : B.truelist, ו-B.falselist שאומרות באילו פקודות צריך לחזור ולעדכן את הכתובות של : B.true, ו-B.false כשמגלים את ערכיהם.

  • בנוסף, לכל פסוק S שעבורו החזקנו label סימבולי S.next, נחזיק עתה גם רשימה S.nextlist.


236360 9 intermediate languages representations

אגירת הקוד - המשך

  • B.truelist, ו-B.falselist הן תכונות נוצרות: הצאצאים מספרים לאב איפה יש קוד שצריך לתקן.

  • כאשר עולים לאב של B עצמו, נדע מה הכתובת הרלוונטית ונוכל לבצע backpatch ולהכניס אותה לכל הפקודות שנרשמו ברשימה.

  • באופן דומה, ל-S.nextlist תכונות דומות.

  • נשתמש בפונקציה nextinstr שתחזיר את הכתובת של הפקודה הבאה.


236360 9 intermediate languages representations

חישוב ביטויים בוליאניים על ידי הפנית בקרה

  • כזכור, הקוד שקופץ ל-B.true או ל-B.false לפי הערך של B.

  • קודם היה:

  • ועכשיו עם backpatching:

  • איזו צורת חישוב מוצגת כאן? מקוצרת או מלאה?


236360 9 intermediate languages representations

חישוב ביטויים בוליאניים על ידי הפנית בקרה

  • כזכור, הקוד שקופץ ל-B.true או ל-B.false לפי הערך של B.

  • קודם היה:

  • ועכשיו עם backpatching:

  • איזו צורת חישוב מוצגת כאן? מקוצרת או מלאה?


236360 9 intermediate languages representations

חישוב ביטויים בוליאניים על ידי הפנית בקרה

  • כזכור, הקוד שקופץ ל-B.true או ל-B.false לפי הערך של B.

  • קודם היה:

  • ועכשיו עם backpatching:

  • איזו צורת חישוב מוצגת כאן? מקוצרת או מלאה?


Marker

טריק ה-marker הסטנדרטי

  • למשל: B → B1or M B2 ו- M →.

  • בזמן הגזירה של M משיגים את הכתובת של תחילת B1.

B

or

B1

M

B1


236360 9 intermediate languages representations

B.t = {100, 104}

B.f = {103, 105}

B.t = {100}

B.f = {101}

or

M.i = 102

B.t = {104}

B.f = {103, 105}

a

<

b

and

M.i = 104

B.t = {102}

B.f = {103}

B.t = {104}

B.f = {105}

c

<

d

e

<

f

תיקון לאחור


236360 9 intermediate languages representations

B.t = {100, 104}

B.f = {103, 105}

B.t = {100}

B.f = {101}

or

M.i = 102

B.t = {104}

B.f = {103, 105}

a

<

b

and

M.i = 104

B.t = {102}

B.f = {103}

B.t = {104}

B.f = {105}

c

<

d

e

<

f

תיקון לאחור


236360 9 intermediate languages representations

B.t = {100, 104}

B.f = {103, 105}

B.t = {100}

B.f = {101}

or

M.i = 102

B.t = {104}

B.f = {103, 105}

a

<

b

and

M.i = 104

B.t = {102}

B.f = {103}

B.t = {104}

B.f = {105}

c

<

d

e

<

f

תיקון לאחור


236360 9 intermediate languages representations

B.t = {100, 104}

B.f = {103, 105}

B.t = {100}

B.f = {101}

or

M.i = 102

B.t = {104}

B.f = {103, 105}

a

<

b

and

M.i = 104

B.t = {102}

B.f = {103}

B.t = {104}

B.f = {105}

c

<

d

e

<

f

תיקון לאחור


236360 9 intermediate languages representations

B.t = {100, 104}

B.f = {103, 105}

B.t = {100}

B.f = {101}

or

M.i = 102

B.t = {104}

B.f = {103, 105}

a

<

b

and

M.i = 104

B.t = {102}

B.f = {103}

B.t = {104}

B.f = {105}

c

<

d

e

<

f

תיקון לאחור


236360 9 intermediate languages representations

B.t = {100, 104}

B.f = {103, 105}

B.t = {100}

B.f = {101}

or

M.i = 102

B.t = {104}

B.f = {103, 105}

a

<

b

and

M.i = 104

B.t = {102}

B.f = {103}

B.t = {104}

B.f = {105}

c

<

d

e

<

f

תיקון לאחור


236360 9 intermediate languages representations

פסוקים עם הפנית בקרה: IF


While

פסוקים עם הפנית בקרה: While


236360 9 intermediate languages representations

לסיכום

  • יצירת קוד משולבת בניתוח הסמנטי (בפעולות הסמנטיות)

  • או שפולטים קוד לבפר באמצעות emit, או שאוספים את הקוד כתכונה של המשתנים הנגזרים, וכשגומרים, ה-code של המשתנה ההתחלתי S הוא הקוד הנדרש.

  • הניתוח של ביטויים לוגיים ופסוקי הפניית הבקרה הם יותר מסובכים.

  • ראשית צריך להחליט על ביצוע מקוצר (או לא).

  • שנית, צריך לדאוג להכנסת כתובות הקפיצה אחרי שמגלים את ערכן.

  • אפשרות אחת:שימוש ב-labels סימבוליים ומעבר נוסף לעידכונם לכתובת אמיתית.

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


  • Login